Scrapy_关闭爬虫

配置版

CLOSESPIDER_TIMEOUT
默认值: 0
 
一个整数值,单位为秒。如果一个spider在指定的秒数后仍在运行, 它将以 closespider_timeout 的原因
被自动关闭。 如果值设置为0(或者没有设置),spiders不会因为超时而关闭。



CLOSESPIDER_ITEMCOUNT
缺省值: 0
 
一个整数值,指定条目的个数。如果spider爬取条目数超过了指定的数, 并且这些条目通过item pipeline传递,
spider将会以 closespider_itemcount 的原因被自动关闭。



CLOSESPIDER_PAGECOUNT
缺省值: 0
 
一个整数值,指定最大的抓取响应(reponses)数。 如果spider抓取数超过指定的值,则会以 closespider_pagecount 
的原因自动关闭。 如果设置为0(或者未设置),spiders不会因为抓取的响应数而关闭。



CLOSESPIDER_ERRORCOUNT
缺省值: 0

一个整数值,指定spider可以接受的最大错误数。 如果spider生成多于该数目的错误,它将以 closespider_errorcount 的原因关闭。 
如果设置为0(或者未设置),spiders不会因为发生错误过多而关闭。



对象版

spider:

self.crawler.engine.close_spider(self, 'response msg error %s, job done!' % response.text)

pipeline与Middlewares:

spider.crawler.engine.close_spider(spider, 'yestoday: %s news collection and completion' % self.YES_TODAY)

扩展(适合分布式)

extentions.py
import logging
import time
from scrapy import signals
from scrapy.exceptions import NotConfigured
logger = 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):
        # 首先检查是否应该启用和提高扩展
        # 否则不配置
        if not crawler.settings.getbool('MYEXT_ENABLED'):
            raise NotConfigured

        # 获取配置中的时间片个数,默认为360个,30分钟
        idle_number = crawler.settings.getint('IDLE_NUMBER', 12)

        # 实例化扩展对象
        ext = cls(idle_number, crawler)

        # 将扩展对象连接到信号, 将signals.spider_idle 与 spider_idle() 方法关联起来。
        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())       # 每次触发 spider_idle时,记录下触发时间戳
        idle_list_len = len(self.idle_list)         # 获取当前已经连续触发的次数
        print("---------------")
        print(idle_list_len)
        # 判断 当前触发时间与上次触发时间 之间的间隔是否大于20秒,如果大于20秒,说明有任务在跑。这里一定要是>6秒以上都可以,
#因为spider_idle是空闲5秒执行一次
        #idle_list_len > 2保证此集合长度至少为2
        #注意:这个判断一定要写,否则一直是连接超时
        if idle_list_len > 2 and self.idle_list[-1] - self.idle_list[-2] > 20:
            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

# Enable or disable extensions
# See https://doc.scrapy.org/en/latest/topics/extensions.html
MYEXT_ENABLED=True      # 开启扩展
MYEXT_ITEMCOUNT=12   #12个 一分钟,1个5s
EXTENSIONS = {
   'Scrapy_Hans.extensions.RedisSpiderSmartIdleClosedExensions': 500,
}

猜你喜欢

转载自blog.csdn.net/rookie_is_me/article/details/85262285