scrapy-redis 和 scrapy 有什麼區別?
剛剛接觸scrapy,想讓scrapy實現分散式爬取,發現還有個東西叫做scrapy-redis,請問二者卻別是什麼
一時興起寫了篇回復,能給大家解決一點小問題,十分高興。但偶爾被誤認為是大牛,誠惶誠恐。
只是當初一點小愛好而已,大牛實在是不敢當。
另外要對私信給我請求幫助的朋友說聲抱歉,我已經離開技術崗位很長時間了,手頭上早已沒有了編程的環境,加上目前工作太多,對大家的問題也是有心無力(我這人太慫,也不敢給大家隨便丟個回復)。
最後祝大家學習爬蟲的路上一帆風順~(雖然不大可能,不過加油吧)
以下是正文
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
不妖自來~
我剛剛接觸scrapy的時候,也看過這個項目,奈何對scrapy本身就不怎麼熟悉,所以當時怎麼也想不明白,直到後來開始看scrapy 的源代碼,才漸漸明白。這裡提一下我的看法,水平有限,不敢保證完全正確,歡迎指正。
一、scrapy和scrapy-redis的主要區別在哪裡?
個人認為,scrapy和scrapy-redis不應該討論區別。
scrapy 是一個通用的爬蟲框架,其功能比較完善,可以幫你迅速的寫一個簡單爬蟲,並且跑起來。scrapy-redis是為了更方便地實現scrapy分散式爬取,而提供了一些以redis為基礎的組件(注意,scrapy-redis只是一些組件,而不是一個完整的框架)。你可以這麼認為,scrapy是一工廠,能夠出產你要的spider。而scrapy-redis是其他廠商為了幫助scrapy工廠更好的實現某些功能而製造了一些設備,用於替換scrapy工廠的原設備。
所以要想跑分散式,先讓scrapy工廠搭建起來,再用scrapy-redis設備去更換scrapy的某些設備。
那麼這些scrapy-redis組件有什麼突出特點呢?他們使用了redis資料庫來替換scrapy原本使用的隊列結構(deque),換了數據結構,那麼相應的操作當然都要換啦,所以與隊列相關的這些組件都做了更換。
二、scrapy-redis提供了哪些組件?
Scheduler、Dupefilter、Pipeline、Spider
提供了哪些組件具體見darkrho/scrapy-redis · GitHub。
三、為什麼要提供這些組件?
這要從哪哪哪說起(喝口水,默默地望著遠方......)
我們先從scrapy的「待爬隊列」和「Scheduler」入手:
咱們玩過爬蟲(什麼玩過,是學習過,研究過,愛過也被虐過)的同學都多多少少有些了解,在爬蟲爬取過程當中,有一個主要的數據結構是「待爬隊列」,以及能夠操作這個隊列的調度器(也就是Scheduler啦)。scrapy官方文檔對這二者的描述不多,基本上沒提。
scrapy使用什麼樣的數據結構來存放待爬取的request呢?
其實沒用高大上的數據結構,就是python自帶的collection.deque,不過當然是改造過後的啦(後面所說到的deque均是指scrapy改造之後的隊列,至於如何改造的,就去看代碼吧)。
詳見源代碼queuelib/queue.py at master · scrapy/queuelib · GitHub
不過咱們用一用deque就會意識到,該怎麼讓兩個以上的Spider共用這個deque呢?答案是,我水平不夠,不知道。那分散式怎麼實現呢,待爬隊列都不能共享,還玩個泥巴呀。scrapy-redis提供了一個解決方法,把deque換成redis資料庫,我們從同一個redis伺服器存放要爬取的request,這樣就能讓多個spider去同一個資料庫里讀取,這樣分散式的主要問題就解決了嘛。
---------------------------------------------------分割線的隨地大小便----------------------------------------------------------
那麼問題又來了,我們換了redis來存放隊列,哪scrapy就能直接分散式了么?(當初天真的我呀~
當然不能。我們接著往下說。scrapy中跟「待爬隊列」直接相關的就是調度器「Scheduler」:scrapy/scheduler.py at master · scrapy/scrapy · GitHub,它負責對新的request進行入列操作(加入deque),取出下一個要爬取的request(從deque中取出)等操作。
在scrapy中,Scheduler並不是直接就把deque拿來就粗暴的使用了,而且提供了一個比較高級的組織方法,它把待爬隊列按照優先順序建立了一個字典結構,比如:
{
priority0:隊列0
priority1:隊列2
priority2:隊列2
}
然後根據request中的priority屬性,來決定該入哪個隊列。而出列時,則按priority較小的優先出列。為了管理這個比較高級的隊列字典,Scheduler需要提供一系列的方法。說這麼多有什麼意義呢?最主要的指導意義就是:你要是換了redis做隊列,這個scrapy下的Scheduler就用不了,所以自己寫一個吧。
於是就出現了scrapy-redis的專用scheduler:scrapy-redis/scheduler.py at master · darkrho/scrapy-redis · GitHub,其實可以對比一下看,操作什麼的都差不太多。主要是操作的數據結構變了。
----------------------------------------------被當眾抓住的分割線---------------------------------------------------------
那麼既然使用了redis做主要數據結構,能不能把其他使用自帶數據結構關鍵功能模塊也換掉呢?(關鍵部分使用自帶數據結構簡直有種沒穿小內內的危機感,這是本人的想法~)
在我們爬取過程當中,還有一個重要的功能模塊,就是request去重(已經發送過得請求就別再發啦,也要考慮一下伺服器君的感受好伐)。
scrapy中把已經發送的request指紋放入到一個集合中,把下一個request的指紋拿到集合中比對,如果該指紋存在於集合中,說明這個request發送過了,如果沒有則繼續操作。這個核心的判重功能是這樣實現的:
def request_seen(self, request):
#self.figerprints就是一個指紋集合
fp = self.request_fingerprint(request)
if fp in self.fingerprints:#這就是判重的核心操作。
return True
self.fingerprints.add(fp)
......
詳見源代碼:scrapy/dupefilters.py at master · scrapy/scrapy · GitHub
為了分散式,把這個集合也換掉吧,換了redis,照樣也得把去重類給換了。
於是就有了scrapy-redis的dupefilter:scrapy-redis/dupefilter.py at master · darkrho/scrapy-redis · GitHub
------------------------------------------把分割線掀起來(╯‵□′)╯︵||||||\\\\\\------------------------------------
那麼依次類推,接下來的其他組件(Pipeline和Spider),我們也可以輕鬆的猜到,他們是為什麼要被修改呢。對,都是因為redis,全怪redis,redis是罪魁禍首。(其實我不知道,我只是在湊字數而已)
以上是我個人見解,不代表權威說法。希望對你有幫助。如有紕漏請指正(但是別打我
這個是他們有什麼區別,我想很多人都已經給了很多的答案,而且百度是你最好的老師。
但是我可以這樣簡單的形容一下我的理解:
scrapy是一個比較成熟的框架,你可以用它爬網站,但是在很多時候,會出現數據量太大,爬去速度太慢,這樣的話就需要做分散式爬蟲了,所以通常就把scrapy-redis扔來了,如題目所示,scrapy是爬蟲框架,redis是一個資料庫,也就是說,redis的資料庫名字叫A,你打開你的蟲子,他開始監聽,你再打開一個他又在監聽,你打開了n個都在監聽,然後你給他們仍一個初始網址,於是你之前打開的n個蟲子就開始動了。這個是他們的理論區別,關於代碼區別很簡單,就是spider開始的時候修改一下,settings適當改一改就可以
具體的你可以參考一下我的兩個網頁:
1:Scrapy-Redis:大創網項目採集(cy.ncss.org.cn)-Python學習-零度站
2:Scrapy學習:taobao.com商品數據採集(分類存入資料庫實例)-Python學習-零度站
scrapy 是爬蟲框架
scrapy-redis 是用redis替換了原本scrapy的爬蟲調度部分
讓他可以分散式運作,具體可以參考他的源代碼
推薦閱讀: