基於webmagic的爬蟲專案經驗小結

weixin_34226182發表於2015-12-05

大概在1個月前,利用webmagic做了一個爬蟲專案,下面是該專案的一些個人心得,貼在這裡備份:

一、為什麼選擇webmagic?

說實話,開源的爬蟲框架已經很多了,有各種語言(比如:python、java)實現的,有單機的,還有大型分散式的,多達上百種,詳情可見:

http://www.oschina.net/project/tag/64/spider?lang=0&os=0&sort=view&

github上隨手搜尋一下spider之類的關鍵字,也不計其數,如何選擇呢?

我的標準其實很簡單:

a) 要有一定量的使用群體(即:用的人越多越好),有人實際在用的專案,才會有生命力

b) 文件要全(沒有文件或文件不全的專案,學起來太費勁)

c) 使用起來要簡單,越傻瓜越好(否則,如果要先安裝這,安裝那,弄一堆依賴的東西,太花時間了)

d) 爬蟲的主要功能要有,比如:支援多執行緒,url自動去重複,html解析方便(至少要能支援css選擇器,xpath選擇器,正規表示式等常見的解析方式

e) 架構不要太龐大,越輕巧越好,簡單的設計,意味著擴充套件起來比較容易,有些功能如果要自行擴充套件,直接繼承一個類就完事了

把這些因素考慮進去後,綜合下來,選擇了webmagic,作者很用心,有一個很完整的教科書式的線上文件:http://webmagic.io/docs/zh/ 基本上花半天時間看完,就明白爬蟲是怎麼回事了。

 

二、如何設計自己的專案架構

選定好一款爬蟲開源框架後,就要考慮自己的業務特點,設計自己的專案架構了,大多數用爬蟲的人,基本需求其實是類似的:

a) 將目標網站的頁面儘可能快速的扒下來

b) 然後解析出有用的內容

c) 落地儲存到db中

但凡稍微成熟一些的爬蟲的開源框架,步驟a)所需的技術細節,基本上都已經實現了(比如:如何發起http請求,如何進行多執行緒控制等等),直接拿來用即可,但是解析哪些內容,用什麼規則解析,這是每個專案的業務來決定的,需要自己處理,解析完了以後,如何落地,以及目標網站的內容變了,如何設計自己的更新爬取策略,這也是要認真考慮的。

 

我的個人經驗:

專案分成3個模組:

---- 1)spider(爬取模組) ,

---- 2)parser(解析及db入庫模組) ,

---- 3)schdule(更新爬取計劃任務模組)

模組1)與3)可以打包在同一個jar中集中部署,模組2)單獨部署,之所以這樣設計,出於以下考慮:

通常最終儲存內容的db小型專案中只會有一個,儘管爬蟲支援多執行緒併發爬取,可以分散式的高效狂爬,但是db是一個慢速的IO瓶頸,如果把 "爬取->解析->入庫"全放在一個模組中按順序同步處理,最後的結果相當於前面有幾個水管收集水源,但是最後進入水庫的總管道不給力,整體的蓄水效率還是很慢。

分開之後,爬取模組可以同時部署多個,然後將得到的html集中儲存在1個目錄下,再按子目錄儲存(比如:一個大型網站,會有很多分站,可以例項A爬上海站,例項B爬北京站...),這樣可以儘可能快的把內容先撈回來。然後由解析模組,再到這個目錄下將檔案取出來慢慢解析入庫,解析成功後將原始檔案刪除(或移到其它目錄備份,這個看情況而定),如果程式碼有問題,比如解析規則有bug,導致某些頁面解析失敗,因為原始html檔案已經在本機儲存,修正解析的bug後,可以再試重新解析失敗的檔案,而不需要重新爬取。

至於爬取模組完成後,如何通知解析模組去開始解析入庫,有很多辦法,比如訊息佇列,zookeeper訂閱節點狀態變化,或者在某個目錄下放置一個標記檔案 之類的都可以。

 

三、如何更有效的更新爬取

通常爬取時,會先從一個所謂的"種子URL"層層引導,直到發現最終的目標url,首次爬取時,可以將最終頁面的url及http的返回碼(404,500,200之類)記錄下來,下次更新爬取時,直接重新爬取這些http狀態為200的最終頁面即可,這樣省去了再次從seed頁面層層分析的過程。(當然,這個要看自身專案的特點,如果seed頁的內容本身會週期性的變化,那就省不了從seed頁重新爬取的過程)

 

四、其它一些可能會遇到的問題

a) xpath的問題

webmagic提供的xpath解析工具,不支援xpath2.0的一些高階特性,比如:查詢父節點之類,解析時可以考慮引入其它一些第三方開源庫,比如dom4j來處理,反正html內容已經儲存到硬碟上了,想咋解析都行(但是dom4j也有一個缺點,返回的html必須是嚴格符合xml規範的,有些網頁的html原始碼,標籤沒有正常結束,會導致dom4j出錯)

b) ajax的問題

有些資料是通過ajax動態請求得到的,在目標網站上並未以a連結的方式明顯給出,這種情況可以根據用一些瀏覽器的開發者工具,觀察最終發出去的ajax請求,如果ajax請求的url是有規律的,可以直接在webmagic中用類似 page.addTargetRequests("xxx")的方式手動新增。

c) post的問題

webmagic目前的版本,不支援post方式的url爬取,據說以後的版本會考慮,這個暫時可以手動寫httpclient來發起post請求,最終拿到資料 

d)如何對應有防爬機制的網站

這個沒有一勞永逸的辦法,具體情況具體分析,

 -- 有些網站會限制url訪問的頻率(比如:同1個ip1分鐘內只能訪問某個頁面N次),這種需要手動在程式碼裡控制下節奏,比如每次http請求後,加入sleep(5000)之類的,

 -- 有些網站會根據http請求header中的User-Agent來判斷是否是同一款瀏覽器在惡意刷,這種可以在程式碼中手動弄一個User-Agent列表,把市面上的所有User-Agent全加進去,每次請求前,隨機從列表中取一個User-Agent,這樣看起來,貌似有很多不同的瀏覽器在訪問,顯得真實一點。但是有一點要注意,目前很多大型網站都提供了pc版與移動版的頁面,如果在pc瀏覽器上訪問,對方會返回pc版的網頁,如果用手機訪問,會返回移動版的頁面,很多就是根據User-Agent來判斷的(因為PC瀏覽器與手機瀏覽器對應的User-Agent資訊不同),如果你希望每次爬蟲訪問的都是PC版的頁面,用程式碼設定User-Agent時,要小心別弄錯了。

 -- 有些網站會限制IP,甚至有IP黑名單機制,對於這種出狠招的網站,我們也只能放大招:花點錢,找一群代理伺服器,在爬蟲程式碼裡,隨機切換代理伺服器。

 

最後,希望大家爬取順利。

相關文章