做爬虫的最怕遇到验证码了,费尽了心思好不容易搞定了IP轮询,还模拟好了浏览器指纹,自认为整个流程已然是没有任何破绽,堪称天衣无缝了,突然弹出来的图形验证码,直接让数据流戛然而止。
遇见图形验证码别慌,当代理 IP池碰到初级验证码——如四位数字字母混合、简单扭曲、背景噪点这类图片时,这套“组合拳”打法,能让你90%的初级验证码自动过。

第一步:别急着识别,先试试“绕过”和“屏蔽”
最高级的应对,是从源头减少麻烦。动识别模型之前,不妨先琢磨两个问题:
一个问题是,这个验证码能不能触发得晚一点、少一点?很多网站的验证码不是首次访问就出现,而是单位时间内访问频次过高才会触发。一个稳定、优质的动态代理IP池——比如独享IP池或设置得当的隧道代理,本身就是第一道防线。它能有效分散请求,模拟真实用户的“慢速”访问节奏,从根上减少验证码的触发几率。要是用粗暴的高频请求,哪怕换再多IP,也是在“求着”对方弹出验证码。
另一个问题是,我们看到的验证码,浏览器也看到了吗?打开浏览器开发者工具(F12),切换到Network(网络)标签,仔细查看触发验证码的请求。有时候,验证码的答案(Token)会直接藏在某个接口的响应里,或者生成逻辑完全由前端JavaScript计算完成。这种情况下,根本不用识别图形,只要正确重现前端逻辑就行。这类“验证码”本质是“逻辑题”,破解成本比图像识别低多了。
第二步:预处理是成功的一半——把“脏图”变“干净”
从网页上直接下载的验证码图片,大多不能直接扔给识别库。需要一套图像处理“流水线”把它标准化。
关键点在于,预处理没有标准答案,一张处理得当的图片,能够让后续的识别准确率提高数倍。
import cv2
import numpy as np
def preprocess_captcha(image_data):
# 1. 灰度化:降维,去掉颜色干扰
gray = cv2.cvtColor(image_data, cv2.COLOR_BGR2GRAY)
# 2. 二值化:将图像转换为纯粹的黑白,便于分离字符和背景
# 自适应阈值能更好地处理光照不均的图片
binary = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
cv2.THRESH_BINARY_INV, 11, 2)
# 3. 降噪:去除孤立的小黑点(椒盐噪声)
kernel = np.ones((1, 1), np.uint8)
cleaned = cv2.morphologyEx(binary, cv2.MORPH_OPEN, kernel)
# 4. 去干扰线:如果验证码有贯穿的横线或竖线,可取消注释使用
# kernel_line = np.ones((2, 2), np.uint8)
# cleaned = cv2.morphologyEx(cleaned, cv2.MORPH_CLOSE, kernel_line)
return cleaned
# 假设从网页获取了图片(实际使用时需补充下载逻辑)
# raw_image = cv2.imread("captcha.jpg") # 本地读取示例,也可对接网络下载
# processed_image = preprocess_captcha(raw_image)第三步:选择合适的“武器”——识别引擎的选型
图片处理干净后,就该选识别工具了。根据验证码复杂度和项目需求,有三种主流选择:
方案A:OCR通用引擎(快,但适用范围窄)
代表工具:pytesseract(Tesseract的Python封装)、百度/腾讯通用OCR API。
适用场景:字体标准、无扭曲、无粘连、背景极干净的验证码,比如部分企业内部系统或老旧网站的验证码。
优点:部署简单,识别速度快。
缺点:对变形、粘连的验证码几乎无效,准确率可能低于30%。
使用提示:一定要先做好预处理,还可以尝试通过pytesseract的config参数调整页面分割模式,比如--psm 7表示单行文本,有时能带来意外提升。
方案B:专用识别库(性价比之王)
代表工具:ddddocr,应对初、中级验证码的首选。
核心优势:内置训练好的模型,对数字、字母(大小写)、简单中文验证码识别效果出色,而且库体积轻量,无需GPU。本质是基于大量验证码数据预训练的CNN(卷积神经网络)模型,开箱即用。
优点:准确率高(针对目标类型可达90%+),速度和资源占用平衡得好,上手成本极低。
方案C:定制化深度学习模型(终极方案,但成本高)
代表架构:CNN(如ResNet)、CRNN等,需自行收集数据、标注、训练。
适用场景:字体独特、扭曲严重、干扰极强,且样式长期稳定的验证码,值得投入成本定制。
核心流程:
1. 数据收集:利用代理IP池低频率、长时间收集数千到数万张目标验证码图片;
2. 数据标注:可借助打码平台接口或半自动化工具生成初版标注,再人工校验;
3. 模型训练:用TensorFlow或PyTorch搭建训练模型,初期可直接用CNN做分类;
4. 部署集成:将训练好的模型封装成API,或直接集成到爬虫项目中。
第四步:构建稳健的自动化处理流程
除了识别外,还需要搭建一个闭环的自动化流程。
import requests
import ddddocr
import cv2
from your_ip_pool_manager import get_proxy, mark_proxy_temp_disabled # 需对接自身IP池管理模块
# 初始化OCR和预处理函数
ocr = ddddocr.DdddOcr(show_ad=False)
def preprocess_captcha(image_data):
gray = cv2.cvtColor(image_data, cv2.COLOR_BGR2GRAY)
binary = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
cv2.THRESH_BINARY_INV, 11, 2)
kernel = np.ones((1, 1), np.uint8)
cleaned = cv2.morphologyEx(binary, cv2.MORPH_OPEN, kernel)
return cleaned
def solve_and_request(url, captcha_url_parser, retry=3):
for attempt in range(retry):
# 1. 获取新鲜代理IP
proxy = get_proxy(type="http")
if not proxy:
print("未获取到可用代理,重试...")
continue
# 2. 发起请求,获取含验证码的页面(或触发验证码)
session = requests.Session()
session.proxies = {"http": proxy, "https": proxy}
try:
initial_resp = session.get(url, timeout=10)
initial_resp.raise_for_status() # 抛出HTTP错误
except requests.exceptions.RequestException as e:
print(f"请求失败:{e},标记IP暂不可用")
mark_proxy_temp_disabled(proxy)
continue
# 3. 解析页面,提取验证码图片URL(需根据目标网站定制解析逻辑)
image_url = captcha_url_parser(initial_resp.text)
if not image_url:
print("未触发验证码,请求成功")
return initial_resp # 未触发验证码,直接返回结果
# 4. 下载并识别验证码
try:
img_resp = session.get(image_url, timeout=10)
img_resp.raise_for_status()
# 转换为OpenCV可处理的格式
img_array = np.asarray(bytearray(img_resp.content), dtype=np.uint8)
raw_image = cv2.imdecode(img_array, cv2.IMREAD_COLOR)
processed_image = preprocess_captcha(raw_image)
captcha_code = ocr.classification(processed_image)
except Exception as e:
print(f"验证码处理失败:{e}")
mark_proxy_temp_disabled(proxy)
continue
# 5. 构造表单数据,提交验证码
post_data = {
"username": "your_user",
"password": "your_pass",
"captcha": captcha_code
}
try:
final_resp = session.post(url, data=post_data, timeout=10)
final_resp.raise_for_status()
except requests.exceptions.RequestException as e:
print(f"提交验证码失败:{e}")
mark_proxy_temp_disabled(proxy)
continue
# 6. 验证请求是否成功
if "登录成功" in final_resp.text or final_resp.status_code == 200:
print(f"第{attempt+1}次尝试成功,使用代理:{proxy},识别码:{captcha_code}")
return final_resp
else:
print(f"第{attempt+1}次尝试失败,识别码可能错误,更换IP重试...")
mark_proxy_temp_disabled(proxy)
continue
print(f"重试{retry}次均失败,建议人工干预或升级识别方案")
return None需要注意的是:
1.代理IP跟验证码协同,一旦识别失败,就得更换新的IP以及新的验证码图片再去尝试,要是用同一个IP反复提交错误答案,只会加快IP被封禁的速度。
2.进行结果验证,必须得有判断提交成功与否的逻辑,像检查返回页的内容,或者检查状态码之类。
3.当连续失败达到N次之后,需要把相关任务转到“待处理队列”,触发人工处理,避免业务停滞。
应对初级图形验证码时,最重要的是“综合调理”:要先仔细观察验证码的特征,再探寻网络请求绕过的可能性,检查自身流程;同时要保证IP池处于稳定健康的状态、访问节奏尽可能地贴近真实人类的行为模式,最后用“预处理+ddddocr”直击要害。
行业新闻查看更多
- 1
从京东具身数据中心,看代理IP行业未来3年爆发逻辑
- 2
学术数据采集必备:代理 IP 如何助力合法合规收集公开网络数据?
- 3
2026年代理IP服务趋势:动态IP为何比静态更吃香?
- 4
代理IP是什么?怎么工作的?小白必看!一张图看懂代理IP数据转发流程
- 5
2026 免费代理 IP 资源网站 TOP5 推荐!免费代理 IP 资源怎么找?
- 6
2026最新:数据采集为什么必须用国内代理IP?附免费资源推荐
- 7
宽带越普及,好用的动态代理 IP 为何反而越难找?
- 8
浏览器插件代理 vs 系统级代理:哪个更适合你?
- 9
免费代理IP不能用怎么办?4个常见问题+解决方案,新手急救必看!
- 10
代理IP行业用户画像:谁在使用代理IP?
爬虫探索查看更多
- 1
爬虫代理IP端口怎么选择?常见端口适配教程(新手必看)
- 2
搞懂代理IP响应时间:为什么有的代理 IP 能用但慢?如何筛选出速度快的代理IP?
- 3
爬虫被封怎么办?我靠监控这6类指标,提前避开封禁坑
- 4
火车头爬虫怎么配置免费代理IP?详细设置步骤
- 5
用代理 IP 抓取电商价格,如何设置爬取频率才不会触发风控?
- 6
反爬的 “黑暗森林法则”:为什么你的爬虫总活不过三天?
- 7
跨境电商价格监控:如何稳定抓取Amazon、Shopee不封号?
- 8
数据采集别再等IP被封了!爬虫健康状态应该监控这几点
- 9
广告区域验证必看:代理IP如何模拟本地用户检查广告展示
- 10
代理IP端口不会配?爬虫新手速看:常见端口适配指南
