当前位置: 首页 > article >正文

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

目录

在使用scrapy-redis这个库的时候,会出现以下的情况:
在这里插入图片描述
很烦,没说会一直监听啊,烦死了=。=,当时设置了一个拓展件RedisSpiderIdleTimeoutExtension,这个拓展件就是用来自动结束的。分布式部署的时候,这个是用不到的!!!

# 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文件里面添加配置:

#settings
EXTENSIONS = {
    "scrapy.extensions.telnet.TelnetConsole": None,
    'firstpc.middlewares.extensions.RedisSpiderIdleTimeoutExtension': 500,
}
# 设置空闲超时时间(5分钟 = 300秒)
REDIS_IDLE_TIMEOUT = 300
REDIS_IDLE_TIMEOUT_ENABLED = True

在这里插入图片描述


http://www.kler.cn/a/600976.html

相关文章:

  • Spring 源码硬核解析系列专题(三十二):Spring Cloud LoadBalancer 的负载均衡源码解析
  • 数据库的操作,以及sql之DML
  • Linux输入系统应用编程
  • 字符串常量,数组和指针的不同形式
  • uv:Rust 驱动的 Python 包管理新时代
  • 飞书只有阅读权限的文档下载,飞书文档下载没有权限的文件
  • Qt 线程类
  • 详解c++20的协程,自定义可等待对象,生成器详解
  • <tauri><rust><GUI>基于rust和tauri,实现多窗口与窗口间通信
  • ISIS-2 邻居建立关系
  • Python 编程中函数嵌套的相关解析
  • React 中React.memo的作用,如何利用它进行组件性能优化?
  • 单片机中C++的局部static变量的初始化仍然遵循控制流
  • Python爬虫异常处理:自动跳过无效URL
  • 2021年蓝桥杯第十二届CC++大学B组真题及代码
  • Redisson 实现分布式锁简单解析
  • OpenCV的Python开发环境搭建(Windows)
  • 目标和力扣--494
  • Readis自动化部署
  • ReentranLock手写