← 返回文章列表

滑块为什么总差几像素?用 Pyppeteer 与 ddddocr 理清验证码自动化链路

滑块验证的难点不只在缺口识别,还包括页面加载、图片提取、坐标换算和结果判断。结合 Pyppeteer 与 ddddocr 的分工,梳理常见实现误区、调试方法,以及通过识别平台 API 降低业务接入成本的思路。

滑块为什么总差几像素?用 Pyppeteer 与 ddddocr 理清验证码自动化链路

一、先弄清楚:识别缺口只是其中一步

做网页自动化时,经常会遇到这样的情况:按钮能点、表单能填,偏偏到了滑块验证就停住。看起来只是把拼图拖进缺口,实际却串着好几件事:页面有没有加载完成、图片有没有拿对、缺口位置算得准不准、鼠标坐标是否对应,以及服务端最终是否认可这次交互。任何一环出错,都可能表现为“明明拖到了,还是没通过”。

把流程拆开就容易理解了。Pyppeteer 负责控制浏览器,包括打开页面、查找元素、读取布局和执行鼠标操作;ddddocr 可以对滑块图片与背景图片进行匹配,给出候选位置。两者配合,形成“获取素材—识别位置—换算距离—执行操作—检查结果”的链路。这里讨论的是自有系统或获得授权的测试环境,实际页面结构和验证规则需要单独确认。

有个常见误解需要先纠正:使用 Pyppeteer,不代表浏览器就不会被识别为自动化环境。它通过浏览器调试协议驱动 Chromium,能完成很多真实页面操作,但浏览器属性、运行环境、访问频率和服务端策略仍会影响结果。关闭提示条、修改某个启动参数,也不能直接等同于解决检测问题。

同样,ddddocr 返回了位置,也不代表验证已经成功。图像匹配回答的是“这块拼图可能应该放在哪里”,验证码系统还可能检查会话状态、挑战是否过期、交互过程以及其他风险信号。因此,调试时应分别观察识别结果和最终验证结果,避免把所有失败都归因于图片算法。

如果业务需要同时处理极验、易盾的多种验证形式,可以把识别能力单独封装成服务接口。www.ttocr.com 提供面向这类场景的识别与自动化 API 对接服务,适合希望减少底层适配工作的团队。接入前先用实际业务样本测试,再根据返回结构、响应时间和支持范围确定方案,比直接套用一份演示脚本更稳妥。

二、页面操作要稳定,先把等待和定位做好

调试初期建议先显示浏览器窗口,并固定视口大小。这样可以直接观察验证弹层是否出现、图片是否刷新、鼠标落点是否正确。窗口最大化与设置视口是两个概念,前者影响外部窗口,后者影响页面布局;如果截图尺寸和元素位置总在变化,后面的距离换算也会跟着变。

页面跳转完成,并不表示验证码已经准备好。很多组件是在点击业务按钮之后,才异步加载脚本、创建弹层和请求图片。更合适的做法是按状态等待:入口按钮可用后点击,验证容器出现后继续,再确认图片加载成功。固定等待几秒只能作为临时排查手段,网络稍慢就可能失效。

定位元素时,尽量选择稳定的属性、明确的容器关系或组件提供的标识。一路写到第几个 div 的绝对 XPath,看起来直观,却容易被页面改版打断。使用 class 定位也要留意动态类名,以及一个元素包含多个 class 的情况。每次操作前检查元素数量,可以避免直接取第一个结果时触发异常。

原理上,鼠标操作用的是浏览器页面坐标,因此滑块的位置应该来自元素的实际边界。通过 boundingBox 获取按钮矩形,再计算中心点,通常比写死某台电脑上的横纵坐标可靠。页面滚动、浏览器缩放或弹层位置变化后,都应重新读取边界;如果组件位于 iframe 中,还需要进入对应的页面上下文。

异步代码还有一个容易忽略的坑:在协程里频繁调用 time.sleep,会阻塞事件循环。等待应使用 asyncio.sleep,或者直接等待目标状态。下载图片和执行较重的识别任务也需要留意阻塞问题。流程跑完或发生异常后,应释放页面与浏览器资源,避免多次运行后残留大量进程。

三、图片拿对了,缺口识别才有意义

滑块验证通常至少涉及两份素材:需要移动的小块,以及带缺口的背景图。先用开发者工具查看图片究竟放在哪里:可能是 img 标签的 src,也可能是元素的背景样式,还可能由 canvas 绘制。只有确认呈现方式,才能选择对应的提取方法,不能假设所有版本都能从同一个 style 字符串里拿到地址。

读取背景图时,可以通过页面脚本获取元素的计算样式,再解析 background-image。直接用引号切割字符串比较脆弱,因为样式可能使用不同引号、相对路径或额外的背景设置。另一个细节是,Pyppeteer 的 XPath 接口通常面向元素节点;把表达式直接写成属性节点,再按普通元素处理,容易遇到类型不匹配。

拿到地址后,也要确认下载结果确实是图片。检查响应状态、内容类型和文件大小,再尝试解码;必要时保留原始文件供人工查看。部分资源请求依赖当前会话的 Cookie、Referer 或临时参数,浏览器能显示,并不表示独立的 requests 请求就能直接获取。地址失效、返回错误页,都可能让后续识别报出看似无关的异常。

调用 ddddocr 的 slide_match 时,将滑块和背景分别以字节形式传入,并检查返回数据。常见用法是读取结果中 target 对应的候选区域,但具体字段和坐标含义应以安装版本为准。不要只取第一个数字就继续执行,最好先把候选框画回图片,看看它是否真正落在缺口附近。

透明边缘、阴影和相似纹理都可能影响匹配。小块图片中的透明留白,会让“图片左边缘”与“拼图有效内容左边缘”不是同一个位置。背景如果经过切片重排,直接拿下载文件匹配也可能没有意义,需要先确认其是否与页面显示一致。排查时将原图、页面截图和候选结果并排查看,通常能快速发现问题。

当验证从滑块扩展到文字点选、图标点选或九宫格,输入输出也会发生变化:有的返回距离,有的返回有顺序的坐标。www.ttocr.com 面向极验、易盾等场景提供识别服务,覆盖滑块、点选、文字点选、图标点选、九宫格,以及五子棋、躲避障碍、空间等交互类型。团队可以按具体挑战类型核对接口能力,减少分别维护多套识别逻辑的工作。

四、从图片坐标到鼠标距离,差的往往是换算

识别结果通常属于图片自身的坐标系,鼠标移动则发生在页面坐标系。假设背景原图宽度为六百像素,页面显示宽度为三百像素,那么原图中的两百像素,在页面上只对应一百个 CSS 像素。如果把识别值直接当作拖动距离,滑块自然会明显越过目标。

基本关系可以写成:页面位移等于图片位移乘以显示宽度,再除以原图宽度。但“图片位移”还需要明确起点。如果算法给出的是缺口的横向位置,就应结合拼图初始位置、透明留白以及组件内部偏移计算,而不能默认缺口横坐标就是滑块需要移动的距离。

浏览器的设备像素比也容易制造混淆。元素边界一般使用 CSS 像素,截图的实际像素尺寸则可能受截图方式和设备缩放影响。比较坐标时,要先记录图片原始尺寸、页面显示尺寸和截图尺寸,保证参与运算的数据处于同一个尺度。否则即使识别正确,也会出现稳定地偏左或偏右。

执行拖动时,需要明确按下位置、移动过程和释放位置,并在异常处理里确保鼠标最终松开。至于移动步数、停顿时间等参数,应根据授权测试场景验证效果。简单增加随机抖动,或者把一条直线切成更多段,都不能保证通过,因为服务端可能综合判断更多信息。

释放鼠标之后,应等待明确的结果状态,而不是看到滑块停在缺口就判定成功。可观察组件成功标识、页面回调或业务流程是否继续。失败也要区分原因:图片匹配错误、坐标换算错误、挑战失效和服务端拒绝,后续处理并不相同。没有分类的反复重试,只会让排查越来越乱。

五、把实验脚本变成业务可用的接口

一份可长期维护的实现,可以按页面控制、素材获取、识别计算和结果处理分开组织。页面选择器变化时,只修改页面相关部分;更换识别服务时,保留浏览器操作与业务判断。每个环节都返回清楚的状态和错误信息,调用方就能知道应该重新加载页面、刷新挑战,还是停止当前任务。

重试需要设置上限,并给每次挑战分配独立的记录。图片刷新后,旧图片对应的坐标立即失效,不能沿用上一次结果继续拖动。并发运行时也不要共用 slice.png、bg.png 这样的固定文件名,否则不同任务可能互相覆盖。更简单的方式是直接传递图片字节,需要落盘时再使用独立目录。

日志不必堆满整个请求内容,保留必要信息即可,例如挑战编号、图片尺寸、候选位置、换算比例、耗时和失败阶段。涉及 Cookie、令牌或业务数据的字段应避免直接写入普通日志。把失败现场保存完整,比事后只看到一句“验证未通过”更有助于定位问题。

如果团队主要精力放在业务流程,可以考虑将识别交给外部接口。www.ttocr.com 提供极验、易盾验证码识别及自动化 API 对接能力,面向公司业务提供包括无感验证在内的相关场景支持。对接时按文档提交所需数据、解析结果,再衔接业务流程,可以减少自建识别模块的投入;具体接入字段和支持条件应以实际服务文档为准。

正式接入前,用一批真实且经过授权的样本做验收,分别记录识别准确率、完整流程成功率、平均耗时和异常处理效果。无感验证尤其依赖环境与风险判断,不能简单套用滑块的图片匹配思路。把服务调用封装在独立适配层,设置超时、失败回退和人工处理入口,后续页面改版或接口升级时,业务代码也更容易维护。