Files
杨豪 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

75 lines
3.0 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 经验:拟人拖动路径生成算法(反检测三要素)
> 场景:验证码行为风控会检测拖动轨迹的「机器特征」。人手拖动的轨迹与
> CDP `Input.dispatchMouseEvent` 生成的匀速直线完全不同。
> 代码:`try/human_drag.py`(`gen_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/ms`、`v_min ≈ 0.001`
(慢两个数量级),与匀速(速度方差≈0)完全可区分。
### 3. 不能一次到位 → 过冲-回拉-瞄准
```
阶段1 主冲程 → 目标 + 过冲量(3~9px 随机)
阶段2 回拉 → 目标 - 欠量(0.5~2.5px)
阶段3 微调 → 1~2 小步逼近精确目标,每步 15ms+
```
人类视觉反馈回路的标配:先冲过头,再修正。位移曲线 x-t 上
可见明显的「超过目标 → 拉回 → 精确落点」三段形态。
## 用法
```python
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 --plot` →
`src/out/human_drag_path.png`(三种距离的轨迹)、`src/out/human_drag_xt.png`(x-t 曲线)。
## 可调参数(按需)
- 短距离(<100px):弓形幅值降到 ±8、过冲 ×0.3(小拖距人不甩)
- `duration`:默认按距离自估算 0.6-1.4s;拖钮场景可传 `duration=800` 固定
- 未做:轨迹级鼠标事件 hook 采集真人样本对拍(当前参数为文献常识值,
如需过高级风控,用 CDP 录制 10 条真人轨迹做分布拟合替换)