bigywater.tech
Scrapy · 41

DropItem、IgnoreRequest、CloseSpider:异常在引擎里怎么处理

DropItem、IgnoreRequest、CloseSpider、NotConfigured……这些异常是 Scrapy 给你控制流程的开关,但“在哪里抛”决定它是否有效。这篇把它们放进回调、中间件、pipeline、信号处理函数里各抛一次,看引擎怎么处理。

回调 / start()
CloseSpider 真正能关掉爬虫的两个位置
3 处
IgnoreRequest 在下载器中间件两个钩子和爬虫中间件里,都是 errback 收到
Disabled
NotConfigured 带消息时的 WARNING 前缀

IgnoreRequest

实测 · 本机执行输出
  下载器中间件 process_request 抛 IgnoreRequest:errback (IgnoreRequest: mw says no);spider_exceptions=0;日志 ["'downloader/exception_type_count/scrapy.exceptions.IgnoreRequest': 1,"]
  下载器中间件 process_response 抛 IgnoreRequest:errback (IgnoreRequest: resp says no);spider_exceptions=0;日志 []
  爬虫中间件 process_spider_input 抛 IgnoreRequest:errback (IgnoreRequest: spider-mw says no);spider_exceptions=0;日志 []
  回调里抛 IgnoreRequest:回调/errback 都没有被调用;spider_exceptions=1;日志 ['ERROR: Spider error processing <GET http://127.0.0.1:9960/target> (referer: None)']

在中间件里抛表示“丢弃这个请求/响应”,errback 会收到它;在回调里抛没有这个含义,只是普通的回调异常。

CloseSpider

实测 · 本机执行输出
  回调里 raise CloseSpider("my_reason")(第 5 个页面):finish_reason=my_reason;服务器收到 7 个请求;item_scraped_count=0;日志里的第一条错误:(无)
  pipeline.process_item 里抛(第 5 个 item):finish_reason=finished;服务器收到 31 个请求;item_scraped_count=29;日志里的第一条错误:ERROR: Error processing {'u': 'http://127.0.0.1:9960/p25'}
  start() 里抛:finish_reason=start_reason;服务器收到 1 个请求;item_scraped_count=0;日志里的第一条错误:(无)
  下载器中间件 process_request 里抛(第 5 个请求):finish_reason=finished;服务器收到 30 个请求;item_scraped_count=0;日志里的第一条错误:ERROR: Error downloading <GET http://127.0.0.1:9960/p26>
  信号处理函数里抛(response_received 的第 5 次):finish_reason=finished;服务器收到 31 个请求;item_scraped_count=0;日志里的第一条错误:ERROR: Error caught on signal handler: <function S.from_crawler.<locals>.f at 0x

只有回调和 start() 里抛的 CloseSpider 才会按给定原因关闭爬虫;其它位置抛只会变成普通的错误日志,爬虫继续跑。

NotConfigured

实测 · 本机执行输出
  日志里的 Disabled 行:WARNING: Disabled <class 'spider.LoudExt'>: missing LOUD_SETTING | WARNING: Disabled <class 'spider.DM'>: no config for DM | WARNING: Disabled <class 'spider.P'>: pipeline off
  爬虫照常跑完:finish_reason=finished;item_scraped_count=1
  [scrapy.middleware] INFO: Enabled item pipelines:
  []

组件构造时抛出,Scrapy 就跳过它,爬虫继续;给了消息会打 WARNING。常用于“没配置就不启用”。

NotSupported

实测 · 本机执行输出
  foo://bar/x:[{'who': 'errback', 'exc': 'scrapy.exceptions.NotSupported', 'msg': "Unsupported URL scheme 'foo': no handler available for that scheme"}];retry/count=0;downloader/exception_count=1

没有对应下载处理器的协议会抛 NotSupported,走 errback,不重试。

分步演示

控制异常
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / Python 3.14.8 / Scrapy 2.19.0 / Twisted 26.4.0 / lxml 6.1.3 / parsel 1.12.1(临时虚拟环境);所有请求只发给本机自己起的测试服务器(127.0.0.1,端口 9960 以上,不访问任何真实网站);服务器可以按实验需要制造延迟、重定向、压缩、断连等行为,并记录收到的原始请求;每个实验在临时目录里新建 Scrapy 项目或单文件 spider,命令输出来自真实的 scrapy 进程;计时用 time.perf_counter,数字每次运行会有小幅抖动。站点 30 个页面,并发 1;异常实验里每种位置写一个最小的组件;日志级别 DEBUG;被异常打断后“服务器收到几个请求”受关闭的异步延迟影响
    • 没有验证:DropItem 在回调里抛(当作普通异常,未测);StopDownload(见信号那一篇);DontCloseSpider(见引擎那一篇);UsageError、ScrapyDeprecationWarning 等命令行与弃用类异常;CloseSpider 在爬虫中间件里抛的行为;NotConfigured 在下载处理器里的行为
    京ICP备2026067502号-1京公网安备11010502063487号