天天看點

scrapy-redis 更改隊列和分布式爬蟲

為初學者友善對分布式爬蟲的學習,總結了一下自己的了解和網上的知識點

初學者的幾個疑問點:

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 更改隊列和分布式爬蟲

總結:

要實作分布式爬蟲,首先引入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是請求隊列

scrapy-redis 更改隊列和分布式爬蟲