为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

慕盖茨4494581 2021-08-24 15:08:33
我想为errback每个添加一个函数来Request捕获 DNS 查找失败、超时等。捕获它们后,我想提交一个要在管道中处理的新项目,以记录(在数据库中)URL x 因错误 y 而失败。我可以想到两种理论上的方法来做到这一点(但实际上我也不知道该怎么做)。1) 以某种方式修补爬虫引擎并向项目处理队列添加一个新项目。2)手动调用相应的管道(为了公平起见,我只需要调用一个),但是访问它们可能类似于选项 1,不知何故需要修补引擎,然后笨拙地找到管道......有什么建议吗?
查看完整描述

2 回答

?
慕森王

TA贡献1777条经验 获得超3个赞

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


我的所有请求都会收到文档中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当然的。


附注!由于这非常依赖于scrapy引擎,所以我使用的版本是1.5.1。


查看完整回答
反对 回复 2021-08-24
?
holdtom

TA贡献1805条经验 获得超10个赞

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

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


查看完整回答
反对 回复 2021-08-24
  • 2 回答
  • 0 关注
  • 160 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号