開發網絡爬蟲應該如何選擇爬蟲框架?
有些人問,開發網絡爬蟲應該選擇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在網絡爬蟲這塊的生態圈是很完好的。
相關的資料也是最全的。這裏可能有爭議,我僅僅是隨便扯淡。
事實上開源網絡爬蟲(框架)的開發很easy,難問題和復雜的問題都被曾經的人攻克了(比方DOM樹解析和定位、字符集檢測、海量URL去重),能夠說是毫無技術含量。包含Nutch,事實上Nutch的技術難點是開發hadoop,本身代碼很easy。網絡爬蟲從某種意義來說。類似遍歷本機的文件,查找文件裏的信息。
沒有不論什麽難度可言。之所以選擇開源爬蟲框架。就是為了省事。比方爬蟲的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++爬蟲來說,學習成本會比較大。
並且不能僅僅計算一個人的學習成本,假設軟件須要團隊開發或者交接,那就是非常多人的學習成本了。軟件的調試也不是那麽easy。
另一些ruby、php的爬蟲。這裏不多評價。的確有一些非常小型的數據採集任務,用ruby或者php非常方便。可是選擇這些語言的開源爬蟲,一方面要調研一下相關的生態圈,還有就是,這些開源爬蟲可能會出一些你搜不到的BUG(用的人少、資料也少)。
能夠增加網絡爬蟲技術社區一起討論:
http://nutcher.org
開發網絡爬蟲應該如何選擇爬蟲框架?