forked from skernelx/tavily-key-generator
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbrowser_solver.py
More file actions
84 lines (75 loc) · 2.45 KB
/
browser_solver.py
File metadata and controls
84 lines (75 loc) · 2.45 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#!/usr/bin/env python3
"""
浏览器原生 Turnstile 验证码解决器(免费)
通过在真实浏览器中点击 Turnstile 复选框来通过验证
"""
import time
def solve_turnstile_browser(page, timeout=30):
"""
在浏览器中直接解决 Turnstile 验证
1. 找到 Turnstile iframe
2. 点击复选框
3. 等待验证通过(cf-turnstile-response 填充)
返回 True/False
"""
print("🔐 [免费模式] 尝试浏览器内解决 Turnstile...")
# 等待 Turnstile iframe 出现
try:
page.wait_for_selector(
'iframe[src*="challenges.cloudflare.com"]',
timeout=8000,
)
except Exception:
print("✅ 未检测到 Turnstile iframe,跳过")
return True
time.sleep(2)
# 尝试在 iframe 中点击复选框
clicked = False
for frame in page.frames:
if "challenges.cloudflare.com" not in frame.url:
continue
try:
# Turnstile 复选框常见选择器
selectors = [
'input[type="checkbox"]',
'[role="checkbox"]',
'.cb-lb',
'#challenge-stage input',
]
for sel in selectors:
try:
cb = frame.wait_for_selector(sel, timeout=3000)
if cb:
cb.click()
print(f"✅ 已点击 Turnstile 复选框: {sel}")
clicked = True
break
except Exception:
continue
except Exception:
continue
if clicked:
break
if not clicked:
print("⚠️ 未找到可点击的复选框,等待自动验证...")
# 等待 cf-turnstile-response 被填充(验证通过的标志)
try:
page.wait_for_function(
"""
() => {
const fields = document.querySelectorAll(
'[name="cf-turnstile-response"], [name="cf-chl-turnstile-response"], [name="captcha"]'
);
for (const f of fields) {
if (f.value && f.value.length > 50) return true;
}
return false;
}
""",
timeout=timeout * 1000,
)
print("✅ Turnstile 验证已通过!")
return True
except Exception:
print("❌ Turnstile 验证超时")
return False