Scrapy——Redis空闲超时关闭扩展

目录

在使用scrapy-redis这个库的时候,会出现以下的情况:

很烦,没说会一直监听啊,烦死了=。=,当时设置了一个拓展件RedisSpiderIdleTimeoutExtension,这个拓展件就是用来自动结束的。分布式部署的时候,这个是用不到的!!!

python 复制代码
# extension.py
import time
from scrapy import signals
from scrapy.exceptions import NotConfigured

class RedisSpiderIdleTimeoutExtension:
    """
    Scrapy-Redis 空闲超时关闭扩展
    - 如果在指定时间内无新任务,自动关闭爬虫
    - 兼容分布式环境,避免空跑
    """
    def __init__(self, timeout, crawler):
        self.crawler = crawler
        self.timeout = timeout          # 超时时间(秒)
        self.last_activity_time = None # 最后活动时间戳

    @classmethod
    def from_crawler(cls, crawler):
        # 检查扩展是否启用
        if not crawler.settings.getbool('REDIS_IDLE_TIMEOUT_ENABLED', True):
            raise NotConfigured

        # 从配置读取超时时间(默认5分钟)
        timeout = crawler.settings.getint('REDIS_IDLE_TIMEOUT', 300)

        ext = cls(timeout, crawler)

        # 连接信号:任务开始、处理成功、空闲
        crawler.signals.connect(ext.spider_opened, signal=signals.spider_opened)
        crawler.signals.connect(ext.request_scheduled, signal=signals.request_scheduled)
        crawler.signals.connect(ext.item_scraped, signal=signals.item_scraped)
        crawler.signals.connect(ext.spider_idle, signal=signals.spider_idle)

        return ext

    def spider_opened(self, spider):
        """爬虫启动时初始化最后活动时间"""
        self.last_activity_time = time.time()
        spider.logger.info(f"启用空闲超时关闭,超时时间: {self.timeout}秒")

    def request_scheduled(self, request, spider):
        """有新请求时更新活动时间"""
        self._update_activity()

    def item_scraped(self, item, spider):
        """处理到Item时更新活动时间"""
        self._update_activity()

    def _update_activity(self):
        """更新最后活动时间"""
        self.last_activity_time = time.time()

    def spider_idle(self, spider):
        """空闲时检查超时"""
        if self.last_activity_time is None:
            return  # 初始状态无需处理

        current_time = time.time()
        idle_duration = current_time - self.last_activity_time

        if idle_duration > self.timeout:
            spider.logger.info(f"空闲超过 {self.timeout} 秒,触发关闭爬虫")
            self.crawler.engine.close_spider(spider, 'idle_timeout')
        else:
            spider.logger.debug(f"当前空闲时间: {idle_duration:.1f}秒 (超时阈值: {self.timeout}秒)")

当然也要在settings.py文件里面添加配置:

python 复制代码
#settings
EXTENSIONS = {
    "scrapy.extensions.telnet.TelnetConsole": None,
    'firstpc.middlewares.extensions.RedisSpiderIdleTimeoutExtension': 500,
}
# 设置空闲超时时间(5分钟 = 300秒)
REDIS_IDLE_TIMEOUT = 300
REDIS_IDLE_TIMEOUT_ENABLED = True
相关推荐
胡斌附体3 分钟前
mobaxterm终端sqlplus乱码问题解决
数据库·乱码·sqlplus·字符集设置
moon66sun12 分钟前
开源项目XYZ.ESB:数据库到数据库(DB->DB)集成
数据库·esb
TDengine (老段)30 分钟前
使用 StatsD 向 TDengine 写入
java·大数据·数据库·时序数据库·iot·tdengine·涛思数据
DarkAthena36 分钟前
【GaussDB】深度解析:创建存储过程卡死且无法Kill会话的疑难排查
数据库·gaussdb
Gauss松鼠会42 分钟前
GaussDB权限管理:从RBAC到精细化控制的企业级安全实践
大数据·数据库·安全·database·gaussdb
时序数据说1 小时前
时序数据库IoTDB用户自定义函数(UDF)使用指南
大数据·数据库·物联网·开源·时序数据库·iotdb
Java初学者小白2 小时前
秋招Day15 - Redis - 缓存设计
java·数据库·redis·缓存
绅士玖2 小时前
前端数据存储总结:Cookie、localStorage、sessionStorage与IndexedDB的使用与区别
前端·javascript·数据库
倔强的石头1063 小时前
飞算JavaAI:重构软件开发范式的智能引擎
java·数据库·重构
Q_970956393 小时前
java+vue+SpringBoo足球社区管理系统(程序+数据库+报告+部署教程+答辩指导)
java·开发语言·数据库