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,配置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:pass@hostname:9001'

設置爲爲True則不會清空redis裏的dupefilter和requests隊列
這樣設置後指紋和請求隊列則會一直保存在redis數據庫中,默認爲False,一般不進行設置

SCHEDULER_PERSIST = True

設置重啓爬蟲時是否清空爬取隊列
這樣每次重啓爬蟲都會清空指紋和請求隊列,一般設置爲False
SCHEDULER_FLUSH_ON_START=True

分佈式

將上述更改後的代碼拷貝的各個服務器,當然關於數據庫這裏可以在每個服務器上都安裝數據,也可以共用一個數據,我這裏方面是連接的同一個MySQL數據庫,當然各個服務器上也不能忘記: 所有的服務器都要安裝scrapy,scrapy_redis,pymysql

這樣運行各個爬蟲程序啓動後,在redis數據庫就可以看到如下內容,dupefilter是指紋隊列,requests是請求隊列

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章