Scrapy爬虫的代理中间件配置:重试、轮换与失效剔除
发布时间: 2026-10-22 10:31:35
阅读量: 5 人次
代理接入的重点不在"设上",而在失败之后怎么处理
Scrapy 接入代理本身只有一两行配置,真正影响采集成功率的是三件事:请求失败时换不换代理、换下来的代理多久再启用、重试有没有上限。配置得简单,往往会把失效代理反复用满整个任务;配置得当,同样的代理池能把成功率拉开明显差距。本文按请求流程讲清 Scrapy代理中间件 的写法与几个常见坑。
一、中间件在请求链路的哪个位置
请求从 Spider 发出后,先经过下载器中间件的 process_request,再交给下载器;响应或异常返回时经过 process_response 与 process_exception。代理的选取、注入与失败统计,放在 process_request 与 process_exception 最合适:前者决定这次用哪个出口,后者决定失败后要不要换、换哪个。
二、最小可用配置
1、开启下载器中间件
在 settings 中把自定义中间件加入 DOWNLOADER_MIDDLEWARES,并给它一个合适的顺序值。代理注入通常放在靠前的位置,保证后续中间件拿到的已经是带代理的请求。
2、给请求写入 proxy 字段
在 process_request 中读取代理池,把选中的代理写到 request.meta["proxy"],格式为协议加主机加端口,带认证时写成 用户名:密码@主机:端口。Scrapy 自带的 HttpProxyMiddleware 会读取这个字段完成转发。
3、把选中的代理记在 meta 里
除了 proxy,再存一份本次使用的代理标识。失败回调、日志和去重统计都要靠它判断是哪个出口出的问题,不能等事后从请求头里反推。
在 settings 中把自定义中间件加入 DOWNLOADER_MIDDLEWARES,并给它一个合适的顺序值。代理注入通常放在靠前的位置,保证后续中间件拿到的已经是带代理的请求。
2、给请求写入 proxy 字段
在 process_request 中读取代理池,把选中的代理写到 request.meta["proxy"],格式为协议加主机加端口,带认证时写成 用户名:密码@主机:端口。Scrapy 自带的 HttpProxyMiddleware 会读取这个字段完成转发。
3、把选中的代理记在 meta 里
除了 proxy,再存一份本次使用的代理标识。失败回调、日志和去重统计都要靠它判断是哪个出口出的问题,不能等事后从请求头里反推。
三、轮换策略怎么选
1、每请求轮换
适合相互独立、无会话的页面抓取。好处是单个代理失效影响面小,代价是连接无法复用,握手开销高。
2、按会话轮换
同一个任务或同一个站点在一段时间内保持同一出口,登录态、分页与需要连续性的请求更稳。实现上给每个会话分配一个代理并绑定到任务,任务结束再释放。
3、固定出口
对白名单授权或需要稳定来源的场景,直接用隧道代理的固定入口,出口变化交给代理侧处理,业务配置最简单。
适合相互独立、无会话的页面抓取。好处是单个代理失效影响面小,代价是连接无法复用,握手开销高。
2、按会话轮换
同一个任务或同一个站点在一段时间内保持同一出口,登录态、分页与需要连续性的请求更稳。实现上给每个会话分配一个代理并绑定到任务,任务结束再释放。
3、固定出口
对白名单授权或需要稳定来源的场景,直接用隧道代理的固定入口,出口变化交给代理侧处理,业务配置最简单。
四、失效剔除与重试
1、区分失败类型
连接超时、代理认证失败、目标返回 403 或 429 是不同问题。前两类应立刻换代理并给该代理记一次失败;后者要结合目标站策略判断,盲目换 IP 重试可能加重限速。
2、失败计数与冷却
每个代理维护成功与失败计数,连续失败达到阈值后移入冷却队列,过一段时间再试探性放回。只剔除不恢复,代理池会越用越小。
3、重试必须有上限
在 process_exception 里重新入队时,先检查请求上的重试次数。没有上限的重试会在目标持续拒绝时形成雪崩,同时把流量和并发全部吃掉。
4、重试时换代理
同一个请求重试时,要显式清除旧的代理标识并重新选取,否则可能继续用刚才失败的出口,重试等于没做。
连接超时、代理认证失败、目标返回 403 或 429 是不同问题。前两类应立刻换代理并给该代理记一次失败;后者要结合目标站策略判断,盲目换 IP 重试可能加重限速。
2、失败计数与冷却
每个代理维护成功与失败计数,连续失败达到阈值后移入冷却队列,过一段时间再试探性放回。只剔除不恢复,代理池会越用越小。
3、重试必须有上限
在 process_exception 里重新入队时,先检查请求上的重试次数。没有上限的重试会在目标持续拒绝时形成雪崩,同时把流量和并发全部吃掉。
4、重试时换代理
同一个请求重试时,要显式清除旧的代理标识并重新选取,否则可能继续用刚才失败的出口,重试等于没做。
五、并发与限速要一起调
并发数提高会放大代理池的压力,失效代理占用的槽位也更多。建议同时设置全局并发、单域名并发与下载延迟,并开启自动限速。观察指标不要只看请求速度,还要看成功率与平均重试次数:速度上去了但重试翻倍,实际有效吞吐并没有提高。
六、几个常见坑
1、meta 没有透传
在回调里重新构造请求时漏掉 meta,代理字段会丢失,后续请求变成直连,日志里看不出明显异常。
2、认证信息写错位置
用户名密码要放在代理 URL 中,或按代理服务商要求使用白名单,不要塞进请求头。认证失败通常表现为 407 或连接被立即关闭。
3、日志缺少代理标识
只在失败时打印异常信息,不打印本次使用的代理,事后无法判断是代理问题还是目标问题。把代理标识放进每条日志,排障成本会低很多。
在回调里重新构造请求时漏掉 meta,代理字段会丢失,后续请求变成直连,日志里看不出明显异常。
2、认证信息写错位置
用户名密码要放在代理 URL 中,或按代理服务商要求使用白名单,不要塞进请求头。认证失败通常表现为 407 或连接被立即关闭。
3、日志缺少代理标识
只在失败时打印异常信息,不打印本次使用的代理,事后无法判断是代理问题还是目标问题。把代理标识放进每条日志,排障成本会低很多。
总结
Scrapy 的代理接入可以很轻,但要把成功率做稳,关键在失败处理:区分失败类型、给代理做失败计数与冷却、重试设上限并在重试时换出口、日志带代理标识。轮换策略按业务连续性选择,独立页面可以每请求轮换,有会话与分页的请求按会话保持。并发与限速要和代理池规模一起调,否则只是把失败放大。
关于山水代理
私密代理 支持按量提取,适合在 Scrapy 中自行维护代理池与失败剔除逻辑。
隧道代理 提供固定入口与自动轮换,配置里只需写一个地址,适合不想自己维护代理池的采集任务。
欢迎随时 免费试用,先用一个小目标站验证重试与剔除策略,再扩大到全量任务。
隧道代理 提供固定入口与自动轮换,配置里只需写一个地址,适合不想自己维护代理池的采集任务。
欢迎随时 免费试用,先用一个小目标站验证重试与剔除策略,再扩大到全量任务。


黑公网安备 23100002000084号