分佈式爬蟲原理之Scrapy分佈式實現

接下來,咱們會利用Scrapy-Redis來實現分佈式的對接。
html

1、準備工做

請確保已經成功實現了Scrapy新浪微博爬蟲,Scrapy-Redis庫已經正確安裝。
git

2、搭建Redis服務器

要實現分佈式部署,多臺主機須要共享爬取隊列和去重集合,而這兩部份內容都是存於Redis數據庫中的,咱們須要搭建一個可公網訪問的Redis服務器。
github

推薦使用Linux服務器,能夠購買阿里雲、騰訊雲、Azure等提供的雲主機,通常都會配有公網IP,具體的搭建方式能夠參考第1章中Redis數據庫的安裝方式。redis

Redis安裝完成以後就能夠遠程鏈接了,注意部分商家(如阿里雲、騰訊雲)的服務器須要配置安全組放通Redis運行端口才能夠遠程訪問。若是遇到不能遠程鏈接的問題,能夠排查安全組的設置。mongodb

須要記錄Redis的運行IP、端口、地址,供後面配置分佈式爬蟲使用。當前配置好的Redis的IP爲服務器的IP 120.27.34.25,端口爲默認的6379,密碼爲foobared。數據庫

3、部署代理池和Cookies池

新浪微博項目須要用到代理池和Cookies池,而以前咱們的代理池和Cookies池都是在本地運行的。因此咱們須要將兩者放到能夠被公網訪問的服務器上運行,將代碼上傳到服務器,修改Redis的鏈接信息配置,用一樣的方式運行代理池和Cookies池。
安全

遠程訪問代理池和Cookies池提供的接口,來獲取隨機代理和Cookies。若是不能遠程訪問,先確保其在0.0.0.0這個Host上運行,再檢查安全組的配置。bash

如我當前配置好的代理池和Cookies池的運行IP都是服務器的IP,120.27.34.25,端口分別爲5555和5556,以下圖所示。服務器

接下來咱們要修改Scrapy新浪微博項目中的訪問連接,以下所示:微信

PROXY_URL = 'http://120.27.34.25:5555/random'
COOKIES_URL = 'http://120.27.34.25:5556/weibo/random'複製代碼

具體的修改方式根據實際配置的IP和端口作相應調整。

4、配置Scrapy-Redis

配置Scrapy-Redis很是簡單,只須要修改一下settings.py配置文件便可。

1. 核心配置

首先最主要的是,須要將調度器的類和去重的類替換爲Scrapy-Redis提供的類,在settings.py裏面添加以下配置便可:

SCHEDULER = "scrapy_redis.scheduler.Scheduler"
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"複製代碼

2. Redis鏈接配置

接下來配置Redis的鏈接信息,這裏有兩種配置方式。

第一種方式是經過鏈接字符串配置。咱們能夠用Redis的地址、端口、密碼來構造一個Redis鏈接字符串,支持的鏈接形式以下所示:

redis://[:password]@host:port/db
rediss://[:password]@host:port/db
unix://[:password]@/path/to/socket.sock?db=db複製代碼

password是密碼,好比要以冒號開頭,中括號表明此選項無關緊要,host是Redis的地址,port是運行端口,db是數據庫代號,其值默認是0。

根據上文中提到個人Redis鏈接信息,構造這個Redis的鏈接字符串以下所示:

redis://:foobared@120.27.34.25:6379複製代碼

直接在settings.py裏面配置爲REDIS_URL變量便可:

REDIS_URL = 'redis://:foobared@120.27.34.25:6379'複製代碼

第二種配置方式是分項單獨配置。這個配置就更加直觀明瞭,如根據個人Redis鏈接信息,能夠在settings.py中配置以下代碼:

REDIS_HOST = '120.27.34.25'
REDIS_PORT = 6379
REDIS_PASSWORD = 'foobared'複製代碼

這段代碼分開配置了Redis的地址、端口和密碼。

注意,若是配置了REDIS_URL,那麼Scrapy-Redis將優先使用REDIS_URL鏈接,會覆蓋上面的三項配置。若是想要分項單獨配置的話,請不要配置REDIS_URL

在本項目中,我選擇的是配置REDIS_URL

3. 配置調度隊列

此項配置是可選的,默認使用PriorityQueue。若是想要更改配置,能夠配置SCHEDULER_QUEUE_CLASS變量,以下所示:

SCHEDULER_QUEUE_CLASS = 'scrapy_redis.queue.PriorityQueue'
SCHEDULER_QUEUE_CLASS = 'scrapy_redis.queue.FifoQueue'
SCHEDULER_QUEUE_CLASS = 'scrapy_redis.queue.LifoQueue'複製代碼

以上三行任選其一配置,便可切換爬取隊列的存儲方式。

在本項目中不進行任何配置,咱們使用默認配置。

4. 配置持久化

此配置是可選的,默認是False。Scrapy-Redis默認會在爬取所有完成後清空爬取隊列和去重指紋集合。

若是不想自動清空爬取隊列和去重指紋集合,能夠增長以下配置:

SCHEDULER_PERSIST = True複製代碼

SCHEDULER_PERSIST設置爲True以後,爬取隊列和去重指紋集合不會在爬取完成後自動清空,若是不配置,默認是False,即自動清空。

值得注意的是,若是強制中斷爬蟲的運行,爬取隊列和去重指紋集合是不會自動清空的。

在本項目中不進行任何配置,咱們使用默認配置。

5. 配置重爬

此配置是可選的,默認是False。若是配置了持久化或者強制中斷了爬蟲,那麼爬取隊列和指紋集合不會被清空,爬蟲從新啓動以後就會接着上次爬取。若是想從新爬取,咱們能夠配置重爬的選項:

SCHEDULER_FLUSH_ON_START = True複製代碼

這樣將SCHEDULER_FLUSH_ON_START設置爲True以後,爬蟲每次啓動時,爬取隊列和指紋集合都會清空。因此要作分佈式爬取,咱們必須保證只能清空一次,不然每一個爬蟲任務在啓動時都清空一次,就會把以前的爬取隊列清空,勢必會影響分佈式爬取。

注意,此配置在單機爬取的時候比較方便,分佈式爬取不經常使用此配置。

在本項目中不進行任何配置,咱們使用默認配置。

6. Pipeline配置

此配置是可選的,默認不啓動Pipeline。Scrapy-Redis實現了一個存儲到Redis的Item Pipeline,啓用了這個Pipeline的話,爬蟲會把生成的Item存儲到Redis數據庫中。在數據量比較大的狀況下,咱們通常不會這麼作。由於Redis是基於內存的,咱們利用的是它處理速度快的特性,用它來作存儲未免太浪費了,配置以下:

ITEM_PIPELINES = {
    'scrapy_redis.pipelines.RedisPipeline': 300
}複製代碼

本項目不進行任何配置,即不啓動Pipeline。

到此爲止,Scrapy-Redis的配置就完成了。有的選項咱們沒有配置,可是這些配置在其餘Scrapy項目中可能用到,要根據具體狀況而定。

5、配置存儲目標

以前Scrapy新浪微博爬蟲項目使用的存儲是MongoDB,並且MongoDB是本地運行的,即鏈接的是localhost。可是,當爬蟲程序分發到各臺主機運行的時候,爬蟲就會鏈接各自的的MongoDB。因此咱們須要在各臺主機上都安裝MongoDB,這樣有兩個缺點:一是搭建MongoDB環境比較繁瑣;二是這樣各臺主機的爬蟲會把爬取結果分散存到各自主機上,不方便統一管理。

因此咱們最好將存儲目標存到同一個地方,例如都存到同一個MongoDB數據庫中。咱們能夠在服務器上搭建一個MongoDB服務,或者直接購買MongoDB數據存儲服務。

這裏使用的就是服務器上搭建的的MongoDB服務,IP仍然爲120.27.34.25,用戶名爲admin,密碼爲admin123。

修改配置MONGO_URI爲以下:

MONGO_URI = 'mongodb://admin:admin123@120.27.34.25:27017'複製代碼

到此爲止,咱們就成功完成了Scrapy分佈式爬蟲的配置。

6、運行

接下來將代碼部署到各臺主機上,記得每臺主機都須要配好對應的Python環境。

每臺主機上都執行以下命令,便可啓動爬取:

scrapy crawl weibocn複製代碼

每臺主機啓動了此命令以後,就會從配置的Redis數據庫中調度Request,作到爬取隊列共享和指紋集合共享。同時每臺主機佔用各自的帶寬和處理器,不會互相影響,爬取效率成倍提升。

7、結果

一段時間後,咱們能夠用RedisDesktop觀察遠程Redis數據庫的信息。這裏會出現兩個Key:一個叫做weibocn:dupefilter,用來儲存指紋;另外一個叫做weibocn:requests,即爬取隊列,以下圖所示。

隨着時間的推移,指紋集合會不斷增加,爬取隊列會動態變化,爬取的數據也會被儲存到MongoDB數據庫中。

8、本節代碼

本節代碼地址爲:https://github.com/Python3WebSpider/Weibo/tree/distributed,注意這裏是distributed分支。

9、結語

本節經過對接Scrapy-Redis成功實現了分佈式爬蟲,可是部署仍是有不少不方便的地方。另外,若是爬取量特別大的話,Redis的內存也是個問題。在後文咱們會繼續瞭解相關優化方案。


本資源首發於崔慶才的我的博客靜覓: Python3網絡爬蟲開發實戰教程 | 靜覓

如想了解更多爬蟲資訊,請關注個人我的微信公衆號:進擊的Coder

weixin.qq.com/r/5zsjOyvEZ… (二維碼自動識別)

相關文章
相關標籤/搜索