# 滑块验证码自动化文档(tmp_captcha_test7) > 2026-09-23 版。数据全部来自 `../guiji_new` 真人录制的 19 条轨迹(1220x2712 屏幕设备,getevent 采集)。 ## 1. 流程总览 淘宝/饿了么拼图滑块验证码的解决流程(`solve_slider(driver, sx=None)`): ``` 按下滑块 → 静默停顿(60~120ms) → 右滑到折返点(1060~1105px, 按屏宽缩放) [真人右段速度模板] → 等待幕布展开 + 轮询确认滑块到右端(静默) → 截取展开后的拼图区 → 打码API(jfbym type=20226)拿 gap → 折返点停顿 = API耗时 + 0.15~0.35s → 折回拖到 gap [分桶锚点链速度剖面] → 轮询确认滑块中心到位(静默) → 释放前慢速微调: 幕布左边缘量出真实缺口 vs 当前位置, 差3~12px时1px/30~90ms慢慢挪过去 → 静默停顿(40~120ms) → 抬起手指 → OCR 验证结果, 归档成功/失败截图+轨迹JSON ``` ## 2. 文件清单 | 文件 | 说明 | |---|---| | `tmp_captcha_test7.py` | 当前主版本(全面真人化校准版) | | `tmp_captcha_test6.py` | 旧版(生产兜底,参数已过时) | | `nine_grid.py` | 九宫格验证码(另一类验证码) | | `get_guiji.py` | 真人轨迹录制工具(adb getevent,输出 JSON+PNG 到 `guiji_new/`) | | `run_test7.py` | 编码免疫启动器(纯 ASCII,自动识别 UTF-8/GBK,防 PyCharm 存 GBK 后 Python 报编码错) | | `../guiji_new/` | **真人轨迹模板库**(19 条,必需——缺失时右滑退回匀速模式) | | `../detect_slider_button.py` | 橙色滑块按钮检测 | | `../detect_captcha_edge.py` | 幕布(橙色覆盖层)左边缘检测 = 真实缺口位置 | ## 3. 轨迹生成核心 ### 3.1 右滑段(按下 → 折返点) - 直接复用真人右段速度模板(`_normalize_velocity_template(points, "right")`):爆发起步(峰值 4~7 px/ms)→ 长弧刹车 → 末端爬行 - 模板曲线按 **7~9ms 均匀时间网格重采样**(主机注入下限),时长按距离缩放后钳位 0.30~1.20s - Y 漂移:`(-0.02, +0.10) × 距离`(真人实测均值 +3.6% 向下) - 折返点:`RIGHT_END_RANGE_1220 = (1060, 1105)`(按屏宽缩放,真人集中在 1023~1109) ### 3.2 折回段(折返点 → 缺口)——按距离分三档 真人 19 条按距离分桶实测: | 档 | 距离 | 巡航速度(px/ms) | 特征 | |---|---|---|---| | 短折 | <450×scale | 0.45~0.9 | 全程较慢,减速区 55% 路程起 | | 中折 | 450~600×scale | 0.7~1.3 | 减速起点 150px(缩放后) | | 长折 | >600×scale | **1.6~2.4** | 高速巡航 + 超长慢尾 | - **锚点链**(距缺口 px, 速度/巡航)对数线性插值,所有距离按屏幕宽度 `scale = W/1220` 缩放: | 档 | 锚点链(1220 基准,运行时×scale) | |---|---| | 长折 | (150,1.0) (100,0.40) (70,0.25) (50,0.16) (30,0.08) (20,0.04) (10,0.02) (5,0.01) | | 中折 | (150,1.0) (100,0.26) (50,0.15) (20,0.10) (10,0.07) (5,0.01) | | 短折 | (dec_start,1.0) (100,0.45) (50,0.28) (20,0.12) (10,0.04) (5,0.02) | - 减速起点:`dec_start = 150×scale`(≥250px),短折 `max(80×scale, 0.55×距离)` - 起步加速:前 20~30% 路程内从 25% 平滑升到巡航峰值(真人 10~40% 达峰) - 事件采样:**10~14ms** 时间步进(真人 4.4ms 中位,但主机注入稳定下限约 10ms),巡航段偶发 30~80ms 微犹豫(1.5%,最后 15% 路程不插) - Y 漂移:`triangular(0.20, 0.38, 0.30) × 距离` 全部向下,上限 `RETURN_END_DRIFT_LIMIT_1220=240×scale`(真人实测 0.19~0.39,90~239px) ### 3.3 平滑化:大跨步拆分 主机 10~14ms 采样下高速段单步可达 40px+(视觉"加速猛")。`_subdivide_track`:步长 >16px 的段按时间表对半拆成小步(子步间隔 ≥3.5ms)。改后右滑最大步长 ~20px、折回 ~15px。 ### 3.4 停顿参数(真人 19 条实测) | 停顿 | 真人 | 代码 | |---|---|---| | 初始按压 | 中位 75ms(62~122) | 60~120ms | | 折返点 | 中位 0.2~0.6s(37~1014ms) | API 返回后 +0.15~0.35s(API 必须在此期间完成,实测 0.6~2.0s,故无法完全对齐真人) | | 释放前 | 中位 43ms | 40~120ms | ### 3.5 释放前微调(gap 校准) 打码 API 的 gap 有 ±几 px 随机误差。折回到位后:截图检测**幕布左边缘**(=真实缺口),差 3~12px 时 1px/30~90ms 慢速挪过去(差 ≤2px 跳过、>12px 判为检测错误跳过)。已实测把 +12px 的落点误差拉回缺口。 ## 4. 发送层(主机 → 设备) - 通道:uiautomator2 ATX agent 9008 端口 keep-alive HTTP(TouchPipe),send95≈0.3ms - **Windows 定时器 `timeBeginPeriod(1)`**:默认 15.6ms 精度会让 sleep(4~14ms) 随机超睡 40~360ms → 卡顿跳点 - 等待策略:sleep 到 deadline 前 1ms + 忙等补足 - **重同步机制**:落后 >10ms 时不丢点,把剩余时间表整体后移全部滞后量(丢点=轨迹瞬移"飞过去";后移=轻微变慢无瞬移)。一次卡顿一次重同步,无级联 - 开跑前 `计时自检`:100 次 12ms sleep 测超睡率,坏窗口(杀毒/负载尖峰)提前告警 ## 5. 生产接入 - 入口:`main1.py` 的 `_handle_captcha`(饿了么闪购主入口 V1,最多重试 5 次) ```python try: from yzm.tmp_captcha_test7 import solve_slider # 全面真人化版 except ImportError: from yzm.tmp_captcha_test6 import solve_slider # 旧版兜底 ``` - 部署到生产机需同步:`yzm/tmp_captcha_test7.py` + **`guiji_new/` 整个目录** + `detect_slider_button.py` + `detect_captcha_edge.py` - 生产机若目录结构与本机不同(如 `D:\drug\sg\yzm`),注意 `tmp_captcha_test7.py` 内 `sys.path.insert` 与 `GUIJI_ROOT` 两个路径解析 ## 6. 归档与调试 - 归档:`image/test7_image/{success,failure}/{日期}/{设备}_{时间}_track.json/.png/_b.png` - `phase_timing` 关键字段: - `right_ms/return_ms`:两段实际耗时;`resyncs/shifted_ms`:重同步次数与累计后移(0 为理想) - `hold_ms`:折返点总停顿(含 settle+确认+API) - `micro_adjust_px/ms`:释放前微调量(None=旧版代码) - `release_pause_ms`:释放前静默停顿 - `return_center` vs `gap`:落点误差(>8px 需关注) - 日志关注:`计时自检`(坏窗口告警)、`微调:` 行、`远端停顿=`(应为 ~1000~2400ms) ## 7. 通过率与已知边界 - 旧基线 ~50%:**淘宝滑块本身有约一半的随机拒绝率**(真人拖动也会"请重试"),落点完美+轨迹对齐仍失败的样本占失败样本 58%——轨迹不再是主要变量 - 2026-09-23 生产数据:全天 **74%**(29/39),12:30 后 **100%**(7/7,样本小) - 主机计时在负载窗口(杀毒/磁盘/USB 抢占)不可靠——计时自检可提前发现;彻底方案是**设备端播放器**(app_process 跑 Java,用 `InputManager.injectInputEvent` + `SystemClock` 在手机上按时间表注入,与主机负载无关;设备无 root 也可行,方案已设计未实施) - 注入端只能发整数像素坐标(injectInputEvent 限制),尾段爬行的亚像素级更新无法复刻,这是 API 限制下最平滑形态 ## 8. 常用调参位置(tmp_captcha_test7.py 顶部常量区) | 想调什么 | 改哪里 | |---|---| | 折返点范围 | `RIGHT_END_RANGE_1220` | | 右滑时长/速度 | `RIGHT_TEMPLATE_DURATION_RANGE`、右段模板重采样间隔 `0.007~0.009` | | 折回巡航速度 | `_build_human_return_track` 内三档 `v_peak` | | 折回减速形状 | 三档 `chain` 锚点链 + `dec_start` | | 事件密度 | 折回采样 `10.0~14.0` ms | | 折返点停顿时长 | `solve_slider` 内 `time.sleep(random.uniform(0.15, 0.35))`(回退旧值见注释) | | 微调幅度 | `solve_slider` 内 `2 < abs(micro_px) <= 12` | | Y 漂移 | `RETURN_END_DRIFT_LIMIT_1220`、`end_ratio` | | 步长拆分 | `_subdivide_track(..., max_step_px=16.0)` | ## 9. 编码注意事项 PyCharm 曾多次把文件以 GBK 保存导致 `Non-UTF-8 code ... no encoding declared`。`tmp_captcha_test7.py` 第 1 行有 `# -*- coding: utf-8 -*-` 声明;如再出现乱码报错,在 PyCharm 中关掉文件标签重新打开(丢弃旧缓冲区),并用 `run_test7.py` 启动可免疫编码问题。