scrapy-redis實現爬蟲分散式爬取分析與實現
阿新 • • 發佈:2019-01-30
一 scrapy-redis實現分散式爬取分析
所謂的scrapy-redis實際上就是scrapy+redis其中對redis的操作採用redis-py客戶端。這裡的redis的作用以及在scrapy-redis的方向我在自己fork的repository(連結:https://github.com/younghz/scrapy-redis)已經做了翻譯(README.rst)。在前面一篇文章中我已經藉助兩篇相關文章分析了使用redis實現爬蟲分散式的中心。歸結起來就是:所有爬蟲獲取到的url(request)都放到一個redis queue中,並且所有爬蟲都從單個redis queue中獲取request(url)。
scrapy-redis已經很長時間沒有更新,如何是它相容更新版本的scrapy我在博文(連結:
二 分散式爬取實現
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中(https://github.com/younghz/scrapy-redis/)。為了易於觀察,設定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出來。
iii)問題:上述ii中的排程方式是怎樣實現的?
在scrapy-redis中預設使用的是SpiderPriorityQueue方式,這是由sorted set實現的一種非FIFO、LIFO方式。
3. 細節分析與注意點
每次執行重新爬取,應該將redis中儲存的資料清空,否則影響爬取現象。
4. 其它
request和url區別:前者是由後者經由函式make_request_from_url實現,並且這個過程由spider完成。spider會返回(return、yield)request給scrapy引擎進而交割排程器。url也是在spider中定義或由spider獲取的。
spider和crawler:
spider不同於crawler。crawler包含spider。scrapy的架構就是crawler,spider作用為:提供start_url,根據下載到的response分析獲取想要的內容,繼續提取url等。