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
相关推荐
蓝帆傲亦2 小时前
代码革命!我用Claude Code 3个月完成1年工作量,这些实战经验全给你
jvm·数据库·oracle
亓才孓2 小时前
[JDBC]事务
java·开发语言·数据库
PD我是你的真爱粉2 小时前
FastAPI使用tortoiseORM
数据库·fastapi
剩下了什么9 小时前
MySQL JSON_SET() 函数
数据库·mysql·json
山峰哥10 小时前
数据库工程与SQL调优——从索引策略到查询优化的深度实践
数据库·sql·性能优化·编辑器
较劲男子汉10 小时前
CANN Runtime零拷贝传输技术源码实战 彻底打通Host与Device的数据传输壁垒
运维·服务器·数据库·cann
java搬砖工-苤-初心不变10 小时前
MySQL 主从复制配置完全指南:从原理到实践
数据库·mysql
山岚的运维笔记12 小时前
SQL Server笔记 -- 第18章:Views
数据库·笔记·sql·microsoft·sqlserver
roman_日积跬步-终至千里13 小时前
【LangGraph4j】LangGraph4j 核心概念与图编排原理
java·服务器·数据库
汇智信科13 小时前
打破信息孤岛,重构企业效率:汇智信科企业信息系统一体化运营平台
数据库·重构