请求失败时 errback 拿到的 Failure 里到底是什么?不同故障对应哪个异常类?怎么在 errback 里判断类型?errback 的返回值又会被怎么处理?这篇用 11 种故障逐个造出来。
服务器返回 500 scrapy.spidermiddlewares.httperror.HttpError 带 response Ignoring non-200 response
服务器返回 404 scrapy.spidermiddlewares.httperror.HttpError 带 response Ignoring non-200 response
连接被拒(127.0.0.1:1) scrapy.exceptions.DownloadConnectionRefusedError无 response Connection was refused by other side: 61: Connection refused.
DNS 解析失败(.invalid) scrapy.exceptions.CannotResolveHostError 无 response DNS lookup failed: no results for hostname lookup: no-such-host.invalid.
读取超时(服务器睡 2 s,超时 1 s) scrapy.exceptions.DownloadTimeoutError 无 response Getting http://127.0.0.1:9964/x took longer than 1.0 seconds.
收到请求后直接关闭连接 scrapy.exceptions.DownloadFailedError 无 response [<twisted.python.failure.Failure twisted.internet.error.ConnectionDone: Connection was clo
声明 Content-Length: 100 只发 15 字节就关闭 scrapy.exceptions.ResponseDataLossError 无 response (空消息)
分块编码的块大小不是十六进制 scrapy.exceptions.ResponseDataLossError 无 response (空消息)
回的根本不是 HTTP scrapy.exceptions.DownloadFailedError 无 response [<twisted.python.failure.Failure twisted.web._newclient.ParseError: ('non-integer status c
正文 5000 字节,DOWNLOAD_MAXSIZE=1000 scrapy.exceptions.DownloadCancelledError 无 response Expected to receive 5000 bytes which is larger than download max size (1000) in request <G
https 请求打到明文 http 端口 scrapy.exceptions.DownloadFailedError 无 response [<twisted.python.failure.Failure OpenSSL.SSL.Error: [('SSL routines', '', 'wrong version n
URL 缺少协议(Request("bar")):构造时就抛 ValueError: Missing scheme in request url: bar状态码错误是 HttpError(带 response);网络层有专门的连接被拒、DNS、超时类;数据截断、超限也各有一个;其它底层问题统一包成 DownloadFailedError,原始异常在消息和 __cause__ 里。
500 check(HttpError)=True;check(DownloadConnectionRefusedError)=False;check(两者)→HttpError;failure.value.response.status=500
getErrorMessage()='Ignoring non-200 response';getTraceback() 共 8 行,最后一行 'scrapy.spidermiddlewares.httperror.HttpError: Ignoring non-200 response';value.__cause__ 的类型 NoneType
x check(HttpError)=False;check(DownloadConnectionRefusedError)=True;check(两者)→DownloadConnectionRefusedError;failure.value.response.status=None
getErrorMessage()='Connection was refused by other side: 61: Connection refused';getTraceback() 共 38 行,最后一行 'scrapy.exceptions.DownloadConnectionRefusedError: Connection was refused by othe';value.__cause__ 的类型 ConnectionRefusedErrorfailure.check(*classes) 返回命中的类用来分支,failure.request 是出错的请求,failure.value.response 只有 HttpError 才有。
return None(什么都不做) 事件 [];ERROR 日志 [];stats downloader/exception_count=1, spider_exceptions=0
yield 一个 item 事件 [{'who': 'item', 'item': {'failed': 'http://127.0.0.1:1/x'}}];ERROR 日志 [];stats downloader/exception_count=1, spider_exceptions=0
返回一个新 Request(换个地址) 事件 [{'who': 'retry callback', 'url': 'http://127.0.0.1:9969/ok'}];ERROR 日志 [];stats downloader/exception_count=1, spider_exceptions=0
不定义 errback 事件 [];ERROR 日志 ['ERROR: Error downloading <GET http://127.0.0.1:1/x>'];stats downloader/exception_count=1, spider_exceptions=0
errback 自己抛异常 事件 [];ERROR 日志 ['ERROR: Error downloading <GET http://127.0.0.1:1/x>'];stats downloader/exception_count=1, spider_exceptions=1errback 的返回值按回调规则处理:item 进 pipeline,Request 被调度,None 吞掉;没有 errback 或 errback 抛异常时 Scrapy 记 ERROR。