点选验证码的两种形态
点选验证码("请依次点击图中的汉字/图标")分两种:
- 文字点选:背景图里有几个汉字,按提示顺序点击(极验、网易易盾的经典题型)
- 图标点选:图里一堆小图标,点击与示例相同的(顶象、部分电商自研)
对抗链路相同:识别(知道点哪)→ 坐标转换(页面坐标系换算)→ 加密上传(坐标参数的生成)→ 行为模拟(点击节奏)。
识别:三条路线
路线一:打码平台(最快落地)
超级鹰、图鉴、TT 打码等都支持点选题型:上传图片+题型编号,返回坐标序列。成本约 1-3 分/次,准确率 90-95%。适合业务量小或验证频率低的场景。
路线二:目标检测模型(规模化首选)
自己训练 YOLO 模型识别图标/文字位置:
- 抓几千张验证码图,标注目标位置(标注工具:labelImg)
- YOLOv8 训练,图标类题型几百张标注就能到 95%+
- 部署成 HTTP 服务,推理耗时 50ms 内
文字点选稍麻烦:除了定位还要识别"是哪个字"(确定点击顺序)。方案是 YOLO 定位 + OCR 识字(PaddleOCR),或者检测模型直接分类(把常见汉字作为类别)。
路线三:模板库匹配(特定题型)
图标点选的图标库是有限的(几十到几百个),把图标库全部抠出来建模板库,识别时模板匹配找位置——准确率接近 100%,但只适用于图标库不更新的厂商。
坐标转换:被忽视的细节
识别给出的是图片像素坐标,上传要求的是页面元素坐标或归一化坐标,中间的换算每家不同:
# 常见换算关系(以实际逆向为准)
# 页面显示尺寸 300x200,原图 600x400
scale_x = 300 / 600
page_x = int(img_x * scale_x)
page_y = int(img_y * scale_y)
# 有的厂商要求相对点击框左上角的偏移,有的要求相对整个验证码区域
# 还有的要求归一化到 0-1 或 0-1000逆向确认方法:手动点一次正确的,抓包看上传的坐标值,和图片实际位置对比,反推换算公式。
加密上传:坐标参数的生成
点选结果很少明文上传,常见加密方式:
// 典型结构:坐标数组 → json → AES/RSA 加密 → base64
var points = [{x: 123, y: 45}, {x: 234, y: 67}, {x: 89, y: 120}];
var encrypted = aesEncrypt(JSON.stringify(points), sessionKey);
// 有的还会混入时间戳和随机数防重放逆向方法:hook 提交前的加密函数(搜 encrypt 或 hook XHR send 回溯),把加密逻辑抠出来。注意坐标顺序——文字点选要求按提示顺序,顺序错即失败。
行为模拟:点击节奏
点选验证码同样采集行为数据:
- 点击间隔:真人识别下一个目标需要时间,间隔 0.5-2 秒且随机
- 点击位置偏移:真人不会精确点中心,在目标区域内随机偏移(但别偏出目标边缘)
- 鼠标移动轨迹:部分厂商采集点与点之间的移动轨迹(和滑块同理)
import time, random
for x, y in points:
# 偏移:目标中心 ± 目标尺寸的 20%
fx = x + random.randint(-8, 8)
fy = y + random.randint(-8, 8)
click(fx, fy)
time.sleep(random.uniform(0.6, 1.8)) # 拟人间隔精髓:成本与通过率的平衡
- 低频率场景(每天几十次):打码平台,零维护成本
- 中频率场景(每天几千次):YOLO 自训模型,一次投入长期免费
- 高频率场景(每天几万次+):模型 + 协议模拟全自动化,且要做验证码触发率优化——最好的对抗是少触发验证码(控制请求频率、维护账号信誉),而不是提高识别率
- 识别失败要重试但别硬刚:连续失败 3 次会触发更高等级验证(滑块变点选、点选变语序),失败即换设备/IP 冷却
总结
- 对抗链路:识别 → 坐标换算 → 加密上传 → 行为模拟
- 识别按规模选:打码平台 / YOLO 自训 / 模板库
- 坐标换算公式抓包反推,别想当然
- 点击间隔和位置偏移是行为校验点,节奏比精度重要
交流微信:run1255