使用scrapy的定製爬蟲-第三章-爬蟲的javascript支持

-.-編輯中.我語文是數學老師教的...
後續補充參考代碼,連接. javascript

不少網站都使用javascript...網頁內容由js動態生成,一些js事件觸發的頁面內容變化,連接打開.甚至有些網站在沒有js的狀況下根本不工做,取而代之返回你一條相似"請打開瀏覽器js"之類的內容. java

對javascript的支持有四種解決方案:
1,寫代碼模擬相關js邏輯.
2,調用一個有界面的瀏覽器,相似各類普遍用於測試的,selenium這類.
3,使用一個無界面的瀏覽器,各類基於webkit的,casperjs,phantomjs等等.
4,結合一個js執行引擎,本身實現一個輕量級的瀏覽器.難度很大. python

對於簡單的有限爬取任務,若能夠經過代碼模擬js邏輯,首選這種方案,例如,在duckduckgo搜索引擎中,翻頁這個動做是靠js觸發的.模擬彷佛仍是很難,而後我注意到他頁面的第二個form,彷佛submit後就能夠翻頁,試了一下果真如此.
在寫代碼模擬相關js邏輯時,首先試下關閉瀏覽器的js,看下是否能獲取到須要的東西.有些頁面提供了沒有js的兼容.不行再開chrome的控制檯或firebug觀察js邏輯,多是ajax這類收發包.用urllib2(推薦requests庫)模擬便可,也多是修改dom之類,用lxml這類對應修改便可.說來就是js執行了什麼,就用python代碼對應模擬執行. web

也可選擇使用selenium這類,缺點是效率很低,你應當先測試一下selenium啓動一個瀏覽器實例所需時間你是否可接受.這個時間通常在秒級別.再考慮到瀏覽器打開頁面渲染,就更慢了.在效率可接受的前提下,這個方案也不錯.
這個方案的另外一個問題是在沒有桌面環境的服務器上,selenium目測沒法運行. ajax

對規模不小,模擬js不可行,selenium效率過低,或須要在無桌面環境上執行的狀況.有無界面瀏覽器,幾個無界面瀏覽器大致狀況以下:
1,casperjs,phantomjs:非py,能夠經過命令行調用,功能基本知足,推薦先看下這兩個是否知足.比較成熟.phantomjs還有一個非官方的webdriver協議實現,由此可經過selenium調phantomjs實現無界面.
2,ghost,spynner等:py定製的webkit,我的以爲spynner代碼亂,ghost代碼質量不錯.但有bug.我看過幾個這類庫後本身改了一個.
這種方案的詳細狀況見下面. redis

最後還有一種選擇,在js執行引擎的基礎上,本身實現一個輕量級的支持js的無界面瀏覽器.除非你有很是很是很是多須要爬取的內容,效率十分十分十分重要.若你有這個想法,能夠看下pyv8,在v8的示例代碼中有一個基於v8實現的簡易瀏覽器模型.是的,只是個模型,並不徹底可用,你要本身填充裏面的一些方法.實現這些你須要在js引擎(v8),http庫(urllib2)之上實現這些功能,1,當網頁打開時獲取其包含的js代碼,2,構建一個瀏覽器模型,包括各類事件與dom樹.3,執行js.除此以外可能還有其餘一些細節.難度較大.
網上能夠找到一淘所用購物比價爬蟲的一篇相關ppt.該爬蟲也僅使用的第三種方案.能夠看下這篇ppt.該爬蟲大概是用的webkit,scrapy,另外把scrapy的調度隊列改成基於redis的,實現分佈式. chrome

如何實現: 數據庫

回頭談點背景知識,scrapy使用了twisted.一個異步網絡框架.所以要留意潛在的阻塞狀況.但注意到settings中有個參數是設置ItemPipeline的並行度.由此推測pipeline不會阻塞,pipeline多是在線程池中執行的(未驗證).Pipeline通常用於將抓取到的信息保存(寫數據庫,寫文件),所以這裏你就不用擔憂耗時操做會阻塞整個框架了,也就不用在Pipeline中將這個寫操做實現爲異步.
除此以外框架的其餘部分.都是異步的,簡單說來就是,爬蟲生成的請求交由調度器去下載,而後爬蟲繼續執行.調度器完成下載後會將響應交由爬蟲解析. 瀏覽器

網上找到的參考例子,部分將js支持寫到了DownloaderMiddleware中,scrapy官網的code snippet也是這樣 .若這樣實現,就阻塞了整個框架,爬蟲的工做模式變成了,下載-解析-下載-解析,而不在是並行的下載.在對效率要求不高的小規模爬取中問題不大.
更好的作法是將js支持寫到scrapy的downloader裏.網上有一個這樣的實現(使用selenium+phantomjs).不過僅支持get請求. 服務器

在適配一個webkit給scrapy的downloader時,有各類細節須要處理. 待續......

相關文章
相關標籤/搜索