如何配置Scrapy爬虫在断网/断电时无限重试当前请求?
解决Scrapy断网/断电后无限重试当前请求的配置方案
一、全局重试参数配置(针对ISP断网场景)
在项目的settings.py中修改以下参数,让Scrapy对连接类错误无限重试,并固定10秒间隔:
# 启用重试中间件 RETRY_ENABLED = True # 指定需要触发重试的连接异常类型(匹配你遇到的"unreachable host"错误) RETRY_EXCEPTIONS = ( ConnectionRefusedError, ConnectionResetError, OSError, socket.error, ) # 设置最大重试次数为0(表示无上限,无限重试) RETRY_TIMES = 0 # 固定重试间隔为10秒 RETRY_DELAY = 10 # 禁用指数退避机制(避免重试间隔越来越长) RETRY_BACKOFF = False
二、自定义中间件确保优先重试当前请求
默认RetryMiddleware会把重试请求放回队列尾部,可能被其他请求插队。要确保断网时优先重试当前失败的URL,需要自定义中间件:
在项目的middlewares.py中添加以下代码:
from scrapy.downloadermiddlewares.retry import RetryMiddleware class InfiniteRetryMiddleware(RetryMiddleware): def process_exception(self, request, exception, spider): # 仅处理指定的连接异常 if isinstance(exception, tuple(self.EXCEPTIONS_TO_RETRY)): retry_times = request.meta.get('retry_times', 0) + 1 request.meta['retry_times'] = retry_times # 复制请求并标记为不重复过滤 retry_request = request.copy() retry_request.dont_filter = True # 将重试请求插入队列头部,确保优先处理 spider.crawler.engine.schedule(retry_request, spider, priority=100) return None return super().process_exception(request, exception, spider)
然后在settings.py中替换默认的重试中间件:
DOWNLOADER_MIDDLEWARES = { 'scrapy.downloadermiddlewares.retry.RetryMiddleware': None, '你的项目名.middlewares.InfiniteRetryMiddleware': 550, }
三、断电恢复的持久化配置
要解决断电后恢复任务的问题,需要启用Scrapy的持久化调度功能,让未完成的请求保存到磁盘:
# 开启调度器持久化 SCHEDULER_PERSIST = True # 使用FIFO磁盘队列保证请求顺序 SCHEDULER_DISK_QUEUE = 'scrapy.squeues.PickleFifoDiskQueue'
效果验证
- ISP断网时,Scrapy会每隔10秒重试当前失败的URL,不会切换到其他请求;
- 断电重启爬虫后,会自动加载磁盘中保存的未完成请求,从断点处继续处理。
内容的提问来源于stack exchange,提问作者asfand hikmat
相关产品推荐
相关产品推荐

