開源爬蟲larbin分析


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/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM