【问题标题】:How to retry the request n times when an item gets an empty field?当项目获得空字段时如何重试请求n次?
【发布时间】:2016-12-31 00:13:22
【问题描述】:

我正在尝试废弃一系列网页,但出现漏洞,有时看起来网站无法正确发送 html 响应。这会导致 csv 输出文件有空行。当响应上的 xpath 选择器为空时,如何重试 n 次请求和解析?请注意,我没有任何 HTTP 错误。

【问题讨论】:

    标签: scrapy


    【解决方案1】:

    您可以使用自定义重试中间件来执行此操作,您只需覆盖当前 Retry Middlewareprocess_response 方法:

    from scrapy.downloadermiddlewares.retry import RetryMiddleware
    from scrapy.utils.response import response_status_message
    
    
    class CustomRetryMiddleware(RetryMiddleware):
    
        def process_response(self, request, response, spider):
            if request.meta.get('dont_retry', False):
                return response
            if response.status in self.retry_http_codes:
                reason = response_status_message(response.status)
                return self._retry(request, reason, spider) or response
    
            # this is your check
            if response.status == 200 and response.xpath(spider.retry_xpath):
                return self._retry(request, 'response got xpath "{}"'.format(spider.retry_xpath), spider) or response
            return response
    

    然后启用它而不是settings.py中默认的RetryMiddleware

    DOWNLOADER_MIDDLEWARES = {
        'scrapy.downloadermiddlewares.retry.RetryMiddleware': None,
        'myproject.middlewarefilepath.CustomRetryMiddleware': 550,
    }
    

    现在您有了一个中间件,您可以在其中配置 xpath 以使用属性 retry_xpath 在您的蜘蛛中重试:

    class MySpider(Spider):
        name = "myspidername"
    
        retry_xpath = '//h2[@class="tadasdop-cat"]'
        ...
    

    当您的 Item 字段为空时,这不一定会重试,但您可以在此 retry_xpath 属性中指定该字段的相同路径以使其工作。

    【讨论】:

    • 你能给我解释一下self._retry是什么,检查xpath是否为空的测试在哪里以及为什么我不必给process_response我的蜘蛛的名字第三个论点?谢谢
    • 查看如何创建自己的downloader middleware。关于 _retry 和其他类方法,请记住我们是从 RetryMiddleware 继承的,所以我们只是覆盖它的方法(答案中的链接)。关于spider参数,就是当前的spider实例,不需要名字。
    • 好的,谢谢。顺便说一句,我用if len(response.xpath(spider.retry_xpath))==0 替换了if response.status == 200 and response.xpath(spider.retry_xpath),你为什么不这样做?
    【解决方案2】:

    您可以将settings.py 中的RETRY_TIMES 设置设置为您希望重试页面的次数。默认为 2 次。

    more on RetryMiddleware

    【讨论】:

    • 奇怪的是,如果RETRY_TIMES设置为0,它仍然会重试一次。我一直尝试将其设置为 1,但它会重试两次。
    • @chainstair 您可以尝试使用RETRY_ENABLED = False 设置禁用重试中间件,请参阅doc.scrapy.org/en/latest/topics/…
    • 我试过这个,但是我遇到了一个问题,它甚至没有重试一次。奇怪...
    猜你喜欢
    • 2020-12-14
    • 1970-01-01
    • 2023-03-14
    • 2020-08-09
    • 2017-08-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-26
    相关资源
    最近更新 更多