Scrapy是一個比較好用的Python爬蟲框架,你只須要編寫幾個組件就能夠實現網頁數據的爬取。可是當咱們要爬取的頁面很是多的時候,單個服務器的處理能力就不能知足咱們的需求了(不管是處理速度仍是網絡請求的併發數),這時候分佈式爬蟲的優點就顯現出來。
redis
而Scrapy-Redis則是一個基於Redis的Scrapy分佈式組件。它利用Redis對用於爬取的請求(Requests)進行存儲和調度(Schedule),並對爬取產生的項目(items)存儲以供後續處理使用。scrapy-redi重寫了scrapy一些比較關鍵的代碼,將scrapy變成一個能夠在多個主機上同時運行的分佈式爬蟲。vim
說白了,就是使用redis來維護一個url隊列,而後scrapy爬蟲都鏈接這一個redis獲取url,且當爬蟲在redis處拿走了一個url後,redis會將這個url從隊列中清除,保證不會被2個爬蟲拿到同一個url,即便可能2個爬蟲同時請求拿到同一個url,在返回結果的時候redis還會再作一次去重處理,因此這樣就能達到分佈式效果,咱們拿一臺主機作redis 隊列,而後在其餘主機上運行爬蟲.且scrapy-redis會一直保持與redis的鏈接,因此即便當redis 隊列中沒有了url,爬蟲會定時刷新請求,一旦當隊列中有新的url後,爬蟲就當即開始繼續爬緩存
首先分別在主機和從機上安裝須要的爬蟲庫安全
pip3 install requests scrapy scrapy-redis redis
在主機中安裝redis服務器
#安裝redis yum install redis 啓動服務 systemctl start redis 查看版本號 redis-cli --version 設置開機啓動 systemctl enable redis.service
修改redis配置文件 vim /etc/redis.conf 將保護模式設爲no,同時註釋掉bind,爲了能夠遠程訪問,另外須要注意阿里雲安全策略也須要暴露6379端口網絡
#bind 127.0.0.1 protected-mode no
改完配置後,別忘了重啓服務才能生效併發
systemctl restart redis
而後分別新建爬蟲項目框架
scrapy startproject myspider
在項目的spiders目錄下新建test.pyscrapy
#導包 import scrapy import os from scrapy_redis.spiders import RedisSpider #定義抓取類 #class Test(scrapy.Spider): class Test(RedisSpider): #定義爬蟲名稱,和命令行運行時的名稱吻合 name = "test" #定義redis的key redis_key = 'test:start_urls' #定義頭部信息 haders = { 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/73.0.3683.86 Chrome/73.0.3683.86 Safari/537.36' } def parse(self, response): print(response.url) pass
而後修改配置文件settings.py,增長下面的配置,其中redis地址就是在主機中配置好的redis地址:分佈式
BOT_NAME = 'myspider' SPIDER_MODULES = ['myspider.spiders'] NEWSPIDER_MODULE = 'myspider.spiders' #設置中文編碼 FEED_EXPORT_ENCODING = 'utf-8' # scrapy-redis 主機地址 REDIS_URL = 'redis://root@39.106.228.179:6379' #隊列調度 SCHEDULER = "scrapy_redis.scheduler.Scheduler" #不清除緩存 SCHEDULER_PERSIST = True #經過redis去重 DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter" #不遵循robots ROBOTSTXT_OBEY = False
最後,能夠在兩臺主機上分別啓動scrapy服務
scrapy crawl test
此時,服務已經起來了,只不過redis隊列中沒有任務,在等待狀態
進入主機的redis
redis-cli
將任務隊列push進redis
lpush test:start_urls http://baidu.com
lpush test:start_urls http://chouti.com
能夠看到,兩臺服務器的爬蟲服務分別領取了隊列中的任務進行抓取,同時利用redis的特性,url不會重複抓取
爬取任務結束以後,能夠經過flushdb命令來清除地址指紋,這樣就能夠再次抓取歷史地址了。