為初學者友善對分布式爬蟲的學習,總結了一下自己的了解和網上的知識點
初學者的幾個疑問點:
1.什麼是分布式爬蟲?
請參考:https://blog.csdn.net/zhusongziye/article/details/80457487
2.分布式爬蟲需要掌握哪些技能?
scrapy-redis原理
3.scrapy-redis是幹嗎用的?
記分布式爬蟲關鍵點:
(1)scrapy : 實作爬蟲的主體。scrapy是目前非常熱門的一種爬蟲架構,它把整個爬蟲過程分為了多個獨立的子產品,并提供了多個基類可以供我們去自由擴充,讓爬蟲編寫變得簡單而有邏輯性。并且scrapy自帶的多線程、異常處理、以及強大的自定義Settings也讓整個資料抓取過程變得高效而穩定。
(2)scrapy-redis:一個三方的基于redis的分布式爬蟲架構,配合scrapy使用,讓爬蟲具有了分布式爬取的功能。github位址: https://github.com/darkrho/scrapy-redis
(3)mongodb 、mysql 或其他資料庫:針對不同類型資料可以根據具體需求來選擇不同的資料庫存儲。結構化資料可以使用mysql節省空間,非結構化、文本等資料可以采用mongodb等非關系型資料提高通路速度。具體選擇可以自行百度谷歌,有很多關于sql和nosql的對比文章。
分布式原理:
scrapy-redis實作分布式,其實從原理上來說很簡單,這裡為描述友善,我們把自己的核心伺服器稱為master,而把用于跑爬蟲程式的機器稱為slave。
我們知 道,采用scrapy架構抓取網頁,我們需要首先給定它一些start_urls,爬蟲首先通路start_urls裡面的url,再根據我們的具體邏輯,對裡面的元素、或者是其他的二級、三級頁面進行抓取。而要實作分布式,我們隻需要在這個starts_urls裡面做文章就行了。
我們在master上搭建一個redis資料庫(注意這個資料庫隻用作url的存儲,不關心爬取的具體資料,不要和後面的mongodb或者mysql混淆),并對每一個需要爬取的網站類型,都開辟一個單獨的清單字段。通過設定slave上scrapy-redis擷取url的位址為master位址。這樣的結果就是,盡管有多個slave,然而大家擷取url的地方隻有一個,那就是伺服器master上的redis資料庫。
并且,由于scrapy-redis自身的隊列機制,slave擷取的連結不會互相沖突。這樣各個slave在完成抓取任務之後,再把擷取的結果彙總到伺服器上(這時的資料存儲不再在是redis,而是mongodb或者 mysql等存放具體内容的資料庫了)
這種方法的還有好處就是程式移植性強,隻要處理好路徑問題,把slave上的程式移植到另一台機器上運作,基本上就是複制粘貼的事情。
Scrapy-redis工作原理:
scrapy-redis的工作原理,就是把原來scrapy自帶的queue隊列用redis資料庫替換,隊列都在redis資料庫裡面了,每次存,取,删,去重,都在redis資料庫裡進行,那我們如何使用分布式呢,假設機器A有redis資料庫,我們在A上把url push到redis裡面,然後在機器B上啟動scrapy-redis爬蟲,在機器B上connect到A,有遠端端口可以登入,在爬蟲程式裡,儲存的時候注意啟用追加模式,而不是每次儲存都删除以前的東西,這樣的話,我們可以在B上面多次運作同一個程式。
如圖所示,其實連copy都不要,直接另開一個終端,接着運作同樣的程式即可。
當然我們也可以在機器C上同樣這樣運作,是以這就是分布式爬蟲。
總結:
要實作分布式爬蟲,首先引入scrapy-redis,配置settings,連接配接到redis資料庫,具體配置方式檢視詳情。配置完成以後,在主機B上進行同樣的配置,連接配接到同一個redis資料庫就行,并且啟用追加模式,共享隊列的具體配置:
修改該settings中的配置資訊:
替換scrapy排程器
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
添加去重的class
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
添加pipeline
如果添加這行配置,每次爬取的資料也都會入到redis資料庫中,是以一般這裡不做這個配置
ITEM_PIPELINES = {
'scrapy_redis.pipelines.RedisPipeline': 300
}
共享的爬取隊列,這裡用需要redis的連接配接資訊
這裡的user:pass表示使用者名和密碼,如果沒有則為空就可以
REDIS_URL = 'redis://user:[email protected]:9001'
設定為為True則不會清空redis裡的dupefilter和requests隊列
這樣設定後指紋和請求隊列則會一直儲存在redis資料庫中,預設為False,一般不進行設定
SCHEDULER_PERSIST = True
設定重新開機爬蟲時是否清空爬取隊列
這樣每次重新開機爬蟲都會清空指紋和請求隊列,一般設定為False
SCHEDULER_FLUSH_ON_START=True
分布式
将上述更改後的代碼拷貝的各個伺服器,當然關于資料庫這裡可以在每個伺服器上都安裝資料,也可以共用一個資料,我這裡方面是連接配接的同一個MySQL資料庫,當然各個伺服器上也不能忘記: 所有的伺服器都要安裝scrapy,scrapy_redis,pymysql
這樣運作各個爬蟲程式啟動後,在redis資料庫就可以看到如下内容,dupefilter是指紋隊列,requests是請求隊列