爬虫请求失败怎么办?超时、封禁、验证码的自动重试与异常处理实战
发布时间: 2026-09-12 08:27:04
阅读量: 22 人次
爬虫跑着跑着就崩了?超时、403、验证码、连接重置——没有完善的异常处理,爬虫撑不过第一轮
在爬虫开发中,请求失败不是异常而是常态。网络超时、目标服务器返回403/429/503、触发验证码挑战、连接被重置——这些问题在大规模爬虫中每天都会发生上百次。一个健壮的爬虫系统不是"不遇到错误",而是"遇到错误后能自动恢复"。本文从实战角度,系统讲解爬虫异常处理的三大核心机制:自动重试、封禁应对和验证码处理。
一、自动重试机制的设计
1、哪些错误应该重试
并非所有错误都值得重试。应该重试的错误包括:网络超时(timeout)、连接重置(connection reset)、服务端临时错误(500/502/503/504)。不应该重试的错误包括:客户端认证失败(401/403,除非确认是IP被封需要换IP)、资源不存在(404)、请求参数错误(400)。对于429(请求过多),应该降速后再重试而非立即重试。
2、指数退避策略
最简单的重试策略是固定间隔重试(如每3秒重试一次),但在高并发场景下,所有请求同时重试会造成"重试风暴",加剧目标服务器的压力。推荐使用指数退避策略:第1次重试等待1秒,第2次等待2秒,第3次等待4秒……同时加入随机抖动(jitter),避免多个请求同步重试。Python中可以使用`tenacity`库实现:`@retry(wait=wait_exponential(multiplier=1, max=60) + wait_random(0, 2))`。
3、最大重试次数与熔断机制
为每种错误设置不同的最大重试次数:网络超时最多重试3次,503错误最多重试5次,429错误最多重试2次(间隔更长)。当某个目标URL的连续失败次数超过阈值时,触发熔断机制——暂停对该URL的请求一段时间(如5分钟),避免无效重试浪费资源。
并非所有错误都值得重试。应该重试的错误包括:网络超时(timeout)、连接重置(connection reset)、服务端临时错误(500/502/503/504)。不应该重试的错误包括:客户端认证失败(401/403,除非确认是IP被封需要换IP)、资源不存在(404)、请求参数错误(400)。对于429(请求过多),应该降速后再重试而非立即重试。
2、指数退避策略
最简单的重试策略是固定间隔重试(如每3秒重试一次),但在高并发场景下,所有请求同时重试会造成"重试风暴",加剧目标服务器的压力。推荐使用指数退避策略:第1次重试等待1秒,第2次等待2秒,第3次等待4秒……同时加入随机抖动(jitter),避免多个请求同步重试。Python中可以使用`tenacity`库实现:`@retry(wait=wait_exponential(multiplier=1, max=60) + wait_random(0, 2))`。
3、最大重试次数与熔断机制
为每种错误设置不同的最大重试次数:网络超时最多重试3次,503错误最多重试5次,429错误最多重试2次(间隔更长)。当某个目标URL的连续失败次数超过阈值时,触发熔断机制——暂停对该URL的请求一段时间(如5分钟),避免无效重试浪费资源。
二、IP封禁的检测与应对
1、如何判断IP被封
IP被封的典型信号:连续多个请求返回403或429;原本正常的目标网站突然无法访问,但换一个IP就能正常访问;返回的页面内容变成了验证码页面或"访问被拒绝"提示。建议在爬虫中设置IP健康度监控:如果某个IP在10分钟内的失败率超过50%,标记为疑似被封,自动切换到新的代理IP。
2、IP轮换策略
被动轮换:IP被封后才切换,适合对成本敏感的场景;主动轮换:每N个请求或每M分钟主动切换一次IP,适合对稳定性要求高的场景。推荐使用主动轮换+被动切换的组合策略:设置默认轮换频率(如每20个请求轮换一次),同时在检测到封禁信号时立即切换。
3、降低被封概率的请求特征管理
除了IP轮换,还需要管理请求的其他特征:随机化User-Agent(维护一个50+的UA池,每次请求随机选取);随机化请求间隔(避免固定频率,使用正态分布生成间隔时间);维护Cookie会话(模拟真实浏览器的Cookie行为);控制单IP的请求速率(不超过目标网站的正常用户访问频率)。
IP被封的典型信号:连续多个请求返回403或429;原本正常的目标网站突然无法访问,但换一个IP就能正常访问;返回的页面内容变成了验证码页面或"访问被拒绝"提示。建议在爬虫中设置IP健康度监控:如果某个IP在10分钟内的失败率超过50%,标记为疑似被封,自动切换到新的代理IP。
2、IP轮换策略
被动轮换:IP被封后才切换,适合对成本敏感的场景;主动轮换:每N个请求或每M分钟主动切换一次IP,适合对稳定性要求高的场景。推荐使用主动轮换+被动切换的组合策略:设置默认轮换频率(如每20个请求轮换一次),同时在检测到封禁信号时立即切换。
3、降低被封概率的请求特征管理
除了IP轮换,还需要管理请求的其他特征:随机化User-Agent(维护一个50+的UA池,每次请求随机选取);随机化请求间隔(避免固定频率,使用正态分布生成间隔时间);维护Cookie会话(模拟真实浏览器的Cookie行为);控制单IP的请求速率(不超过目标网站的正常用户访问频率)。
三、验证码的检测与处理
1、验证码检测
在解析响应内容时,检测是否触发了验证码:检查HTTP状态码是否为202/403+特殊页面;检查页面标题或body中是否包含"验证码""captcha""verify""challenge"等关键词;检查是否出现了Google reCAPTCHA、腾讯验证码、阿里验证码等常见验证码服务的特征脚本标签。
2、验证码应对策略
首选策略:切换代理IP+清空Cookie后重试。很多验证码是基于IP和Cookie的关联判断,换IP+清Cookie有较高概率绕过。次选策略:降低请求频率,模拟人类浏览行为后重试。最后策略:接入验证码识别服务(如OCR识别或人工打码平台),但会增加成本和延迟。
3、从根本上减少验证码触发
大部分验证码触发都可以通过以下方式预防:控制单IP的请求频率不超过5次/分钟;使用住宅IP而非数据中心IP(住宅IP被标记为机器人的概率更低);模拟完整的浏览器行为链(先访问首页,再访问列表页,最后访问详情页);保持合理的会话持续时间(每次会话至少持续3-5分钟)。
在解析响应内容时,检测是否触发了验证码:检查HTTP状态码是否为202/403+特殊页面;检查页面标题或body中是否包含"验证码""captcha""verify""challenge"等关键词;检查是否出现了Google reCAPTCHA、腾讯验证码、阿里验证码等常见验证码服务的特征脚本标签。
2、验证码应对策略
首选策略:切换代理IP+清空Cookie后重试。很多验证码是基于IP和Cookie的关联判断,换IP+清Cookie有较高概率绕过。次选策略:降低请求频率,模拟人类浏览行为后重试。最后策略:接入验证码识别服务(如OCR识别或人工打码平台),但会增加成本和延迟。
3、从根本上减少验证码触发
大部分验证码触发都可以通过以下方式预防:控制单IP的请求频率不超过5次/分钟;使用住宅IP而非数据中心IP(住宅IP被标记为机器人的概率更低);模拟完整的浏览器行为链(先访问首页,再访问列表页,最后访问详情页);保持合理的会话持续时间(每次会话至少持续3-5分钟)。
总结
健壮的爬虫系统需要三层异常处理:自动重试机制应对临时性错误,IP轮换策略应对封禁,验证码检测与规避应对人机验证。三者配合使用,可以将爬虫的任务成功率从50%-60%提升至95%以上。建议在项目初期就搭建完善的异常处理框架,而非等问题出现后再补救。
关于山水代理
山水代理 的私密代理支持API动态提取,方便在爬虫中实现IP自动轮换——检测到封禁信号时,调用API获取新的代理IP即可无缝切换。
隧道代理 内置自动轮换机制,无需手动管理IP切换,适合需要高可用性的长时间爬虫任务。
欢迎随时 免费试用,提升爬虫的稳定性和成功率。
隧道代理 内置自动轮换机制,无需手动管理IP切换,适合需要高可用性的长时间爬虫任务。
欢迎随时 免费试用,提升爬虫的稳定性和成功率。


黑公网安备 23100002000084号