Files
douyin-captcha/try/trace_watch.py
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

78 lines
3.0 KiB
Python
Raw 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.
"""真人拖动轨迹监视器:等 rmc iframe 出现后 attach,每 0.5s 快照
window.__dragTrace / __lastVerify 到 /tmpiframe 销毁(验证通过)后保留最后快照退出。"""
import asyncio, json, time, urllib.request as ur
import websockets
def _json(path):
try:
with ur.urlopen(f"http://127.0.0.1:9222{path}", timeout=5) as r:
return json.load(r)
except (OSError, ValueError):
return None
async def main():
ver = _json("/json/version")
if not ver or not ver.get("webSocketDebuggerUrl"):
print("CDP 不可达,退出")
return
# 等待验证码 iframe 出现(最多 180s
ifr = None
for _ in range(60):
targets = _json("/json/list") or []
ifr = next((t for t in targets if "rmc.bytedance.com" in t.get("url", "")), None)
if ifr:
break
await asyncio.sleep(3)
if not ifr:
print("无 iframe,退出")
return
async with websockets.connect(ver["webSocketDebuggerUrl"], max_size=64 * 1024 * 1024) as ws:
mid = [0]
async def cdp(method, params=None, sid=None):
mid[0] += 1
m = {"id": mid[0], "method": method, "params": params or {}}
if sid:
m["sessionId"] = sid
await ws.send(json.dumps(m))
while True:
try:
r = json.loads(await ws.recv())
except (json.JSONDecodeError, asyncio.TimeoutError):
continue
if r.get("id") == mid[0]:
if "error" in r:
raise RuntimeError(str(r["error"]))
return r.get("result", {})
isid = (await cdp("Target.attachToTarget", {"targetId": ifr["id"], "flatten": True}))["sessionId"]
await cdp("Runtime.enable", sid=isid)
print("trace_watch 就绪", flush=True)
last_len = -1
while True:
try:
r = await cdp("Runtime.evaluate", {
"expression": "JSON.stringify({n:(window.__dragTrace||[]).length,"
"trace:window.__dragTrace||null,v:window.__lastVerify||null})",
"returnByValue": True}, sid=isid)
val = r.get("result", {}).get("value")
if val:
d = json.loads(val)
if d["n"] != last_len:
last_len = d["n"]
with open("/tmp/trace_snap.json", "w") as f:
json.dump(d, f)
if d["v"]:
with open("/tmp/verify_snap.txt", "w") as f:
f.write(d["v"])
print(f"[{time.strftime('%H:%M:%S')}] {d['n']} 事件", flush=True)
await asyncio.sleep(0.5)
except (RuntimeError, websockets.exceptions.ConnectionClosed, OSError):
print("iframe 已销毁,保留最后快照退出", flush=True)
return
asyncio.run(main())