scrapy-redis實現爬蟲分散式爬取分析與實現

鴨脖發表於2015-05-20

一 scrapy-redis實現分散式爬取分析

所謂的scrapy-redis實際上就是scrapy+redis其中對redis的操作採用redis-py客戶端。這裡的redis的作用以及在scrapy-redis的方向我在自己fork的repository(連結:)已經做了翻譯(README.rst)。

在前面一篇文章中我已經藉助兩篇相關文章分析了使用redis實現爬蟲分散式的中心。歸結起來就是:所有爬蟲獲取到的url(request)都放到一個redis queue中,並且所有爬蟲都從單個redis queue中獲取request(url)。

scrapy-redis已經很長時間沒有更新,如何是它相容更新版本的scrapy我在博文(連結: http://blog.csdn.net/u012150179/article/details/38087661 )中也已經說明,後期我可能會用較新版本的scrapr介面重寫scrapy-redis。

二 分散式爬取實現

1. 對scrapy-redis中自帶example的分析

在庫的README中已經對example的使用做了說明,但是初步接觸時執行example中的spider會存在很多疑問,比如,分散式體現在哪?是通過那幾方面實現的?其次,在執行結果中很難發現分散式的影子,感覺就像兩個spider在自己爬自己的東西。

對於第一種疑問,我在翻譯和標註scrapy-redis中settings.py已經做了說明。而第二中疑問也是實現2中自己的example所要做的。

2. 更清晰驗證scrapy-redis實現分散式的思路與編碼實現。

(1)思路

實現兩個爬蟲,定義爬蟲A爬取dmoz.com的關鍵詞bussiness下的所有連結(通過start_urls設定)。爬蟲B爬取game下的所有連結,觀察二者同時執行時爬取連結的url,是各自範圍的url還是二者的交集。這樣由於二者定義的爬取範圍是不一致的,通過爬取現象可以得出結果。

(2)實現

程式碼放在了github的repo中。為了易於觀察,設定DEPTH_LIMIT為1。

(3)現象與分析

現象:可以發現,二者是首先同時爬取單個關鍵詞下的連結(首先爬取哪一個取決與先執行爬蟲的start_urls),完畢後進而爬取另一個關鍵詞下連結。

分析:通過同時爬取單個關鍵詞可以說明兩個爬蟲是同時被排程的,這就是爬蟲的分散式。並且爬蟲預設是廣度優先搜尋的。爬取的步驟如下:

i)首先執行爬蟲A(B同理),爬蟲引擎請求spider A中start_urls中的連結並交割排程器,進而引擎向排程器請求爬取的url並交給下載器下載,下載後的response交給spider,spider根據定義的rules得到連結,繼續通過引擎交給排程器。(這一系列過程可檢視scrapy架構)。其中排程器scheduler中request(url)順序是redis queue實現的,也就是將request(url)push到queue中,請求時pop出來。

ii)進而啟動B,同理B的start_urls首先交給了排程器(注意和A中的排程器是同一個),而B的引擎請求爬取url時,排程器排程給B下載的url還是A中沒下載完成的url(預設的排程方式是先排程返回的url,並且是廣度優先的),這是A和B同時下載A中未完成連結,待完成後,同時下載B的要求連結。

iii)問題:上述ii中的排程方式是怎樣實現的?

3. 細節分析與注意點

每次執行重新爬取,應該將redis中儲存的資料清空,否則影響爬取現象。

4. 其它

scrapy中request=url。

spider不同於crawler。crawler包含spider。scrapy的架構就是crawler,spider作用為:提供start_url,根據下載到的response分析獲取想要的內容,繼續提取url等。

相關文章