scrapy和scrapy-redis的區別

scrapy是一個python爬蟲框架,爬取的效率極高,具備高度的定製性,可是不支持分佈式。而scrapy-redis是一套基於redis庫,運行在scrapy框架之上的組件,可讓scapy支持分佈式策略html

Slaver端共享Master端redis數據庫裏的item 隊列、請求隊列和請求指紋集合。python

選擇redis數據庫的緣由:react

  redis支持主從同步,並且數據都是緩存在內存中的,因此基於redis的分佈式爬蟲,對請求和數據的高頻率讀取效率都很是高redis

    scrapy-redis和scrapy的關係就像電腦和固態硬盤同樣,是電腦中的一個插件,能讓電腦更快的運行數據庫

    scrapy是一個爬蟲框架,scrapy-redis則是這個框架上能夠選擇的插件,它可讓爬蟲跑得更緩存

 

 

解釋說明:

  1. 從優先級隊列中獲取requests對象,交給engine
  2. engine將requests對此昂交給下載器下載,期間會經過downlomiddleware的process_request方法
  3. 下載器完成下載,得到response對象,將該對象交給engine,期間會通過downloadmiddleware的process_response()方法
  4. engine將得到的response對象交給spider進行解析,期間會通過spidermiddleware的process_spider_input()方法
  5. spider解析下載器下載下來的response,返回item或links(url)
  6. item或者link通過spidermiddleware的process_spider_out()方法,交給engine
  7. engine將item交給item pipeline,將links交給調度器
  8. 在調度器中,先將requests對象利用scrapy內置的指紋函數生成一個指紋
  9. 若是requests對象中的don't filter參數設置爲False,而且該requests對象的指紋不在信息指紋的隊列中,那麼就把該requests對象放到優先級隊列中

 

中間件:

  spider與engine之間(爬蟲中間件)服務器

    介於scrapy引擎和爬蟲之間的框架,主要工做就是處理爬蟲的響應輸入和請求的輸出python爬蟲

  download與engine之間(下載器中間件)框架

    介於scrapy引擎和下載器之間的框架,主要是處理scrapy引擎與下載器之間的請求和響應異步

 

scrapy框架中的middleware.py

  1. Scrapy Middleware有如下幾個函數被管理
    1. process_spider_input:接收一個response對象並處理
    2. process_spider_exception:spider出現異常時被調用
    3. process_spider_output:當spider處理response返回result時,就會調用該方法
    4. process_spider_requests:當spider發出請求時,被調用
  2. Download Middleware有如下幾個函數被管理
    1. process_requests:requests經過下載中間件的時候,該方法被調用,這裏能夠經過設置代理,設置request.meta['proxy']就OK了
    2. process_response:下載結果通過中間件的時候會被這個方法解惑來進行處理
    3. process_exception:下載過程當中出現異常的時候會被調用

 

Scrapy的優缺點:

  1. 優勢
    1. scrapy是異步處理的,寫middleware,方便寫一些統一的過濾器
  2. 缺點
    1. 基於python的爬蟲框架,擴展性比較差,基於twisted框架,運行中的exception是不會幹掉reactor,而且異步框架出錯後是不會停掉其餘任務的,數據出錯後難以察覺

 

Scrapy-Redis提供了四種組件(四種組件也就意味着這四個模塊都須要作出相應的改動):

  1. Scheduler
    1. scrapy改變了python本來的collection.deque(雙向隊列)造成了本身的Scrapy queue,可是Scrapy多個spider不能共享爬取隊列Scrapy queue,也就是Scrapy自己不支持爬蟲的分佈式,scrapy-redis的解決是把這個Scrapy queue換成了redis數據庫(也是指redis隊列),從同一個redis-server存放要爬取的request,就可讓多個爬蟲去同一個數據庫裏讀取了
    2. scrapy中跟待爬隊列直接相關的就是調度器Scheduler,它負責對新的request進行入列操做(加入到Scrapy queue),取出下一個要爬的request(從Scrapy queue中取出來)等操做。它把待爬隊列按照優先級創建一個字典結構,而後根據request中的優先級,再來決定該入哪一個隊列,出列時就按照優先級較小的優先出列,爲了管理這個比較高級的隊列字典,Scheduler須要提供一系列的方法,可是原來的Scheduler已經沒法使用,因此使用Scrapy-redis的Scheduler組件
  2. Duplication Filter
    1. scrapy中用集合實現這個request的去重功能,scrapy中把已經發送的request指紋放入到一個集合中,把下一個request的指紋拿到集合中進行比較,若是該指紋已經存在集合中了,說了這個request發送過了,若是沒有的話就繼續這個操做
    2. 在scrapy-redis中去重是由Duplication Filter組件來實現的,它經過redis的set不重複的特性,巧妙的實現了Duplicating Filter去重。scrapy-redis調度器從引擎接受request,將request的指紋存入redis的set檢查是否產生了重複,並將不重複的request push寫入redis的request queue
    3. 引擎請求request時,調度器從redis的request queue隊列里根據優先級進行pop出一個request返回給engine,engine將這個request發送給spider進行處理
  3. Item Pipeline
    1. 引擎(spider返回的)將爬取到的item給item pipeline,scrapy-redis的item pipeline將爬取到的item存入到redis的items queue
    2. 修改過的item pipeline能夠很方便的根據key從items queue提取item,從而實現items processes集羣
  4. Base Spider
    1. 不在使用scrapy原有的Spider類,重寫RedisSpider繼承了Spider和RedisMixin這兩個類,RedisMixin是用來從redis中讀取url的類
    2. 當咱們生成一個Spider繼承RedisSpider的時候,調用setup_redis函數,這個函數會去鏈接redis數據庫,而後就設置signals(信號):一個是當spider空閒時候的signal,會調用spider_idle函數,這個函數調用scheduler_next_request函數,保證spider是一直活着的狀態,而且拋出DontCloseSpider異常,還有一個就是當抓到一個item的signal,會調用item_scrapy函數,這個函數會調用scheduler_next_request函數,獲取下一個request。

 

Scrapy-Redis分佈式策略:

    首先要說一下Master端和Slaver端

    1. Master
      1. 核心服務器,搭建Redis數據庫,不負責爬取,只負責url指紋判斷是否重複、request的分配、以及數據的存儲
    2. Slaver
      1. 爬蟲程序執行端,負責執行爬蟲程序,運行過程當中提交新的request給Master

    

    首先Slaver端從Master端拿任務(request, url)進行數據爬取,Slaver抓取數據的同時,產生新的request就提交給Master進行處理

    Master端只有一個Redis數據庫,負責將未處理的request去重和任務分配,將處理後的request加入待爬取的隊列,而且存儲爬取的數據

 

將scrapy變成scrapy-redis的過程(前提是已經安裝好了scrapy-redis)

  1. 修改settings.py配置文件,最簡單的方式就是使用redis來替換當前電腦的內存,而且同時配置好redis數據庫相關的內容
    # 這個是須要手動加上的,經過scrapy-redis自帶的pipeline將item存入redis中
    ITEM_PIPELINES = {'scrapy_redis.pipelines.RedisPipeline': 400 } # 啓動redis自帶的去重
    DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
    # 啓用調度器
    SCHEDULER = "scrapy_redis.scheduler.Scheduler"
    # 是否在關閉spider的時候保存記錄
    SCHEDULER_PERSIST = True # 使用優先級調度請求隊列(默認使用)
    SCHEDULER_QUEUE_CLASS = 
     'scrapy_redis.queue.SpiderPriorityQueue'
    # 指定redis的地址和端口,有密碼的須要加上密碼
    REDIS_HOST = '127.0.0.1' REDIS_PORT = '6379'
    # 若是你的redis設了密碼就須要加上密碼, REDIS_PARAMS = { 'password': '123456', }

     

     

 

原文出處:https://www.cnblogs.com/tulintao/p/11599741.html

相關文章
相關標籤/搜索