開發網絡爬蟲應該怎樣選擇爬蟲框架?

有些人問,開發網絡爬蟲應該選擇Nutch、Crawler4j、WebMagic、scrapy、WebCollector還是其他的?這裏按照我的經驗隨便扯淡一下:

上面說的爬蟲,基本可以分3類:

      1.分佈式爬蟲:Nutch

      2.JAVA單機爬蟲:Crawler4j、WebMagic、WebCollector

      3. 非JAVA單機爬蟲:scrapy

    

第一類:分佈式爬蟲

        爬蟲使用分佈式,主要是解決兩個問題:

                1)海量URL管理

                2)網速

        現在比較流行的分佈式爬蟲,是Apache的Nutch。但是對於大多數用戶來說,Nutch是這幾類爬蟲裏,最不好的選擇,理由如下:

                1)Nutch是爲搜索引擎設計的爬蟲,大多數用戶是需要一個做精準數據爬取(精抽取)的爬蟲。Nutch運行的一套流程裏,有三分之二是爲了搜索引擎而設計的。對精抽取沒有太大的意義。也就是說,用Nutch做數據抽取,會浪費很多的時間在不必要的計算上。而且如果你試圖通過對Nutch進行二次開發,來使得它適用於精抽取的業務,基本上就要破壞Nutch的框架,把Nutch改的面目全非,有修改Nutch的能力,真的不如自己重新寫一個分佈式爬蟲框架了。

                 2)Nutch依賴hadoop運行,hadoop本身會消耗很多的時間。如果集羣機器數量較少,爬取速度反而不如單機爬蟲快

                 3)Nutch雖然有一套插件機制,而且作爲亮點宣傳。可以看到一些開源的Nutch插件,提供精抽取的功能。但是開發過Nutch插件的人都知道,Nutch的插件系統有多蹩腳。利用反射的機制來加載和調用插件,使得程序的編寫和調試都變得異常困難,更別說在上面開發一套複雜的精抽取系統了。而且Nutch並沒有爲精抽取提供相應的插件掛載點。Nutch的插件有隻有五六個掛載點,而這五六個掛載點都是爲了搜索引擎服務的,並沒有爲精抽取提供掛載點。大多數Nutch的精抽取插件,都是掛載在“頁面解析”(parser)這個掛載點的,這個掛載點其實是爲了解析鏈接(爲後續爬取提供URL),以及爲搜索引擎提供一些易抽取的網頁信息(網頁的meta信息、text文本)。

                 4)用Nutch進行爬蟲的二次開發,爬蟲的編寫和調試所需的時間,往往是單機爬蟲所需的十倍時間不止。瞭解Nutch源碼的學習成本很高,何況是要讓一個團隊的人都讀懂Nutch源碼。調試過程中會出現除程序本身之外的各種問題(hadoop的問題、hbase的問題)。

                 5)很多人說Nutch2有gora,可以持久化數據到avro文件、hbase、mysql等。很多人其實理解錯了,這裏說的持久化數據,是指將URL信息(URL管理所需要的數據)存放到avro、hbase、mysql。並不是你要抽取的結構化數據。其實對大多數人來說,URL信息存在哪裏無所謂。

                 6)Nutch2的版本目前並不適合開發。官方現在穩定的Nutch版本是nutch2.2.1,但是這個版本綁定了gora-0.3。如果想用hbase配合nutch(大多數人用nutch2就是爲了用hbase),只能使用0.90版本左右的hbase,相應的就要將hadoop版本降到hadoop 0.2左右。而且nutch2的官方教程比較有誤導作用,Nutch2的教程有兩個,分別是Nutch1.x和Nutch2.x,這個Nutch2.x官網上寫的是可以支持到hbase 0.94。但是實際上,這個Nutch2.x的意思是Nutch2.3之前、Nutch2.2.1之後的一個版本,這個版本在官方的SVN中不斷更新。而且非常不穩定(一直在修改)。

        所以,如果你不是要做搜索引擎,儘量不要選擇Nutch作爲爬蟲。有些團隊就喜歡跟風,非要選擇Nutch來開發精抽取的爬蟲,其實是衝着Nutch的名氣(Nutch作者是Doug Cutting),當然最後的結果往往是項目延期完成。

         如果你是要做搜索引擎,Nutch1.x是一個非常好的選擇。Nutch1.x和solr或者es配合,就可以構成一套非常強大的搜索引擎了。如果非要用Nutch2的話,建議等到Nutch2.3發佈再看。目前的Nutch2是一個非常不穩定的版本。


       第二類:JAVA單機爬蟲

                這裏把JAVA爬蟲單獨分爲一類,是因爲JAVA在網絡爬蟲這塊的生態圈是非常完善的。相關的資料也是最全的。這裏可能有爭議,我只是隨便扯淡。

                其實開源網絡爬蟲(框架)的開發非常簡單,難問題和複雜的問題都被以前的人解決了(比如DOM樹解析和定位、字符集檢測、海量URL去重),可以說是毫無技術含量。包括Nutch,其實Nutch的技術難點是開發hadoop,本身代碼非常簡單。網絡爬蟲從某種意義來說,類似遍歷本機的文件,查找文件中的信息。沒有任何難度可言。之所以選擇開源爬蟲框架,就是爲了省事。比如爬蟲的URL管理、線程池之類的模塊,誰都能做,但是要做穩定也是需要一段時間的調試和修改的。

                對於爬蟲的功能來說。用戶比較關心的問題往往是:

                1)爬蟲支持多線程麼、爬蟲能用代理麼、爬蟲會爬取重複數據麼、爬蟲能爬取JS生成的信息麼?

                      不支持多線程、不支持代理、不能過濾重複URL的,那都不叫開源爬蟲,那叫循環執行http請求。

                      能不能爬js生成的信息和爬蟲本身沒有太大關係。爬蟲主要是負責遍歷網站和下載頁面。爬js生成的信息和網頁信息抽取模塊有關,往往需要通過模擬瀏覽器(htmlunit,selenium)來完成。這些模擬瀏覽器,往往需要耗費很多的時間來處理一個頁面。所以一種策略就是,使用這些爬蟲來遍歷網站,遇到需要解析的頁面,就將網頁的相關信息提交給模擬瀏覽器,來完成JS生成信息的抽取。

                2)爬蟲可以爬取ajax信息麼?

                     網頁上有一些異步加載的數據,爬取這些數據有兩種方法:使用模擬瀏覽器(問題1中描述過了),或者分析ajax的http請求,自己生成ajax請求的url,獲取返回的數據。如果是自己生成ajax請求,使用開源爬蟲的意義在哪裏?其實是要用開源爬蟲的線程池和URL管理功能(比如斷點爬取)。

                    如果我已經可以生成我所需要的ajax請求(列表),如何用這些爬蟲來對這些請求進行爬取?                   

                    爬蟲往往都是設計成廣度遍歷或者深度遍歷的模式,去遍歷靜態或者動態頁面。爬取ajax信息屬於deep web(深網)的範疇,雖然大多數爬蟲都不直接支持。但是也可以通過一些方法來完成。比如WebCollector使用廣度遍歷來遍歷網站。爬蟲的第一輪爬取就是爬取種子集合(seeds)中的所有url。簡單來說,就是將生成的ajax請求作爲種子,放入爬蟲。用爬蟲對這些種子,進行深度爲1的廣度遍歷(默認就是廣度遍歷)。

                3)爬蟲怎麼爬取要登陸的網站?

                    這些開源爬蟲都支持在爬取時指定cookies,模擬登陸主要是靠cookies。至於cookies怎麼獲取,不是爬蟲管的事情。你可以手動獲取、用http請求模擬登陸或者用模擬瀏覽器自動登陸獲取cookie。

                4)爬蟲怎麼抽取網頁的信息?

                       開源爬蟲一般都會集成網頁抽取工具。主要支持兩種規範:CSS SELECTOR和XPATH。至於哪個好,這裏不評價。

                5)爬蟲怎麼保存網頁的信息?

                       有一些爬蟲,自帶一個模塊負責持久化。比如webmagic,有一個模塊叫pipeline。通過簡單地配置,可以將爬蟲抽取到的信息,持久化到文件、數據庫等。還有一些爬蟲,並沒有直接給用戶提供數據持久化的模塊。比如crawler4j和webcollector。讓用戶自己在網頁處理模塊中添加提交數據庫的操作。至於使用pipeline這種模塊好不好,就和操作數據庫使用ORM好不好這個問題類似,取決於你的業務。

                6)爬蟲被網站封了怎麼辦?

                       爬蟲被網站封了,一般用多代理(隨機代理)就可以解決。但是這些開源爬蟲一般沒有直接支持隨機代理的切換。所以用戶往往都需要自己將獲取的代理,放到一個全局數組中,自己寫一個代理隨機獲取(從數組中)的代碼。

                7)網頁可以調用爬蟲麼?

                       爬蟲的調用是在Web的服務端調用的,平時怎麼用就怎麼用,這些爬蟲都可以使用。

                8)爬蟲速度怎麼樣? 

                      單機開源爬蟲的速度,基本都可以講本機的網速用到極限。爬蟲的速度慢,往往是因爲用戶把線程數開少了、網速慢,或者在數據持久化時,和數據庫的交互速度慢。而這些東西,往往都是用戶的機器和二次開發的代碼決定的。這些開源爬蟲的速度,都很可以。

                9)明明代碼寫對了,爬不到數據,是不是爬蟲有問題,換個爬蟲能解決麼?

                      如果代碼寫對了,又爬不到數據,換其他爬蟲也是一樣爬不到。遇到這種情況,要麼是網站把你封了,要麼是你爬的數據是javascript生成的。爬不到數據通過換爬蟲是不能解決的。

                10)哪個爬蟲可以判斷網站是否爬完、那個爬蟲可以根據主題進行爬取?

                       爬蟲無法判斷網站是否爬完,只能儘可能覆蓋。

                       至於根據主題爬取,爬蟲之後把內容爬下來才知道是什麼主題。所以一般都是整個爬下來,然後再去篩選內容。如果嫌爬的太泛,可以通過限制URL正則等方式,來縮小一下範圍。

                 11)哪個爬蟲的設計模式和構架比較好?

                       設計模式純屬扯淡。說軟件設計模式好的,都是軟件開發完,然後總結出幾個設計模式。設計模式對軟件開發沒有指導性作用。用設計模式來設計爬蟲,只會使得爬蟲的設計更加臃腫。

                       至於構架,開源爬蟲目前主要是細節的數據結構的設計,比如爬取線程池、任務隊列,這些大家都能控制好。爬蟲的業務太簡單,談不上什麼構架。

   

        所以對於JAVA開源爬蟲,我覺得,隨便找一個用的順手的就可以。如果業務複雜,拿哪個爬蟲來,都是要經過複雜的二次開發,纔可以滿足需求。


       第三類:非JAVA單機爬蟲

               在非JAVA語言編寫的爬蟲中,有很多優秀的爬蟲。這裏單獨提取出來作爲一類,並不是針對爬蟲本身的質量進行討論,而是針對larbin、scrapy這類爬蟲,對開發成本的影響。

              先說python爬蟲,python可以用30行代碼,完成JAVA  50行代碼乾的任務。python寫代碼的確快,但是在調試代碼的階段,python代碼的調試往往會耗費遠遠多於編碼階段省下的時間。使用python開發,要保證程序的正確性和穩定性,就需要寫更多的測試模塊。當然如果爬取規模不大、爬取業務不復雜,使用scrapy這種爬蟲也是蠻不錯的,可以輕鬆完成爬取任務。           

              對於C++爬蟲來說,學習成本會比較大。而且不能只計算一個人的學習成本,如果軟件需要團隊開發或者交接,那就是很多人的學習成本了。軟件的調試也不是那麼容易。 

              還有一些ruby、php的爬蟲,這裏不多評價。的確有一些非常小型的數據採集任務,用ruby或者php很方便。但是選擇這些語言的開源爬蟲,一方面要調研一下相關的生態圈,還有就是,這些開源爬蟲可能會出一些你搜不到的BUG(用的人少、資料也少)。


可以加入網絡爬蟲技術社區一起討論:

       http://nutcher.org








發佈了90 篇原創文章 · 獲贊 67 · 訪問量 52萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章