【发布时间】:2016-12-31 00:13:22
【问题描述】:
我正在尝试废弃一系列网页,但出现漏洞,有时看起来网站无法正确发送 html 响应。这会导致 csv 输出文件有空行。当响应上的 xpath 选择器为空时,如何重试 n 次请求和解析?请注意,我没有任何 HTTP 错误。
【问题讨论】:
标签: scrapy
我正在尝试废弃一系列网页,但出现漏洞,有时看起来网站无法正确发送 html 响应。这会导致 csv 输出文件有空行。当响应上的 xpath 选择器为空时,如何重试 n 次请求和解析?请注意,我没有任何 HTTP 错误。
【问题讨论】:
标签: scrapy
您可以使用自定义重试中间件来执行此操作,您只需覆盖当前 Retry Middleware 的 process_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我的蜘蛛的名字第三个论点?谢谢
if len(response.xpath(spider.retry_xpath))==0 替换了if response.status == 200 and response.xpath(spider.retry_xpath),你为什么不这样做?
您可以将settings.py 中的RETRY_TIMES 设置设置为您希望重试页面的次数。默认为 2 次。
【讨论】:
RETRY_ENABLED = False 设置禁用重试中间件,请参阅doc.scrapy.org/en/latest/topics/…