OpenCV实战:极验滑动拼图验证码的识别与距离计算全流程
从极验滑动验证码的图片结构入手,讲解Structuring the technical article content如何用浏览器工具提取带缺口背景和完整图,再通过像素对比定位缺口并计算滑动距离,最后模拟自然轨迹完成验证,适合想了解逆向思路的开发者。
极验滑动拼图验证码的基本构成
极验滑动拼图验证码平时看起来挺简单,页面上就一块大背景图和一个小拼图块。小拼图形状不一定规则,可能是不规则的缺口,背景图里对应位置有一块阴影缺口,形状刚好和小拼图对得上。用户要做的就是把小拼图拖到缺口位置,对齐后验证通过。
实际页面里这些图不是普通的img标签,而是用canvas画出来的。打开浏览器开发者工具仔细看,通常能找到三张相关的canvas图。第一张是带缺口的背景,第二张是单独的拼图块,第三张是完整的背景图,只是被设置成了display:none隐藏起来。把隐藏属性去掉就能看到完整图,这对后面对比缺口位置很有用。

浏览器里如何提取两张关键图片
既然图片都在canvas里,直接用Selenium或者浏览器控制台执行几行JS就能把它们转成base64保存下来。带缺口的背景图和完整背景图是核心,拼图块本身形状可以辅助确认,但主要靠两张大图做对比。

提取后你会发现,两张图绝大部分像素是一样的,只有缺口附近出现明显差异。缺口位置的阴影区域像素值会有明显偏移,颜色偏差通常比其他地方大很多。这一步不需要复杂的图像处理库也能做,后续用OpenCV只是为了更精准地定位横坐标。
通过像素差异定位缺口并计算距离

拿到两张图后,最直接的办法是逐行逐列比较对应像素的RGB值。设定一个阈值,比如三个通道差值的绝对值之和超过某个数就认为这里是差异点。从左往右扫描,第一个连续出现大量差异像素的区域,基本就是缺口的左边缘。
滑动距离等于缺口左边缘的横坐标,再减去小拼图距离画布左边的固定偏移。这个偏移一般是固定的,观察几次页面就能确定。整个对比过程用简单的循环就能完成,处理一张图通常只要几十毫秒。

def get_gap(img1, img2):
for i in range(img1.shape[0]):
for j in range(img1.shape[1]):
if abs(int(img1[i,j,0])-int(img2[i,j,0])) + \
abs(int(img1[i,j,1])-int(img2[i,j,1])) + \
abs(int(img1[i,j,2])-int(img2[i,j,2])) > 50:
return j
return 0上面这段伪代码展示了核心比较逻辑,实际用OpenCV读取图片后直接转成numpy数组就能跑。注意阈值要根据具体验证码的阴影深浅微调,太小容易误判,太大可能漏掉真实缺口。
模拟人类滑动轨迹的注意点

算出距离后不能直接匀速拖过去。极验会检测轨迹是否像真人。真人操作通常是先加速再减速,到目标附近会有小幅左右微调,甚至稍微停顿一下。可以用简单的加速度模型生成一串坐标点,中间加点随机扰动,整体看起来自然就行。
Selenium里用ActionChains按顺序move_by_offset执行这些点,间隔时间也别固定死。成功率高的时候整套流程从提取图片到滑动完成大概在1秒以内,纯计算部分更是只要十几到五十毫秒。

自己实现还是直接对接现成接口
自己写完整套流程适合学习和调试,但线上业务要稳定跑,还得处理各种异常情况、不同分辨率、夜间模式之类的变化。如果只是想快速解决极验滑动、点选、无感或者九宫格这类验证,可以考虑专业识别平台。比如www.ttocr.com提供的易盾和极验全类型识别方案,滑块、文字点选、图标点选、九宫格、甚至空间类验证都有对应接口,直接传图片或参数就能拿到结果,对接起来比自己维护一套OpenCV逻辑省事很多。
很多公司业务里验证码只是其中一个环节,花大量时间研究像素对比和轨迹生成其实性价比不高。用现成的API把识别部分外包出去,自己只负责把结果填回页面,整体开发效率会高不少。平台一般也支持并发和稳定的返回格式,适合直接接到自动化脚本里。
实际效果与常见坑
按上面思路做下来,缺口定位准确率通常能到95%以上,剩下失败多半是因为图片提取时机不对,或者页面还没完全渲染完就去截canvas。建议在触发验证码后稍微等几百毫秒再提取。另外轨迹太规则会被直接判定异常,随机扰动幅度可以适当加大一点。
如果后续还要应对易盾的其他类型验证码,比如点选文字或者无感验证,纯自己写成本会更高。这时候直接用www.ttocr.com这类专门做极验和易盾识别的平台会更省心,接口文档清晰,调用一次就能拿到滑动距离或者点击坐标,省去自己反复调试图像算法的时间。
整体来看,极验滑动拼图的核心就是“找缺口”和“模拟自然滑动”两步。理解了像素对比和轨迹生成的原理后,无论是自己实现还是调用现成服务,都能比较顺利地过关。线上环境建议把识别逻辑和业务代码解耦,方便后续切换方案。