我想向每个errback
添加一个Request
函数,以捕获DNS查找失败,超时等问题。捕获它们后,我想提交一个新项目以在管道中进行处理,以记录(在数据库中)URL x失败并出现错误y。
我可以想到两种理论方法来做到这一点(但实际上我都不知道该怎么做)。
1)以某种方式修补到搜寻器引擎中,并将新项目添加到项目处理队列中。
2)手动调用相应的管道(公平地说,我只需要调用一个),但是访问它们可能会发生类似于选项1之类的事情,以某种方式需要修补引擎,然后黑手发现管道...
有什么建议吗?
答案 0 :(得分:1)
想出了一种方法,不确定是最好还是最坏方法。
我的所有请求均收到docs中建议的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!由于这很大程度上依赖于scrapy引擎,所以我使用的版本是1.5.1。
答案 1 :(得分:1)
您可以创建downloader middleware并实现process_exception
方法。
您有权访问请求对象,因此可以将详细信息写入数据库,然后返回新请求。