天天看點

scrapy定制爬蟲-爬取javascript

很多網站都使用javascript...網頁内容由js動态生成,一些js事件觸發的頁面内容變化,連結打開.甚至有些網站在沒有js的情況下根本不工作,取而代之傳回你一條類似"請打開浏覽器js"之類的内容.

對javascript的支援有四種解決方案:

1,寫代碼模拟相關js邏輯.

2,調用一個有界面的浏覽器,類似各種廣泛用于測試的,selenium這類.

3,使用一個無界面的浏覽器,各種基于webkit的,casperjs,phantomjs等等.

4,結合一個js執行引擎,自己實作一個輕量級的浏覽器.難度很大.

對于簡單的有限爬取任務,若可以通過代碼模拟js邏輯,首選這種方案,例如,在duckduckgo搜尋引擎中,翻頁這個動作是靠js觸發的.模拟似乎還是很難,然後我注意到他頁面的第二個form,似乎submit後就可以翻頁,試了一下果然如此.

在寫代碼模拟相關js邏輯時,首先試下關閉浏覽器的js,看下是否能擷取到需要的東西.有些頁面提供了沒有js的相容.不行再開chrome的控制台或firebug觀察js邏輯,可能是ajax這類收發包.用urllib2(推薦requests庫)模拟即可,也可能是修改dom之類,用lxml這類對應修改即可.說來就是js執行了什麼,就用python代碼對應模拟執行.

也可選擇使用selenium這類,缺點是效率很低,你應當先測試一下selenium啟動一個浏覽器執行個體所需時間你是否可接受.這個時間一般在秒級别.再考慮到浏覽器打開頁面渲染,就更慢了.在效率可接受的前提下,這個方案也不錯.

這個方案的另一個問題是在沒有桌面環境的伺服器上,selenium目測無法運作.

對規模不小,模拟js不可行,selenium效率太低,或需要在無桌面環境上執行的情況.有無界面浏覽器,幾個無界面浏覽器大體情況如下:

1,casperjs,phantomjs:非py,可以通過指令行調用,功能基本滿足,推薦先看下這兩個是否滿足.比較成熟.phantomjs還有一個非官方的webdriver協定實作,由此可通過selenium調phantomjs實作無界面.

2,ghost,spynner等:py定制的webkit,個人覺得spynner代碼亂,ghost代碼品質不錯.但有bug.我看過幾個這類庫後自己改了一個.

這種方案的詳細情況見下面.

最後還有一種選擇,在js執行引擎的基礎上,自己實作一個輕量級的支援js的無界面浏覽器.除非你有非常非常非常多需要爬取的内容,效率十分十分十分重要.若你有這個想法,可以看下pyv8,在v8的示例代碼中有一個基于v8實作的簡易浏覽器模型.是的,隻是個模型,并不完全可用,你要自己填充裡面的一些方法.實作這些你需要在js引擎(v8),http庫(urllib2)之上實作這些功能,1,當網頁打開時擷取其包含的js代碼,2,建構一個浏覽器模型,包括各種事件與dom樹.3,執行js.除此之外可能還有其他一些細節.難度較大.

網上可以找到一淘所用購物比價爬蟲的一篇相關ppt.該爬蟲也僅使用的第三種方案.可以看下這篇ppt.該爬蟲大概是用的webkit,scrapy,另外把scrapy的排程隊列改為基于redis的,實作分布式.

如何實作:

回頭談點背景知識,scrapy使用了twisted.一個異步網絡架構.是以要留意潛在的阻塞情況.但注意到settings中有個參數是設定ItemPipeline的并行度.由此推測pipeline不會阻塞,pipeline可能是線上程池中執行的(未驗證).Pipeline一般用于将抓取到的資訊儲存(寫資料庫,寫檔案),是以這裡你就不用擔心耗時操作會阻塞整個架構了,也就不用在Pipeline中将這個寫操作實作為異步.

除此之外架構的其他部分.都是異步的,簡單說來就是,爬蟲生成的請求交由排程器去下載下傳,然後爬蟲繼續執行.排程器完成下載下傳後會将響應交由爬蟲解析.

網上找到的參考例子,部分将js支援寫到了DownloaderMiddleware中,scrapy官網的code snippet也是這樣 .若這樣實作,就阻塞了整個架構,爬蟲的工作模式變成了,下載下傳-解析-下載下傳-解析,而不在是并行的下載下傳.在對效率要求不高的小規模爬取中問題不大.

更好的做法是将js支援寫到scrapy的downloader裡.網上有一個這樣的實作(使用selenium+phantomjs).不過僅支援get請求.

在适配一個webkit給scrapy的downloader時,有各種細節需要處理.

本文轉自 yntmdr 51CTO部落格,原文連結:http://blog.51cto.com/yntmdr/1904758,如需轉載請自行聯系原作者