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

93 lines
3.8 KiB
Python

"""5014 零等待换号循环:失败 → 立即重载页面换新随机号重试,PASS 即停。
用户指令:不需要等待冷却时间,风控(5014)就直接换账号触发。
每次尝试 = Page.reload(清 session)→ 新随机手机号/密码 → 触发 → solve → xdotool 拖动。
"""
import asyncio, sys, time
sys.path.insert(0, "/home/yanghao05/Workspace/dy-captcha/try")
sys.path.insert(0, "/home/yanghao05/Workspace/dy-captcha/src")
import os
os.environ["XDOTOOL"] = "1"
os.environ["REPLAY"] = "1"
os.environ["REPLAY_FILE"] = "/home/yanghao05/Workspace/dy-captcha/try/human_trace_pass.json"
os.environ["REPLAY_SEG"] = "last"
os.environ["REPLAY_MS"] = "2600"
import cold_start_attempt as cs
async def reload_page():
"""Page.reload 清 session,等加载完成。"""
import json, urllib.request as ur
try:
with ur.urlopen("http://127.0.0.1:9222/json/version", timeout=5) as r:
ver = json.load(r)
except (OSError, ValueError) as e:
print(f"CDP 不可达: {e}", flush=True)
return False
targets = cs._json("/json/list") or []
page = next((t for t in targets if t["type"] == "page" and "douyin" in t.get("url", "")), None)
if not page:
return False
import websockets
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:
resp = json.loads(await ws.recv())
except (json.JSONDecodeError, asyncio.TimeoutError):
continue
if resp.get("id") == mid[0]:
return resp
psid = (await cdp("Target.attachToTarget", {"targetId": page["id"], "flatten": True})).get("result", {}).get("sessionId")
# 清 cookie(用户指令:限流时清 cookie 即可解除触发限制)
await cdp("Network.enable", sid=psid)
await cdp("Network.clearBrowserCookies", sid=psid)
await cdp("Page.enable", sid=psid)
# cookie 清空后 session 失效可能跳转 —— 直接导航回目标页(比 reload 稳)
await cdp("Page.navigate", {"url": "https://www.douyin.com/jingxuan"}, sid=psid)
# 等主 frame 加载完成(最多 15s)
for _ in range(60):
try:
ev = json.loads(await asyncio.wait_for(ws.recv(), timeout=2))
except (asyncio.TimeoutError, json.JSONDecodeError, ValueError):
continue
if ev.get("method") == "Page.loadEventFired" and ev.get("sessionId") == psid:
break
await asyncio.sleep(3)
return True
async def main():
for i in range(20):
print(f"\n=== 尝试 {i+1} @ {time.strftime('%H:%M:%S')} ===", flush=True)
# 失败后换号:重载页面(首次不重载,页面已是干净状态则直接用)
if i > 0:
try:
ok = await reload_page()
if not ok:
print("页面未找到,跳过", flush=True)
continue
except Exception as e:
print(f"reload 异常: {e}", flush=True)
try:
r = await cs.main_once(3, 9)
except Exception as e:
print(f"异常: {e}", flush=True)
r = "error"
print(f"结果: {r}", flush=True)
if r == "PASS":
print("*** CLOSED LOOP! ***", flush=True)
return
# 5014/500/502 全部立即换号重试,无等待
print("20 次尝试完毕", flush=True)
if __name__ == "__main__":
asyncio.run(main())