• (转)开源爬虫larbin分析


    转自风中之炎的博客:http://www.cnblogs.com/FengYan/archive/2012/02/04/2338630.html

    1. larbin简介(百度百科)   

          larbin是一种开源的网络爬虫/网络蜘蛛,由法国的年轻人Sébastien Ailleret独立开发,用c++语言实现。larbin目的是能够跟踪页面的url进行扩展的抓取,最后为搜索引擎提供广泛的数据来源。 Larbin只是一个爬虫,也就是说larbin只抓取网页,至于如何parse的事情则由用户自己完成。另外,如何存储到数据库以及建立索引的事情 larbin也不提供。  

          latbin最初的设计也是依据设计简单但是高度可配置性的原则,因此我们可以看到,一个简单的larbin的爬虫可以每天获取500万的网页,实在是非常高效。  利用larbin,我们可以轻易的获取/确定单个网站的所有联结,甚至可以镜像一个网站;也可以用它建立url 列表群,例如针对所有的网页进行 url retrive后,进行xml的联结的获取。或者是 mp3,或者定制larbin,可以作为搜索引擎的信息的来源。

    2. 高效的larbin    

           简介中提到larbin是一个非常高效的爬虫,但没有说明为什么。这里尝试列出几个原因。此外,由于接触爬虫的时间尚短,没发现的地方,希望各位能补充下。

          a. 节省空间的hash容器。在larbin中,hash的主要用途是判重,因此没必要将元素的值记录到hash表中。于是就使用一个位图保存hash code,根据位图某个位是否为1,判断某个元素是否在hash表中。当要插入一个新元素时,就将hash code对应的位置1。这样说可能不容易明白,举个例吧。假设int为32位,位图为int bitmap[100],元素A的hash code为120,将元素A插入到hash容器就是将bitmap的第120位置1,即bitmap[120/32] | (1 << 120%32)。

          b. 减少dns次数。对于一个站点,使用一次dns解析出IP地址后,下次再遇到该站点的其它网页,就用IP地址替换域名。

         c. 异步连接。使用单线程非阻塞的方法进行socket连接,充分利用了网络资源和CPU资源。

    3. larbin的大致流程    

          larbin的大致流程可以从main.cc看出,这里去掉不重要语句,给出关键语句形成的流程,并加上注释。

       

    int main(int argc, char *argv[]) {
     
      global glob(argc, argv)  //使用配置文件初始化global类中的成员变量
     
      for(; ;) {
             waitbandwidth()  //如果用户设置了最大带宽,则由此函数保证带宽的使用情况 
             input()  //接收用户的输入,得到初始URL列表 
       sequencer() //按优先度将URL放到待爬取站点
     
       fetchDns() //对站点名即host,进行DNS请求
     
       fetchOpen() //从DNS解析成功的站点中,取出一些URL进行socket连接 
     
       checkAll() //下载网页,提取URL,并执行用户定制的网页分析
      }  
    }  

    4. larbin的关键函数    

         这一节主要使用伪代码说明第3节列出的函数是怎样工作的。

    // wait to limit bandwidth usage
    waitBandwidth() {
       while( 剩余带宽 < 0 ) {
          等10ms
          if( socket超时 )    更新待爬取的url数量
          更新剩余带宽
       }
    }
     
    //
    input() {
       初始化webServe,等待用户连接
       接收用户输入,包括优先度,深度,抓取模式,初始URL列表
       从初始URL得到hostName,portNumber,fileName
       按优先度将URL放到待爬取队列
    }
     
    //start the sequencer
    sequencer() {
       得到一轮(perCall)可以加载URL的数量(存放在变量still中)
       根据URL的优先级加载最多still条URL到待爬取站点
    }
     
    //Opens sockets ; this function perform dns calls, using adns
    fetchDns() {
       从dnsSite取出hostName,发送dns解析请求(发送数量受最大连接数限制)
       接收dns解析结果
       if(解析成功) {
          获取并解析该host的robots.txt
          保存URL到okSites
       }  
    }
     
    //Opens sockets ; Never block (only opens sockets on already known sites) ; work inside the main thread
    fetchOpen() {
       while( 空闲连接数 ) {
          从okSites取出一个URL
          if( 成功打开socket ) {
             向conn填写一些信息  
             减少一个空闲连接
          }
       }
    }
     
    //read all data available ; fill fd_set for next select ; give back max fds
    checkAll() {
       for( 每个连接 ) {
          switch( 连接状态 ) {
             case connecting : 检查是否socket错误,若不是,则将状态转为write,break  
             case write : 写socket请求,将状态转为open,break
             case open : 读网页,分析网页,提取链接(endInput函数),状态转为empty,break
          }
       }
     
       for( 每个连接 ) 更新pollfds数组的状态(与异步IO有关)
    }

    5. 参考文献

         以下是我看larbin源码时,对我帮助很大的文献。

    a. larbin官网

    http://larbin.sourceforge.net/index-eng.html

    b. larbin的配置和使用 http://www.cnblogs.com/zhangchaoyang/articles/2031954.html

    c. 从larbin看互联网爬虫设计 http://www.oschina.net/question/12_4114

    d. Linux网络编程入门 http://www.cnblogs.com/duzouzhe/archive/2009/06/19/1506699.html

    e. adns官网 http://ftp.gnu.org/gnu/adns/

  • 相关阅读:
    26 转义符 re模块 方法 random模块 collection模块的Counter方法
    25 正则表达式
    24 from 模块 import 名字
    24 from 模块 import 名字
    24 from 模块 import 名字
    23 析构方法 items系列 hash方法 eq方法
    21 isinstance issubclass 反射 _str_ _new_ _len_ _call_
    20 属性, 类方法, 静态方法. python2与python3的区别.
    python(1)
    python之字符串格式化
  • 原文地址:https://www.cnblogs.com/panweishadow/p/3340302.html
Copyright © 2020-2023  润新知