通过另一个代理重试 Scrapy GET 请求
使用 Scrapy 的重试辅助函数,在遵守重试预算的前提下,用新的代理安排一次新的请求。
修改 response.request.meta 只是改动了一个 Python 对象。要真正再下载一次,必须把另一个 Request 交给 Scrapy 去调度。
如果某个 GET 由回调明确决定重试,Scrapy 公开的重试辅助函数可以把重试计数带到新请求上:
from scrapy.downloadermiddlewares.retry import get_retry_request
def retry_through(self, response, proxy_url):
retry = get_retry_request(
response.request,
spider=self,
reason='choose_another_proxy',
)
if retry is None:
return None
retry.meta['proxy'] = proxy_url
retry.headers.pop('Proxy-Authorization', None)
return retry
这是一个 spider 辅助函数。调用方必须在拿到结果 Request 时将其返回或 yield。返回 None 表示在适用的上限内该辅助函数拒绝了再次重试。
重试辅助函数会复制该请求、更新其重试计数,并给出适合重试的调度器行为。若只是把同一 URL 当作普通新请求 yield,反而可能被去重过滤拦下。
请使用已启用的 HttpProxyMiddleware 所支持的代理 URL。对于允许的公开 GET 请求重试,HTTP 代理列表中未认证的 HTTP 候选即可提供 proxy_url。清除先前附加的 proxy-authorization 字段,可避免把旧中间人的请求头带进这次选择;在适用时让中间件根据新的代理 URL 推导出新的账号。
把这一 callback 层面的选择与 RetryMiddleware 对其配置故障的自动处理分开。明确由哪一层负责重试,避免一次操作消耗两套彼此独立的预算。该示例针对可重放的 GET 工作,并不承诺重复任意已提交事务是安全的。