Files
regplatformm/cmd/grpctest/get_turnstile_token.py
xiaolajiaoyyds 6f71df4849 Initial open-source release
多平台账号批量注册系统,支持 OpenAI / Grok / Kiro / Gemini 平台的全自动注册。

Features:
- 用户名/密码注册登录(首个用户自动管理员)
- JWT 认证 + bcrypt 密码加密
- 积分系统与多用户管理
- HuggingFace Space 弹性 Worker 节点管理
- Cloudflare Worker 负载均衡
- 实时日志推送(SSE/WebSocket)
- 管理后台(用户管理、系统设置、代理池、卡池)

Tech Stack: Go 1.25 / Gin / GORM / PostgreSQL / Vue 3 / Vite / TailwindCSS
2026-03-22 03:44:42 +08:00

161 lines
6.5 KiB
Python

"""
用 Camoufox 提取 accounts.x.ai 的 Turnstile token
策略:在 accounts.x.ai 页面上直接注入 Turnstile widget 获取 token
"""
import asyncio
import sys
import time
from camoufox.async_api import AsyncCamoufox
async def get_turnstile_token(timeout=45):
print(f"[*] 启动 Camoufox (headless)...", flush=True)
start = time.time()
async with AsyncCamoufox(headless=True) as browser:
page = await browser.new_page()
print("[*] 加载 accounts.x.ai ...", flush=True)
try:
await page.goto("https://accounts.x.ai/sign-up", wait_until="domcontentloaded", timeout=30000)
print(f"[+] 页面加载完成 ({time.time()-start:.1f}s)", flush=True)
except Exception as e:
print(f"[!] 页面加载异常: {e}", flush=True)
# 策略 1: 点击 "Sign up with email",让 React 组件加载 Turnstile
print("[*] 策略1: 点击 'Sign up with email'...", flush=True)
try:
btn = await page.query_selector('text=Sign up with email')
if btn:
await btn.click()
print("[+] 点击成功", flush=True)
await asyncio.sleep(2)
else:
print("[-] 未找到 'Sign up with email' 按钮", flush=True)
except Exception as e:
print(f"[-] 点击失败: {e}", flush=True)
# 截图看看当前状态
await page.screenshot(path="/tmp/turnstile_debug2.png")
print("[*] 截图已保存: /tmp/turnstile_debug2.png", flush=True)
# 策略 2: 直接在页面注入 Turnstile widget
print("[*] 策略2: 注入 Turnstile widget...", flush=True)
await page.evaluate("""() => {
window.__capturedToken = null;
// 创建容器
const container = document.createElement('div');
container.id = 'injected-turnstile';
container.style.position = 'fixed';
container.style.bottom = '0';
container.style.right = '0';
container.style.zIndex = '99999';
document.body.appendChild(container);
// 加载 Turnstile JS
const script = document.createElement('script');
script.src = 'https://challenges.cloudflare.com/turnstile/v0/api.js?onload=__onTurnstileReady';
script.async = true;
window.__onTurnstileReady = function() {
console.log('[Inject] Turnstile JS loaded, rendering widget...');
try {
turnstile.render('#injected-turnstile', {
sitekey: '0x4AAAAAAAhr9JGVDZbrZOo0',
callback: function(token) {
console.log('[Inject] Token received!');
window.__capturedToken = token;
},
'error-callback': function(err) {
console.log('[Inject] Turnstile error: ' + err);
window.__turnstileError = err;
},
'expired-callback': function() {
console.log('[Inject] Token expired');
},
theme: 'light',
size: 'invisible',
'response-field': false,
});
console.log('[Inject] Widget rendered');
} catch(e) {
console.log('[Inject] Render error: ' + e);
window.__turnstileError = e.toString();
}
};
document.head.appendChild(script);
}""")
# 同时也监控页面上已有的 Turnstile(如果有的话)
# 以及监控任何 iframe 中的 Turnstile response
print("[*] 等待 Turnstile token...", flush=True)
for i in range(timeout):
# 检查注入的 token
token = await page.evaluate("() => window.__capturedToken")
if token:
elapsed = time.time() - start
print(f"[+] Token 获取成功 (注入方式)! ({elapsed:.1f}s)", flush=True)
print(f"[+] Token 长度: {len(token)}", flush=True)
print(f"TOKEN:{token}", flush=True)
return token
# 检查 hidden input
token2 = await page.evaluate("""() => {
const inputs = document.querySelectorAll('[name="cf-turnstile-response"]');
for (const input of inputs) {
if (input.value) return input.value;
}
return null;
}""")
if token2:
elapsed = time.time() - start
print(f"[+] Token 获取成功 (hidden input)! ({elapsed:.1f}s)", flush=True)
print(f"TOKEN:{token2}", flush=True)
return token2
# 检查错误
error = await page.evaluate("() => window.__turnstileError")
if error and i > 5:
print(f"[-] Turnstile 错误: {error}", flush=True)
break
if i % 5 == 0 and i > 0:
print(f"[*] 等待中... ({i}s)", flush=True)
# 检查 Turnstile iframe
frames = page.frames
for f in frames:
if 'challenges.cloudflare.com' in f.url:
print(f" 发现 Turnstile iframe: {f.url[:80]}", flush=True)
await asyncio.sleep(1)
# 超时
print(f"[-] Token 获取超时 ({timeout}s)", flush=True)
await page.screenshot(path="/tmp/turnstile_debug3.png")
print(" 截图已保存: /tmp/turnstile_debug3.png", flush=True)
# 打印 Turnstile 相关元素
info = await page.evaluate("""() => {
const result = {};
result.turnstileExists = typeof window.turnstile !== 'undefined';
result.iframes = Array.from(document.querySelectorAll('iframe')).map(f => f.src);
result.inputs = Array.from(document.querySelectorAll('input[type=hidden]')).map(i => ({name: i.name, hasValue: !!i.value}));
result.injectedDiv = !!document.getElementById('injected-turnstile');
result.injectedDivHTML = document.getElementById('injected-turnstile')?.innerHTML?.substring(0, 200);
return result;
}""")
print(f" 调试信息: {info}", flush=True)
return None
if __name__ == "__main__":
token = asyncio.run(get_turnstile_token(timeout=40))
if token:
sys.exit(0)
else:
sys.exit(1)