有一个我正在抓取的网站,有时会返回200,但在response.body中没有任何文本(当我尝试用Selector解析时会引发一个AttributeError。)
是否有一种简单的方法可以检查以确保正文包含文本,如果没有,请重试请求直到它为止?这是一些伪代码,用于概述我正在尝试做的事情。
def check_response(response):
if response.body != '':
return response
else:
return Request(copy_of_response.request,
callback=check_response)
基本上,有没有办法可以使用完全相同的属性(方法,网址,有效负载,Cookie等)重复请求?
答案 0 :(得分:8)
比获得许可更容易请求宽恕。这个常见的Python 编码风格假定存在有效的键或属性 如果假设被证明是假的,则捕获异常。这干净又快 风格的特点是存在许多尝试和除外 声明。该技术与许多人共同的LBYL风格形成鲜明对比 其他语言,如C.
处理异常,并使用dont_filter=True
向当前网址提供Request
:
dont_filter(boolean) - 表示此请求不应该是 由调度程序过滤。当您想要执行时使用此选项 多次相同的请求,忽略重复过滤器。使用 它小心翼翼,否则你会陷入爬行循环。默认为False。
def parse(response):
try:
# parsing logic here
except AttributeError:
yield Request(response.url, callback=self.parse, dont_filter=True)
您还可以make a copy当前请求(未经测试):
new_request = response.request.copy()
new_request.dont_filter = True
yield new_request
或者,使用replace()
:
new_request = response.request.replace(dont_filter=True)
yield new_request
答案 1 :(得分:4)
如何从重试中间件调用实际的_rety()
方法,所以它是一个正常的重试,它的所有逻辑都考虑了设置?
在设置中:
DOWNLOADER_MIDDLEWARES = {
'scrapy.downloadermiddlewares.retry.RetryMiddleware': None,
'scraper.middlewares.retry.RetryMiddleware': 550,
}
然后你的重试中间件可能就像:
from scrapy.downloadermiddlewares.retry import RetryMiddleware \
as BaseRetryMiddleware
class RetryMiddleware(BaseRetryMiddleware):
def process_response(self, request, response, spider):
# inject retry method so request could be retried by some conditions
# from spider itself even on 200 responses
if not hasattr(spider, '_retry'):
spider._retry = self._retry
return super(RetryMiddleware, self).process_response(request, response, spider)
然后在您的成功回复回调中,您可以致电前:。
yield self._retry(response.request, ValueError, self)