【问题标题】:How to get response body in scrapy downloader middleware如何在scrapy下载器中间件中获取响应体
【发布时间】:2017-11-21 05:12:58
【问题描述】:

如果在页面上找不到某些 xpath,我需要能够重试请求。所以我写了这个中间件:

class ManualRetryMiddleware(RetryMiddleware):
    def process_response(self, request, response, spider):
        if not spider.retry_if_not_found:
            return response
        if not hasattr(response, 'text') and response.status != 200:
            return super(ManualRetryMiddleware, self).process_response(request, response, spider)
        found = False
        for xpath in spider.retry_if_not_found:
            if response.xpath(xpath).extract():
                found = True
                break
        if not found:
            return self._retry(request, "Didn't find anything useful", spider)
        return response

并在settings.py注册:

DOWNLOADER_MIDDLEWARES = {
    'myproject.middlewares.ManualRetryMiddleware': 650,
    'scrapy.downloadermiddlewares.retry.RetryMiddleware': None,
}

当我运行蜘蛛时,我得到

AttributeError: 'Response' object has no attribute 'xpath'

我尝试手动创建选择器并在其上运行 xpath...但是响应没有 text 属性并且 response.body 是字节,而不是 str...

那么如何在中间件中查看页面内容呢?可能某些页面不包含我需要的详细信息,因此我希望稍后再试一次。

【问题讨论】:

    标签: python scrapy web-crawler scrapy-spider


    【解决方案1】:

    response不包含xpath方法的原因是下载器中间件process_response方法中的response参数是scrapy.http.Response类型,见documentation。只有scrapy.http.TextResponse(和scrapy.http.HtmlResponse)有xpath 方法。所以在使用xpath之前,从response创建HtmlResponse对象。您班级的相应部分将变为:

    ...
    new_response = scrapy.http.HtmlResponse(response.url, body=response.body)
    if new_response.xpath(xpath).extract():
        found = True
        break
    ...
    

    【讨论】:

    • new_response.text 现在有些乱码,specifyingscrapy.http.HtmlResponse(response.url, body=response.body, encoding="utf-8") 无济于事。
    • 检查@mouch 的答案。确保您没有使用压缩响应!
    【解决方案2】:

    还要注意您的中间件位置。它必须在scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware 之前,否则,您最终可能会尝试解码压缩数据(这确实不起作用)。检查 response.header 以了解响应是否被压缩 - Content-Encoding: gzip

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-01-06
      • 1970-01-01
      • 2023-03-14
      • 1970-01-01
      • 1970-01-01
      • 2019-06-03
      • 2020-03-23
      • 1970-01-01
      相关资源
      最近更新 更多