Scrapy-Redis 空跑問題,redis_key連結跑完後,自動關閉爬蟲

來源:互聯網
上載者:User

標籤:support   請求   object   div   orm   col   期間   append   crawler   

首先解決爬蟲等待,不被關閉的問題:

1、scrapy內部的訊號系統會在爬蟲耗盡內部隊列中的request時,就會觸發spider_idle訊號。

2、爬蟲的訊號管理器收到spider_idle訊號後,將調用註冊spider_idle訊號的處理器進行處理。

3、當該訊號的所有處理器(handler)被調用後,如果spider仍然保持空閑狀態, 引擎將會關閉該spider。

scrapy-redis 中的解決方案 在訊號管理器上註冊一個對應在spider_idle訊號下的spider_idle()方法,當spider_idle觸發是,訊號管理器就會調用這個爬蟲中的spider_idle(), Scrapy_redis 源碼如下:

def spider_idle(self):        """Schedules a request if available, otherwise waits."""        # XXX: Handle a sentinel to close the spider.        self.schedule_next_requests()    # 這裡調用         schedule_next_requests() 來從redis中產生新的請求        raise DontCloseSpider              # 拋出不要關閉爬蟲DontCloseSpider異常,保證爬蟲活著
解決思路:
  • 通過前面的瞭解,我們知道 爬蟲關閉的關鍵是 spider_idle 訊號。
  • spider_idle訊號只有在爬蟲隊列為空白時才會被觸發, 觸發間隔為5s。
  • 那麼我們也可以使用同樣的方式,在訊號管理器上註冊一個對應在spider_idle訊號下的spider_idle()方法。
  • 在 spider_idle() 方法中,編寫結束條件來結束爬蟲,這裡以 判斷redis 中關鍵key 是否為空白,為條件

在settings.py 檔案的目錄下,建立一個名為 extensions.py 的檔案,在其中寫入以下代碼

# -*- coding: utf-8 -*-# Define here the models for your scraped Extensionsimport loggingimport timefrom scrapy import signalsfrom scrapy.exceptions import NotConfiguredlogger = logging.getLogger(__name__)class RedisSpiderSmartIdleClosedExensions(object):    def __init__(self, idle_number, crawler):        self.crawler = crawler        self.idle_number = idle_number        self.idle_list = []        self.idle_count = 0    @classmethod    def from_crawler(cls, crawler):        # first check if the extension should be enabled and raise        # NotConfigured otherwise        if not crawler.settings.getbool(‘MYEXT_ENABLED‘):            raise NotConfigured                # 配置僅僅支援RedisSpider        if not ‘redis_key‘ in crawler.spidercls.__dict__.keys():            raise NotConfigured(‘Only supports RedisSpider‘)        # get the number of items from settings        idle_number = crawler.settings.getint(‘IDLE_NUMBER‘, 360)        # instantiate the extension object        ext = cls(idle_number, crawler)        # connect the extension object to signals        crawler.signals.connect(ext.spider_opened, signal=signals.spider_opened)        crawler.signals.connect(ext.spider_closed, signal=signals.spider_closed)        crawler.signals.connect(ext.spider_idle, signal=signals.spider_idle)        # return the extension object        return ext    def spider_opened(self, spider):        logger.info("opened spider %s redis spider Idle, Continuous idle limit: %d", spider.name, self.idle_number)    def spider_closed(self, spider):        logger.info("closed spider %s, idle count %d , Continuous idle count %d",                    spider.name, self.idle_count, len(self.idle_list))    def spider_idle(self, spider):        self.idle_count += 1        self.idle_list.append(time.time())        idle_list_len = len(self.idle_list)               # 判斷 redis 中是否存在關鍵key, 如果key 被用完,則key就會不存在        if idle_list_len > 2 and spider.server.exists(spider.redis_key):            self.idle_list = [self.idle_list[-1]]        elif idle_list_len > self.idle_number:            logger.info(‘\n continued idle number exceed {} Times‘                        ‘\n meet the idle shutdown conditions, will close the reptile operation‘                        ‘\n idle start time: {},  close spider time: {}‘.format(self.idle_number,                                                                              self.idle_list[0], self.idle_list[0]))            # 執行關閉爬蟲操作            self.crawler.engine.close_spider(spider, ‘closespider_pagecount‘)

  

在settings.py 中添加以下配置, 請將 lianjia_ershoufang 替換為你的項目目錄名。

MYEXT_ENABLED=True      # 開啟擴充IDLE_NUMBER=360           # 配置空閑期間單位為 360個 ,一個時間單位為5s# 在 EXTENSIONS 配置,啟用擴充‘EXTENSIONS‘= {            ‘lianjia_ershoufang.extensions.RedisSpiderSmartIdleClosedExensions‘: 500,        },MYEXT_ENABLED: 是否啟用擴充,啟用擴充為 True, 不啟用為 FalseIDLE_NUMBER: 關閉爬蟲的持續空閑次數,持續空閑次數超過IDLE_NUMBER,爬蟲會被關閉。預設為 360 ,也就是30分鐘,一分鐘12個時間單位

 

Scrapy-Redis 空跑問題,redis_key連結跑完後,自動關閉爬蟲

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.