在请求错误回调中处理新项目



我想为每个Request添加一个errback函数,以捕获DNS查找失败、超时等。在捕捉到它们后,我想提交一个要在管道中处理的新项目,以记录(在数据库中(URL x失败并出现错误y。

我能想出两种理论上的方法来做这件事(但在实践中我都不知道怎么做(
1(以某种方式修补爬网程序引擎,并将一个新项目添加到项目处理队列中
2(手动调用各自的管道(公平地说,我只需要调用一个(,但访问它们可能会像选项1一样,不知何故,需要修补到引擎,然后黑客找到管道。。。

有什么建议吗?

想出了一种的方法,不确定这是最好还是最坏的方法。

我的所有请求都会收到文档中建议的errback回调。errback是这样的:

def process_failed_request(self, failure):
status = 'Unknown problem'
if failure.check(HttpError) or failure.check(IgnoreRequest):
return
elif failure.check(twisted_errors.DNSLookupError):
status = 'Server not found'
elif failure.check(TimeoutError, twisted_errors.TCPTimedOutError):
status = '408'
elif failure.check(twisted_errors.SSLError):
status = 'SSL error'
elif failure.check(twisted_errors.ConnectError):
status = 'Connection error'
item = {
'visited_page': LightRequest(None, url=failure.request.url, status_code=status),
}
# Force scrapy to process the failed item as it was a normal item
self.crawler.engine.scraper.slot.itemproc_size += 1
dfd = self.crawler.engine.scraper.itemproc.process_item(item, self)
dfd.addBoth(self.crawler.engine.scraper._itemproc_finished, item, None, self)

不要在意上半部分发生了什么,但三条底线才是魔法。第一行增加项目处理队列计数器以正确限制CONCURRENT_ITEMS。第二行调用处理,第三行添加Scrapy为每个处理的项目添加的回调。None参数是实际上也可以放入的response值,至少对于某些错误是这样。你可以从failure.value.response访问它,但我现在不在乎。

哦,如果不清楚的话,那么self当然就是Spider

PS!由于这在很大程度上依赖于报废的发动机,所以我使用的版本是1.5.1。

您可以创建下载中间件并实现process_exception方法。

您有权访问请求对象,因此可以将详细信息写入数据库,然后返回新的请求。

最新更新