Repository navigation
Expand file tree
/
Copy pathtencent.py
More file actions
113 lines (100 loc) · 3.77 KB
/
Copy pathtencent.py
File metadata and controls
113 lines (100 loc) · 3.77 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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
"""Solve Tencent CAPTCHA on a user-configured page."""
import os
import time
from captcha_solver_api.tasks import TencentTaskProxyless
from common import create_client, logged_example, required_env, wait_for_css
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from seleniumbase import Driver
TENCENT_INTERCEPT_SCRIPT = r"""
(() => {
const records = new Map();
const wrappers = new WeakMap();
let constructor;
let sequence = 0;
const wrap = (Original, scriptUrl) => {
if (typeof Original !== 'function') return Original;
if (wrappers.has(Original)) return wrappers.get(Original);
const Wrapped = new Proxy(Original, {
construct(Target, args, newTarget) {
const offset = typeof args[1] === 'function' ? 0 : 1;
const appId = args[offset];
const callback = args[offset + 1];
if (!appId || typeof callback !== 'function') {
return Reflect.construct(Target, args, newTarget);
}
const id = `tencent-${++sequence}`;
const params = {
id,
websiteURL: location.href,
appId: String(appId),
captchaScript: scriptUrl || [...document.scripts]
.map(script => script.src)
.find(src => /\/TCaptcha-global\.js(?:\?|$)/i.test(src))
};
const nativeArgs = [...args];
nativeArgs[offset + 1] = () => {};
const instance = Reflect.construct(Target, nativeArgs, newTarget);
instance.show = () => {};
records.set(id, {params, callback, submitted: false});
return instance;
}
});
wrappers.set(Original, Wrapped);
wrappers.set(Wrapped, Wrapped);
return Wrapped;
};
Object.defineProperty(window, '__captchaSolverTencent', {value: {
pending: () => [...records.values()]
.filter(record => !record.submitted)
.map(record => record.params),
submit(id, solution) {
const record = records.get(id);
if (!record || record.submitted) throw new Error('Tencent CAPTCHA callback is missing.');
record.submitted = true;
record.callback(solution);
}
}});
const existing = window.TencentCaptcha;
Object.defineProperty(window, 'TencentCaptcha', {
configurable: true,
enumerable: true,
get: () => constructor,
set: value => { constructor = wrap(value, document.currentScript?.src); }
});
if (existing) window.TencentCaptcha = existing;
})();
"""
@logged_example
def main() -> None:
target_url = required_env("TARGET_URL")
success_selector = required_env("TENCENT_SUCCESS_SELECTOR")
with Driver(browser="chrome", headless=False) as driver, create_client() as client:
driver.execute_cdp_cmd(
"Page.addScriptToEvaluateOnNewDocument", {"source": TENCENT_INTERCEPT_SCRIPT}
)
driver.get(target_url)
trigger_selector = os.getenv("TENCENT_TRIGGER_SELECTOR")
if trigger_selector:
WebDriverWait(driver, 30).until(
EC.element_to_be_clickable((By.CSS_SELECTOR, trigger_selector))
).click()
params = WebDriverWait(driver, 30).until(
lambda browser: browser.execute_script(
"return window.__captchaSolverTencent?.pending()[0] || null"
)
)
record_id = params.pop("id")
solution = client.solve(TencentTaskProxyless(**params))
driver.execute_script(
"window.__captchaSolverTencent.submit(arguments[0], arguments[1])",
record_id,
solution,
)
message = wait_for_css(driver, success_selector)
WebDriverWait(driver, 30).until(EC.visibility_of(message))
print(message.text)
time.sleep(5)
if __name__ == "__main__":
main()