谈谈网络蜘蛛 爬开心网001的一些体会

------------- 

前言

------------ 

最近在搞自动登录系统的框架。拿开心网001来实验,可是非常郁闷,我发现开心网的html页面是我所见到的所有页面中最不规范的。

 

水平之烂,第一次见。在php中夹杂Javascript,javascript有使用了php动态生成变量;在div布局中又嵌入table;json格式乱七八糟,根本没有统一的模型规范。 

 

html标签不应该关闭的关闭,应该关闭的开着,几乎就是混乱。 

 

我实在怀疑kaixin001到底能走多远。在几乎摇摇欲坠的架构上面开发,到底还有多少潜力? 

 

虽然整个kaixin001如此之烂,而更令我惊奇是,无论IE、firefox、chrome依然能够正确的解析页面布局。实在佩服这些html解析器的内核,竟然可以容忍这么垃圾的html布局。

 

-------------  

正文

------------ 

使用网络蜘蛛,首先必然要对html进行对象化,变成html树,然后再根据 class / id,甚至节点的位置获取自己需要的信息。

 

可以开心网的html如此之烂,采用标准的html规范解析,一定会崩溃的;既然ie的内核能够正确解析这种html,那么我一定可以进行类似的智能修正操作。 

首先看一段kaixin001恶心的html代码,找找其中的问题。 

代码
     < div  class ="dxx_of"  id ="message7"  onmouseover ="msgOnmouseover(7)"  onmouseout ="msgOnmouseout(7)"   /> ---------- 问题1:毫无道理的中断
    
< div  class ="dxx1"  style ="padding: 15px 10px;" >
    
</ div >
    
< div  class ="dxx4" >
        
< div  class ="l50_s"  id ="icon7" >
            
< href ="/home/?uid=14682889"  title ="陈晨" >
                
< img  src ="http://pic1.kaixin001.com.cn/logo/68/28/50_14682889_24.jpg"  width ="50"
                    height ="50"   /></ a ></ div >
        
< div  style ="text-align: center; margin-top: -8px;" >
            
< href ="/home/?uid=14682889"  class ="sl"  title ="陈晨" > 陈晨 </ a ></ div >
    
</ div >
    
< div  class ="dxx5"  style ="width: 120px;" >
        
< div  class ="c9 f10" >
            3月24日 </ div >
        
< div  style ="display: none; border: 1px solid #EEC0C7; padding: 2px 5px 0 5px; color: #EEC0C7;" >
            群发 </ div >
    
</ div >
    
< div  class ="dxx6" >
        
< table  width ="470"  class ="aa"  border ="0"  cellpadding ="0"  cellspacing ="0" >
            
< colgroup >
                
< col  width ="463"   />
            
</ colgroup >
            
< tbody >
                
< tr  basestyle ="oRowLine2" >
                    
< td  style ="white-space: normal"  valign ="top"  onclick ="javascript:clickDirect('/msg/view.php?thread_mid=1871989755&pos=6');" >
                        
< img  onload ='_commentImageResize(this,350);'  title ="微笑"  src ="http://img1.kaixin001.com.cn/i/face/2.gif" >
                        
< div >
                            
< span  class ='c9' > 共2条会话 </ span >< href ="/msg/view.php?thread_mid=1871989755&pos=6"
                                class ="sl" > +展开 </ a > </ span > -------- 问题2:没有根据的结束符 </ div >
                        
< span  class ="c9" ></ span >
                        
< div  class ="msg_encl"  style ="display: none;" >
                            
< img  src ="http://img.kaixin001.com.cn/i/enclosure.gif"   />
                            此消息含有0个附件 </ div >
                    
</ td >
                
</ tr >
            
</ tbody >
        
</ table >
    
</ div >
    
< div  class ="dxx4"  style ="width: 78px;" >
        
< div >
            
< class ="sl"  href ="/msg/view.php?thread_mid=1871989755&pos=6"  title ="查看该消息" > 查看该消息 </ a ></ div >
        
< div >
            
< class ="sl"  href ="/msg/view.php?thread_mid=1871989755&pos=6"  title ="回复该消息" > 回复该消息 </ a ></ div >
        
< div >
            
< class ="sl"  href ="/msg/write.php?thread_mid=1871989755"  title ="转发该消息" > 转发该消息 </ a ></ div >
        
< div  id ="Div6"  style ="display: none;"  title ="举报不良短消息" >
            
< div  class ="l" >
                
< class ="sl cp"  style ="text-decoration: underline;"  onclick ="javascript:report(14682889,'1871989755');"
                    onmouseover ="javascript:$('reportimg').src='http://img.kaixin001.com.cn/i2/tanhao1.gif'"
                    onmouseout ="javascript:$('reportimg').src='http://img.kaixin001.com.cn/i2/tanhao.gif'"
                    target ="reportspam"  title ="举报不良短消息" > 不良短消息 </ a > &nbsp; </ div >
            
< div  class ="l mt5" >
                
< img  id ="Img6"  onclick ="javascript:report(14682889,'1871989755');"  onmouseover ="this.src='http://img.kaixin001.com.cn/i2/tanhao1.gif'"
                    onmouseout ="this.src='http://img.kaixin001.com.cn/i2/tanhao.gif'"  src ="http://img.kaixin001.com.cn/i2/tanhao.gif"
                    width ="14"  height ="12"  alt ="举报不良短消息"   /></ div >
            
< div  class ="c" >
            
</ div >
        
</ div >
    
</ div >
    
< div  class ="dxx7"  id ="delete7" >
        
< href ="javascript:delThread('1871989755', '0');"  title ="删除该条消息包含的所有会话" >
            
< img  src ="http://img.kaixin001.com.cn/i/close.gif"   /></ a ></ div >
    
< div  class ="c" >
    
</ div >
    
</ div > -------- 问题1:这个应该是开始的div的结束符

 

 

还有类似的代码,例如:

< input  type =hidden  name =id_2  value ="9813861" > --------- 没有关上标签
< input  type =hidden  name =num_2  value ="0" >
< input  type =hidden  name =del_2  value ="0" >

 

 

总之,问题数不胜数。我大概列举一下:

 

1.  标签是否关闭问题

根据html规范,部分标签是不允许有子节点,例如br / hr / input /  img 因此读取到当前节点之后,不会进行嵌套读取。

 

2.  布局的混乱

在第一个例子里面, 

<div class="dxx_of" id="message7" onmouseover="msgOnmouseover(7)" onmouseout="msgOnmouseout(7)"/> 

div过早的关闭了,如果按照html规范递推建立节点,则会导致子节点无法正确的建立。解决方法就是,当遇到当前节点是关闭的节点,例如<a xxx />,同时允许带有子节点,则进入递归继续读取。

3. 遇到结束节点

例如第一个例子里面多余的</span>,要解决这种问题,就需要对递归保存递归路径,使用堆栈Stack。当发生递归后,压入当前节点名称到堆栈,所以读取了结束节点,则判断是否在堆栈中出现过,如果没有,自动丢弃。

 

-------------  

结束语

------------- 

基本上以上3点,可以处理大部分的html代码了。只是还有一个问题,就是第二点的解决方案。 

因为我是默认了可以包含子节点的html标签,忽略关闭记号继续迭代(忽略 />) ,则如果当前节点的确是需要关闭的,那么怎么办??

如果我知道ie的优化算法,估计这个问题可以被解决。

做网络爬虫的人应该占大多数,希望大家给点资料。 

你可能感兴趣的:(网络)