我目前正在研究一个刮板项目,这对于确保每个请求都得到正确处理非常重要,即记录错误或保存成功的结果。我已经实现了基本的爬虫,现在我可以成功处理 99% 的请求,但我可能会收到验证码、50x、30x 之类的错误,甚至结果中没有足够的字段(然后我会尝试另一个网站找到缺失的字段)。
起初,我认为在解析回调中引发异常并在 errback 中处理它们更“合乎逻辑”,这可以使代码更具可读性。但是我尝试了只是发现errback只能捕获下载器模块中的错误,例如非200响应状态。如果我在回调中引发一个自我实现的 ParseError,蜘蛛只会引发它并停止。
即使我必须直接在回调中处理解析请求,我也不知道如何在回调中以干净的方式立即重试请求。你知道,我可能必须包含一个不同的代理来发送另一个请求,或者修改一些请求标头。
我承认我对scrapy比较陌生,但我已经来回尝试了好几天,仍然无法让它发挥作用……我已经检查了关于SO的每一个问题,但没有人匹配,在此先感谢您的帮助。
更新:我意识到这可能是一个非常复杂的问题,所以我尝试在下面的伪代码中说明场景,希望这会有所帮助:
from scraper.myexceptions import *
def parseRound1(self, response):
.... some parsing routines ...
if something wrong happened:
# this causes the spider raises a SpiderException and stops
raise CaptchaError
...
if no enough fields scraped:
raise ParseError(task, "no enough fields")
else:
return items
def parseRound2(self, response):
...some other parsing routines...
def errHandler(self, failure):
# how to trap all the exceptions?
r = failure.trap()
# cannot trap ParseError here
if r == CaptchaError:
# how to enqueue the original request here?
retry
elif r == ParseError:
if raised from parseRound1:
new request for Round2
else:
some other retry mechanism
elif r == HTTPError:
ignore or retry