Scrapy如何为所有请求仅重试指定代理一次后切换代理?
Scrapy代理重试逻辑自定义方案
你的核心问题是原中间件仅在retry_times == 1时切换代理池,但当重试次数超过1后,又会默认使用packetstream_proxies,导致该代理池被反复调用,不符合预期逻辑。
修正后的代理中间件代码
import random from scrapy.utils.conf import get_settings class SdtProxyMiddleware(object): def __init__(self): settings = get_settings() # 初始化packetstream代理池并过滤空配置 self.packetstream_proxies = [ settings.get("PS_PROXY_USA"), settings.get("PS_PROXY_CA"), settings.get("PS_PROXY_IT"), settings.get("PS_PROXY_GLOBAL"), ] self.packetstream_proxies = [proxy for proxy in self.packetstream_proxies if proxy] # 初始化unlimited代理池并过滤空配置 self.unlimited_proxies = [ settings.get("UNLIMITED_PROXY_1"), settings.get("UNLIMITED_PROXY_2"), settings.get("UNLIMITED_PROXY_3"), settings.get("UNLIMITED_PROXY_4"), settings.get("UNLIMITED_PROXY_5"), settings.get("UNLIMITED_PROXY_6"), ] self.unlimited_proxies = [proxy for proxy in self.unlimited_proxies if proxy] def process_request(self, request, spider): # 获取当前重试次数,初始请求默认值为0 retry_times = request.meta.get("retry_times", 0) # 初始请求+第一次重试,固定使用packetstream代理池 if retry_times <= 1: if self.packetstream_proxies: request.meta["proxy"] = random.choice(self.packetstream_proxies) # 第二次及以后的重试,全部切换为unlimited代理池 else: if self.unlimited_proxies: request.meta["proxy"] = random.choice(self.unlimited_proxies)
逻辑说明
- 初始请求(
retry_times=0)和第一次重试(retry_times=1)仅使用packetstream_proxies,满足“先仅用packetstream重试一次”的需求。 - 当重试次数≥2时,自动切换到
unlimited_proxies,后续所有重试(直到达到RETRY_TIMES=25上限)都会持续使用该代理池。 - 增加空代理过滤逻辑,避免因配置缺失导致请求失败。
配置启用提醒
确保在settings.py中正确启用该中间件,调整优先级以保证其在Scrapy默认代理中间件之前执行:
DOWNLOADER_MIDDLEWARES = { '你的项目名.middlewares.SdtProxyMiddleware': 100, 'scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware': 110, }
内容的提问来源于stack exchange,提问作者X-something
相关产品推荐
相关产品推荐

