標籤:分布式 爬蟲 scrapy scrapy-redis
一 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等。