从原理到自动化实战全指南
目录导读
- 验证码类型识别为什么重要?——核心痛点与场景
- 验证码主流类型全解析(图文对照)
- 脚本识别验证码类型的底层逻辑与算法选型
- 手把手实现:Python脚本识别五大验证码类型
- 常见问题Q&A(含代码调试问答)
- 识别精度提升技巧与反爬规避策略
验证码类型识别为什么重要?
Q:网上验证码识别教程那么多,为什么还要专门写一篇“识别验证码类型”的文章?
A:因为90%的自动化脚本在第一步就卡住了——你根本不知道对面站点的验证码属于“字符型”“滑动型”“点选型”还是“行为轨迹型”,不同类型的验证码需要完全不同的处理管线,盲用通用OCR(光学字符识别)对滑动验证码毫无作用。判断验证码类型是自动化操作的第一道门槛。

抓取某电商平台商品价格时,可能会遇到:
- 图形字符验证码(需CNN分类器)
- 滑块缺口验证码(需目标检测+轨迹模拟)
- 旋转角度验证码(需关键点回归)
如果脚本无法自动判别类型,后续对应策略将全部失效。
验证码主流类型全解析
要“用脚本识别类型”,首先得知道有哪些类型可被识别,根据搜索引擎最新资料汇总,常见验证码分为以下五类:
1 文本字符型(Text CAPTCHA)
- 特征:扭曲、粘连、带噪声的字母数字组合,通常为4-6位。
- 示例:
A3c#9,背景有横线/点状干扰。 - 脚本识别指标:图像宽高比、字符连通域数量、灰度直方图波峰波谷。
2 滑块拼图型(Slider CAPTCHA)
- 特征:一张完整背景图+一块缺失的小图,需拖动滑块对齐缺口。
- 示例:极验、腾讯滑块、阿里云盾。
- 脚本识别指标:图像边缘梯度、缺口区域对比度、滑块阴影特征。
3 点选/点击型(Click CAPTCHA)
- 特征:出现一组图片,要求按指定顺序点击某个物体(如“请点击红绿灯”)。
- 示例:12306点选、语义词验证。
- 脚本识别指标:目标检测物体类别置信度、JSON返回的文字指令。
4 旋转校正型(Rotate CAPTCHA)
- 特征:图片被旋转一定角度,需拖动转盘使图片回正。
- 示例:谷歌reCAPTCHA v2的“旋转图片”变体。
- 脚本识别指标:图像方向梯度分布、UI控件中的圆弧进度条角度。
5 行为轨迹型(Behavior CAPTCHA)
- 特征:不需要用户主动输入,后台分析鼠标移动路径、点击频率、时间间隔。
- 示例:极验无感验证、CF防人机挑战。
- 脚本识别指标:请求头中的轨迹加密参数(如w参数),严格来说不是图像型,但脚本需监控页面加载特征。
脚本识别验证码类型的底层逻辑
1 核心方法:基于特征工程+轻量级CNN分类
实现“自动识别类型”,本质上是一个多分类任务,可行方案有两种:
方案A:规则驱动(适用于初阶脚本)
- 步骤1:获取验证码图片元素URL或base64数据。
- 步骤2:计算图像特征向量:
- 分辨率分布(滑块图通常为280x160,字符图为200x70)
- 颜色复杂度(字符型噪声较多)
- 边缘密度(滑块缺口边界明显)
- 步骤3:根据阈值规则判别类型。
优点:无需训练;缺点:对变形验证码容错低。
方案B:深度学习分类(推荐生产环节)
- 使用ResNet18或MobileNetV3轻量网络,在公开验证码数据集(如CAPTCHA-classification-50k)上微调。
- 输入:归一化到224x224的验证码截图。
- 输出:
['text','slider','click','rotate','behavior']概率分布。
优点:泛化性强;缺点:需标注数据。
2 关键判断特征一览(可直接用于规则)
| 验证码类型 | 关键可计算特征 |
|---|---|
| 文本字符型 | 字符数=4~6,连通域个数>3,非连续色块较多 |
| 滑块拼图型 | 图像中出现一条横向缺口(通过Canny边缘检测),且存在一个独立滑块小图 |
| 点选型 | 页面存在多个同类物体图像,且伴随文字提示按钮 |
| 旋转型 | 存在圆形/半圆弧控件,且图像主方向偏移超过15° |
| 行为型 | 页面不显示任何可见输入框,仅监听鼠标事件 |
手把手实现:Python脚本识别五大验证码类型
假设已通过Selenium或Playwright获取到验证码截图为captcha_image.png,下面给出一个综合判断脚本的核心逻辑:
import cv2
import numpy as np
from PIL import Image
import requests
import json
class CaptchaTypeDetector:
def __init__(self, image_path):
self.img = cv2.imread(image_path)
self.gray = cv2.cvtColor(self.img, cv2.COLOR_BGR2GRAY)
def detect_slider(self):
"""检测是否为滑块验证码:通过边缘缺口特征"""
edges = cv2.Canny(self.gray, 50, 150)
# 统计横向边缘的密度分布,若在某一行出现连续高密度缺口,判定为滑块
hist = np.sum(edges, axis=1) # 每行边缘点计数
peak_rows = np.where(hist > np.max(hist)*0.8)[0]
if len(peak_rows) > 5 and (peak_rows[-1] - peak_rows[0]) < 10:
return True
return False
def detect_text_captcha(self):
"""检测是否为文本字符型:通过连通域统计"""
_, binary = cv2.threshold(self.gray, 127, 255, cv2.THRESH_BINARY_INV)
num_labels, labels, stats, centroids = cv2.connectedComponentsWithStats(binary, 8)
# 排除背景(标签0),统计中等大小的连通域
char_labels = [i for i in range(1, num_labels) if 50 < stats[i, cv2.CC_STAT_AREA] < 500]
if 3 <= len(char_labels) <= 6: # 常见字符数范围
return True
return False
def detect_rotate(self):
"""检测是否为旋转型:通过图像主方向偏移"""
# 简单判断:检测图像中是否存在环形控件(通过圆形霍夫变换)
circles = cv2.HoughCircles(self.gray, cv2.HOUGH_GRADIENT, 1, 20, param1=50, param2=30)
if circles is not None and len(circles[0]) >= 1:
# 存在环形控件,大概率是旋转验证码
return True
return False
def classify(self):
# 优先级:滑块 > 旋转 > 文本 > 行为/点选(需结合页面DOM判断)
if self.detect_slider():
return "slider"
elif self.detect_rotate():
return "rotate"
elif self.detect_text_captcha():
return "text"
else:
# 若以上均不满足,根据页面DOM进一步判断
return "unknown"
使用示例:
detector = CaptchaTypeDetector("sample_captcha.png")
print(f"检测到的验证码类型为: {detector.classify()}")
常见问题Q&A(含代码调试)
Q1:脚本把非验证码图片(比如商品图)误识别成字符型怎么办?
A:加一个白名单校验,在detect_text_captcha函数中,增加aspect_ratio判断:文本验证码的长宽比通常为2.5~4.0,而商品图往往接近1:1,同时可利用神经网络过滤自然图像。
Q2:如何将不同类型验证码的处理策略无缝衔接?
A:建议使用策略模式设计代码结构。
type_handlers = {
"text": TextHandler(),
"slider": SliderHandler(),
"click": ClickHandler()
}
captcha_type = detector.classify()
result = type_handlers[captcha_type].solve()
Q3:滑动验证码的特征检测中,图像边缘阈值怎么调?
A:不要用固定阈值,推荐使用自适应阈值(cv2.adaptiveThreshold)或基于大津法(OTSU)的二值化,如果平台滑块有透明度(如极验),需先将图像与背景图差分。
Q4:行为轨迹型验证码(如CloudFlare)脚本能识别吗?
A:无法通过图像识别,但可以从HTML特征判断:检测<iframe>中是否存在challenge-script、turnstile等关键词,或监测window.__cf_chl_opt变量,行为型应走专门的请求头模拟方案。
Q5:识别精度能达到多少?
A:规则方法在标准公开数据集上约85%-90%,若用深度学习方法(CNN),在五大类型分类任务中可达97%+,前提是训练数据准确覆盖各类型变体。
识别精度提升技巧与反爬规避
1 提升识别精度的三个绝招
- 集成投票:同时运行规则法+轻量CNN法,若结果不一致,取置信度最高的。
- 加载页面交互数据:爬取验证码时同步捕获后端返回的
type字段,许多网站请求captcha/api时会返回{ "type": "click" },此时无需图像分析。 - 新增数据增强:对图像施加轻微高斯模糊、随机裁剪,增加分类器鲁棒性。
2 反爬规避注意事项(必读)
- 不要以固定频率请求验证码,模拟人类点击间隔(300ms-800ms随机)。
- 使用高隐蔽User-Agent(
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36...)。 - 对识别失败的验证码,脚本应内置上报机制(记录截图与错误类型),便于后期人工复核并更新分类模型。
- 避坑建议:一定不要在评论区或代码中公开暴力破解频率,遵循目标网站的robots.txt协议,道德使用技术。
通过本文的方法,你可以用脚本自动对任意验证码进行类型预判,然后动态分配对应的识别引擎,从特征工程到深度学习分类,每一步都有明确的实现参考,核心是:分而治之——先判断是“谁”,再决定怎么“打”,没有万能的验证码解决方案,但精准的类型识别就是你自动化脚本最坚固的第一块基石。
注:文中示例代码为精简演示,生产环境中还需处理超时重试、分布式存储等细节,若需要更多场景的脚本实现(如极验、腾讯滑块、数字点选),可进一步迭代封装。