大概在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黑名單機制,對于這種出狠招的網站,我們也只能放大招:花點錢,找一群代理服務器,在爬蟲代碼里,隨機切換代理服務器。
最后,希望大家爬取順利。
文章列表