undetected-chromedriver 是一个 Python 库,它修补 Selenium 的 ChromeDriver 以减少机器人检测信号。它处理 Chrome 版本匹配、删除 navigator.userAgent 标志并修改站点检查的其他浏览器特征。当网站尽管采取了隐形措施但仍然显示验证码时,CaptchaAI 会解决它并返回您注入到页面中的令牌。
本指南展示了如何结合使用这两种工具 - 使用 unDetected-chromedriver 进行隐形浏览,使用 CaptchaAI 处理仍然出现的任何验证码。
你需要什么
| 要求 | 细节 |
|---|---|
| CaptchaAI API 密钥 | 验证码网站 |
| Python 3.8+ | |
| Chrome浏览器 | 安装在您的系统上 |
安装依赖项:
pip install undetected-chromedriver requests
基本设置
import undetected_chromedriver as uc
import requests
import time
def create_stealth_browser():
"""Create an undetected Chrome browser instance."""
options = uc.ChromeOptions()
options.add_argument("--no-sandbox")
options.add_argument("--window-size=1920,1080")
driver = uc.Chrome(options=options)
return driver
在秘密会话中解决 reCAPTCHA v2
第 1 步:导航并提取站点密钥
API_KEY = "YOUR_API_KEY"
def extract_recaptcha_sitekey(driver):
"""Extract reCAPTCHA v2 sitekey from the page."""
try:
element = driver.find_element("css selector", "[data-sitekey]")
return element.get_attribute("data-sitekey")
except Exception:
# Try finding in iframe src
iframes = driver.find_elements("css selector", "iframe[src*='recaptcha']")
for iframe in iframes:
src = iframe.get_attribute("src")
if "k=" in src:
return src.split("k=")[1].split("&")[0]
return None
第2步:用CaptchaAI求解
def solve_recaptcha_v2(sitekey, pageurl):
"""Submit reCAPTCHA v2 to CaptchaAI and return the token."""
submit = requests.post("https://ocr.captchaai.com/in.php", data={
"key": API_KEY,
"method": "userrecaptcha",
"googlekey": sitekey,
"pageurl": pageurl,
"json": 1
}).json()
if submit.get("status") != 1:
raise RuntimeError(f"Submit error: {submit.get('request')}")
task_id = submit["request"]
time.sleep(20)
for _ in range(30):
result = requests.get("https://ocr.captchaai.com/res.php", params={
"key": API_KEY, "action": "get", "id": task_id, "json": 1
}).json()
if result.get("status") == 1:
return result["request"]
if result.get("request") != "CAPCHA_NOT_READY":
raise RuntimeError(f"Solve error: {result['request']}")
time.sleep(5)
raise TimeoutError("Solve timed out")
第三步:注入token并提交
def inject_recaptcha_token(driver, token):
"""Inject the solved token into the page and submit."""
driver.execute_script(f'''
document.getElementById("g-recaptcha-response").innerHTML = "{token}";
document.getElementById("g-recaptcha-response").style.display = "block";
''')
# If there's a callback function, trigger it
driver.execute_script(f'''
if (typeof ___grecaptcha_cfg !== 'undefined') {{
var clients = ___grecaptcha_cfg.clients;
for (var key in clients) {{
var client = clients[key];
if (client && client.callback) {{
client.callback("{token}");
}}
}}
}}
''')
完整的工作流程:使用 reCAPTCHA 登录
import undetected_chromedriver as uc
import requests
import time
API_KEY = "YOUR_API_KEY"
def solve_recaptcha(sitekey, pageurl):
submit = requests.post("https://ocr.captchaai.com/in.php", data={
"key": API_KEY, "method": "userrecaptcha",
"googlekey": sitekey, "pageurl": pageurl, "json": 1
}).json()
if submit.get("status") != 1:
raise RuntimeError(f"Submit error: {submit.get('request')}")
task_id = submit["request"]
time.sleep(20)
for _ in range(30):
result = requests.get("https://ocr.captchaai.com/res.php", params={
"key": API_KEY, "action": "get", "id": task_id, "json": 1
}).json()
if result.get("status") == 1:
return result["request"]
if result.get("request") != "CAPCHA_NOT_READY":
raise RuntimeError(f"Solve error: {result['request']}")
time.sleep(5)
raise TimeoutError("Solve timed out")
def main():
driver = uc.Chrome()
try:
# Navigate to target page
driver.get("https://staging.example.com/qa-login")
time.sleep(3)
# Fill in form fields
driver.find_element("id", "username").send_keys("user")
driver.find_element("id", "password").send_keys("pass")
# Extract sitekey
element = driver.find_element("css selector", "[data-sitekey]")
sitekey = element.get_attribute("data-sitekey")
pageurl = driver.current_url
print(f"Sitekey: {sitekey}")
# Solve CAPTCHA
token = solve_recaptcha(sitekey, pageurl)
print(f"Token: {token[:50]}...")
# Inject token
driver.execute_script(
f'document.getElementById("g-recaptcha-response").innerHTML = "{token}";'
)
# Submit form
driver.find_element("id", "submit-btn").click()
time.sleep(3)
print(f"Current URL: {driver.current_url}")
finally:
driver.quit()
if __name__ == "__main__":
main()
解决Cloudflare Turnstile
对于带有 Cloudflare Turnstile 小部件的站点,提取站点密钥并通过 Turnstile 方法解决:
def solve_turnstile(sitekey, pageurl):
submit = requests.post("https://ocr.captchaai.com/in.php", data={
"key": API_KEY, "method": "turnstile",
"sitekey": sitekey, "pageurl": pageurl, "json": 1
}).json()
if submit.get("status") != 1:
raise RuntimeError(f"Submit error: {submit.get('request')}")
task_id = submit["request"]
time.sleep(10)
for _ in range(30):
result = requests.get("https://ocr.captchaai.com/res.php", params={
"key": API_KEY, "action": "get", "id": task_id, "json": 1
}).json()
if result.get("status") == 1:
return result["request"]
if result.get("request") != "CAPCHA_NOT_READY":
raise RuntimeError(f"Solve error: {result['request']}")
time.sleep(5)
raise TimeoutError("Solve timed out")
# Inject Turnstile token
def inject_turnstile_token(driver, token):
driver.execute_script(f'''
var input = document.querySelector('[name="cf-turnstile-response"]');
if (input) input.value = "{token}";
''')
故障排除
| 问题 | 原因 | 处理方式 |
|---|---|---|
| Chrome 版本不匹配 | UC 找不到匹配的驱动程序 | 更新 Chrome 或在 uc.Chrome() 中指定 version_main |
| 验证码仍然出现 | 网站使用先进的特征采集 | 这是预期的 – 使用 CaptchaAI 解决 |
| token 提交失败 | 元素 ID 或回调错误 | 检查页面的 reCAPTCHA 实施 |
WebDriverException |
Chrome 崩溃了 | 添加 --no-sandbox 和 --disable-dev-shm-usage |
常问问题
为什么将 unDetected-chromedriver 与 CaptchaAI 一起使用?
UnDetected-chromedriver 可减少机器人检测信号,从而减少出现的验证码。当验证码仍然触发时,CaptchaAI 会解决它们。该组合的成功率最高。
未检测到的 chromedriver 在无头模式下工作吗?
是的,但无头模式可能会触发更多验证码。使用 options.add_argument("--headless=new") 来实现 Chrome 的新无头模式。
我可以将其与 Selenium Grid 一起使用吗?
是的,但未检测到的 chromedriver 需要修补本地驱动程序二进制文件。对于分布式设置,请在每个节点上预先修补驱动程序。
如果站点在 UC 的情况下检测到自动化怎么办?
有些网站使用 UC 补丁之外的高级检测。无论检测方法如何,CaptchaAI 都会处理生成的验证码。
将 CaptchaAI 添加到您的浏览器自动化
获取您的 API 密钥:验证码网站。将隐形浏览与可靠的验证码解决相结合。