scrapy的errback

在scrapy我们可以设置一些参数,如DOWNLOAD_TIMEOUT,一般我会设置为10,意思是请求下载时间最大是10秒,文档介绍

如果下载超时会抛出一个错误,比如说

    def start_requests(self):
        yield scrapy.Request('https://www.baidu.com/', meta={'download_timeout': 0.1})

日志设为DEBUG级别,重试设为3次,运行之后的日志

2019-05-23 19:38:01 [scrapy.downloadermiddlewares.retry] DEBUG: Retrying <GET https://www.baidu.com/> (failed 1 times): User timeout caused connection failure: Getting https://www.baidu.com/ took longer than 0.1 seconds..
2019-05-23 19:38:01 [scrapy.downloadermiddlewares.retry] DEBUG: Retrying <GET https://www.baidu.com/> (failed 2 times): User timeout caused connection failure: Getting https://www.baidu.com/ took longer than 0.1 seconds..
2019-05-23 19:38:01 [scrapy.downloadermiddlewares.retry] DEBUG: Retrying <GET https://www.baidu.com/> (failed 3 times): User timeout caused connection failure: Getting https://www.baidu.com/ took longer than 0.1 seconds..
2019-05-23 19:38:01 [scrapy.downloadermiddlewares.retry] DEBUG: Gave up retrying <GET https://www.baidu.com/> (failed 4 times): User timeout caused connection failure.
2019-05-23 19:38:01 [scrapy.core.scraper] ERROR: Error downloading <GET https://www.baidu.com/>
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/scrapy/core/downloader/middleware.py", line 43, in process_request
    defer.returnValue((yield download_func(request=request,spider=spider)))
twisted.internet.error.TimeoutError: User timeout caused connection failure.可以看到重试三次之后,抛出异常。今天讲的就是如何处理这个异常,也就是scrapy的errback。

重新改写下代码

    def start_requests(self):
        yield scrapy.Request('https://www.baidu.com/', meta={'download_timeout': 0.1},
                             errback=self.errback, callback=self.parse)

    def errback(self, failure):
        self.logger.error(repr(failure))

使用errback必须要有callback函数,日志输出

2019-05-23 19:46:20 [51bushou_shop] ERROR: <twisted.python.failure.Failure twisted.internet.error.TimeoutError: User timeout caused connection failure: Getting https://www.baidu.com/ took longer than 0.1 seconds..>

官方的例子

import scrapy

from scrapy.spidermiddlewares.httperror import HttpError
from twisted.internet.error import DNSLookupError
from twisted.internet.error import TimeoutError, TCPTimedOutError

class ErrbackSpider(scrapy.Spider):
    name = "errback_example"
    start_urls = [
        "http://www.httpbin.org/",              # HTTP 200 expected
        "http://www.httpbin.org/status/404",    # Not found error
        "http://www.httpbin.org/status/500",    # server issue
        "http://www.httpbin.org:12345/",        # non-responding host, timeout expected
        "http://www.httphttpbinbin.org/",       # DNS error expected
    ]

    def start_requests(self):
        for u in self.start_urls:
            yield scrapy.Request(u, callback=self.parse_httpbin,
                                    errback=self.errback_httpbin,
                                    dont_filter=True)

    def parse_httpbin(self, response):
        self.logger.info('Got successful response from {}'.format(response.url))
        # do something useful here...

    def errback_httpbin(self, failure):
        # log all failures
        self.logger.error(repr(failure))

        # in case you want to do something special for some errors,
        # you may need the failure's type:

        if failure.check(HttpError):
            # these exceptions come from HttpError spider middleware
            # you can get the non-200 response
            response = failure.value.response
            self.logger.error('HttpError on %s', response.url)

        elif failure.check(DNSLookupError):
            # this is the original request
            request = failure.request
            self.logger.error('DNSLookupError on %s', request.url)

        elif failure.check(TimeoutError, TCPTimedOutError):
            request = failure.request
            self.logger.error('TimeoutError on %s', request.url)

failure.request就是我们创建的Request对象,如果需要重试,直接yield即可errback函数能捕获的scrapy错误有:连接建立超时,DNS错误等。也就是日志中类似

twisted.internet.error.TimeoutError: User timeout caused connection failure.

源代码位置:error.py

最后说一句,华为加油

本文分享自微信公众号 - Python爬虫与算法进阶(zhangslob),作者:小歪丶

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-05-23

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 反反爬虫系列(三)

    大概1年多前看过携程的一个产品经理叫什么崔广宇?写的一篇爬虫与反反爬的文章,当时觉得这个人好狂,当时对于携程的这个eleven我确实没办法,今儿就讲讲怎么去撸这...

    小歪
  • 学点算法之队列的学习及应用

    约瑟夫问题 约瑟夫问题 有 n 个囚犯站成一个圆圈,准备处决。首先从一个人开始,越过k-2个人(因为第一个人已经被越过),并杀掉第k个人。接着,再越过 k-1个...

    小歪
  • 强大的异步爬虫 with aiohttp

    看到现在网络上大多讲的都是requests、scrapy,却没有说到爬虫中的神器:aiohttp

    小歪
  • [WCF-Discovery]如何利用”发现代理”实现可用服务的实时维护?

    上面的内容大部分是围绕着Ad-Hoc模式展开介绍的。Managed模式和Ad-Hoc不同之处在于可用服务的终结点通过发现代理来统一管理。客户端在进行可用目标服务...

    蒋金楠
  • UI动画效果

    用户1941540
  • 华为oj之【中级】单词倒排

    3、要求倒排后的单词间隔符以一个空格表示;如果原字符串中相邻单词间有多个间隔符时,倒排转换后也只允许出现一个空格间隔符;

    Enjoy233
  • 【leetcode刷题】T56-重复的DNA序列

    所有 DNA 由一系列缩写为 A,C,G 和 T 的核苷酸组成,例如:“ACGAATTCCG”。在研究 DNA 时,识别 DNA 中的重复序列有时会对研究非常有...

    木又AI帮
  • 不要插件!轻松整合WordPress与CDN加速服务

    FHYC
  • 图同构在P/NP问题上重大突破,计算机理论10年最重要成果

    芝加哥科学家 László Babai 发明了一种方法,能够用多项式的时间判断两个网络是否相同。 麻省理工学院的计算机科学家 Scott Aaronson...

    新智元
  • Vue.js - 组件快速入门(上)

    组件系统是Vue.js其中一个重要的概念,它提供了一种抽象,让我们可以使用独立可复用的小组件来构建大型应用,任意类型的应用界面都可以抽象为一个组件树:

    Vincent-yuan

扫码关注云+社区

领取腾讯云代金券