Files
douyin-captcha/docs/browser-automation/human-drag-path.md
T
杨豪 cae37465d2 feat: 尺度精修上线,首次机器 PASS(live_160548 s=1.0375)
- method_l_shape: OK 候选尺度 ±0.0375 精修(步长 0.0125 + ±6px 窗口),
  GT live_165204 Δ 179→176(真人 177),离线 9/10 保持
- 插桩 JSON.stringify 捕获 SDK 日志明文;指针 probe 排除 coalesced/pressure
- 拖动不跟手指标作废:post_pos 晚于 SDK 重置滑块,鼠标事件流始终完整
- 剩余 VerifyErr = 候选整体选错(视觉确证),方向:多候选质量评估
- docs: experiments/solution/retrospective 同步收尾
2026-09-15 16:20:05 +08:00

3.0 KiB
Raw Blame History

经验:拟人拖动路径生成算法(反检测三要素)

场景:验证码行为风控会检测拖动轨迹的「机器特征」。人手拖动的轨迹与 CDP Input.dispatchMouseEvent 生成的匀速直线完全不同。 代码:try/human_drag.pygen_human_path(distance_px) → 增量事件序列)。

三要素(用户需求 → 实现机制)

1. 不能是直线 → 贝塞尔弓形骨架 + 高斯抖动

主冲程路径 = 三次贝塞尔 P0(0,0) → P3(过冲点)
             P1/P2 控制点带 y 轴弓形偏移(±8~14px,随机方向)
每步叠加   = gauss 抖动(x: σ≈0.8, y: σ≈1.1)
抖动幅值随速度变化:中段速度快 → 手更不稳(σ 放大)

弓形是关键:不是噪声围绕着直线,而是整体轨迹带自然弧度(人手腕转动)。 y 轴全程摆动 ±5px 左右,终点收敛回 0。

2. 不能匀速 → 三段速度结构

主冲程 (55-70% 时长)ease-in-out(加速→巡航→减速),14-22ms/步
回拉   (15-22% 时长)ease-out 快速回退
微调   (剩余时长)   :步长递减的小步逼近 + 末尾 40-120ms 停顿确认

速度统计上呈「快-慢-停」节奏,v_max ≈ 0.5-0.95 px/msv_min ≈ 0.001 (慢两个数量级),与匀速(速度方差≈0)完全可区分。

3. 不能一次到位 → 过冲-回拉-瞄准

阶段1 主冲程 → 目标 + 过冲量(3~9px 随机)
阶段2 回拉   → 目标 - 欠量(0.5~2.5px)
阶段3 微调   → 1~2 小步逼近精确目标,每步 15ms+

人类视觉反馈回路的标配:先冲过头,再修正。位移曲线 x-t 上 可见明显的「超过目标 → 拉回 → 精确落点」三段形态。

用法

from human_drag import gen_human_path, path_stats

pts = gen_human_path(distance_px=227.9, seed=42)  # seed 可复现
# pts = [(dx, dy, dt_ms), ...] 相对上一点增量
for dx, dy, dt in pts:
    cur_x += dx; cur_y += dy
    cdp("Input.dispatchMouseEvent", type="mouseMoved", x=cur_x, y=cur_y,
        button="left", buttons=1)
    time.sleep(dt / 1000)

拖动距离换算:solve 的 distance_px 是原图(552 宽)坐标, 乘缩放系数 UI宽/552(如 340/552≈0.616)得 UI 像素。

自检(已内置)

python try/human_drag.py 断言五项:终点精确(<0.5px)、时长 0.4-2.5s、 速度起伏(vmax > vmin×5)、y 摆动(>2px)、存在回拉(x 序列非单调)。 10 样本联合烟测(solve → 换算 → 路径)全通过。

可视化:python try/human_drag.py --plotsrc/out/human_drag_path.png(三种距离的轨迹)、src/out/human_drag_xt.pngx-t 曲线)。

可调参数(按需)

  • 短距离(<100px):弓形幅值降到 ±8、过冲 ×0.3(小拖距人不甩)
  • duration:默认按距离自估算 0.6-1.4s;拖钮场景可传 duration=800 固定
  • 未做:轨迹级鼠标事件 hook 采集真人样本对拍(当前参数为文献常识值, 如需过高级风控,用 CDP 录制 10 条真人轨迹做分布拟合替换)