Selenium 可以自动化浏览器交互,但验证码却阻止了它。 CaptchaAI 的 API 在外部解决验证码问题,而 Selenium 处理浏览器 - 您提取验证码参数,将它们发送到 API,然后注入返回的令牌。
要求
| 要求 | 细节 |
|---|---|
| Python 3.7+ | 安装了 pip |
| 硒 | pip install selenium |
| Chrome + Chrome 驱动程序 | 配套版本 |
| 要求 | pip install requests |
| CaptchaAI API 密钥 | 从验证码网站 |
它是如何运作的
- Selenium加载目标页面
- 您的脚本从页面 DOM 中提取 CAPTCHA 站点密钥
- CaptchaAI 使用站点密钥和页面 URL 解决验证码
- 您的脚本将token 提交页面并提交表单
验证码由 CaptchaAI 在服务器端解决 - Selenium 从不直接与验证码小部件交互。
第 1 步:设置 Selenium
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
options = Options()
options.add_argument("--no-sandbox")
options.add_argument("user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36")
driver = webdriver.Chrome(options=options)
AutomationControlled 标志有助于避免基本的机器人检测。为了获得更强的标准配置,请添加:
options.add_experimental_option("excludeSwitches", ["enable-automation"])
options.add_experimental_option("useAutomationExtension", False)
第 2 步:创建验证码求解器
import requests
import time
API_KEY = "YOUR_API_KEY"
def solve_recaptcha_v2(site_key, page_url):
"""Solve reCAPTCHA v2 using CaptchaAI API."""
resp = requests.get("https://ocr.captchaai.com/in.php", params={
"key": API_KEY,
"method": "userrecaptcha",
"googlekey": site_key,
"pageurl": page_url
})
if not resp.text.startswith("OK|"):
raise Exception(f"Submit failed: {resp.text}")
task_id = resp.text.split("|")[1]
for _ in range(60):
time.sleep(5)
result = requests.get("https://ocr.captchaai.com/res.php", params={
"key": API_KEY,
"action": "get",
"id": task_id
})
if result.text == "CAPCHA_NOT_READY":
continue
if result.text.startswith("OK|"):
return result.text.split("|")[1]
raise Exception(f"Solve failed: {result.text}")
raise TimeoutError("CAPTCHA solve timed out")
第三步:提取站点密钥并解决
# Navigate to the target page
driver.get("https://staging.example.com/qa-login")
# Wait for the reCAPTCHA to load
wait = WebDriverWait(driver, 10)
recaptcha = wait.until(
EC.presence_of_element_located((By.CLASS_NAME, "g-recaptcha"))
)
# Extract the site key
site_key = recaptcha.get_attribute("data-sitekey")
page_url = driver.current_url
print(f"Site key: {site_key}")
print(f"Page URL: {page_url}")
# Solve the CAPTCHA
token = solve_recaptcha_v2(site_key, page_url)
print(f"Token received: {token[:50]}...")
第四步:注入Token并提交
# Inject the token into the reCAPTCHA response field
driver.execute_script(f"""
document.getElementById('g-recaptcha-response').innerHTML = '{token}';
document.getElementById('g-recaptcha-response').style.display = '';
""")
# If the form uses a callback function, trigger it
driver.execute_script(f"""
if (typeof ___grecaptcha_cfg !== 'undefined') {{
Object.keys(___grecaptcha_cfg.clients).forEach(function(key) {{
var client = ___grecaptcha_cfg.clients[key];
if (client.callback) client.callback('{token}');
}});
}}
""")
# Submit the form
driver.find_element(By.CSS_SELECTOR, "form").submit()
# Wait for navigation
wait.until(EC.url_changes(page_url))
print(f"Success! Now on: {driver.current_url}")
完整的工作示例
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import requests
import time
API_KEY = "YOUR_API_KEY"
def solve_recaptcha_v2(site_key, page_url):
resp = requests.get("https://ocr.captchaai.com/in.php", params={
"key": API_KEY,
"method": "userrecaptcha",
"googlekey": site_key,
"pageurl": page_url
})
if not resp.text.startswith("OK|"):
raise Exception(f"Submit failed: {resp.text}")
task_id = resp.text.split("|")[1]
for _ in range(60):
time.sleep(5)
result = requests.get("https://ocr.captchaai.com/res.php", params={
"key": API_KEY, "action": "get", "id": task_id
})
if result.text == "CAPCHA_NOT_READY":
continue
if result.text.startswith("OK|"):
return result.text.split("|")[1]
raise Exception(f"Solve failed: {result.text}")
raise TimeoutError("Timed out")
def main():
options = Options()
options.add_argument("--no-sandbox")
driver = webdriver.Chrome(options=options)
try:
driver.get("https://staging.example.com/qa-login")
wait = WebDriverWait(driver, 10)
# Extract site key
recaptcha = wait.until(
EC.presence_of_element_located((By.CLASS_NAME, "g-recaptcha"))
)
site_key = recaptcha.get_attribute("data-sitekey")
# Solve
token = solve_recaptcha_v2(site_key, driver.current_url)
# Inject and submit
driver.execute_script(
f"document.getElementById('g-recaptcha-response').innerHTML = '{token}';"
)
driver.find_element(By.CSS_SELECTOR, "form").submit()
wait.until(EC.url_changes(driver.current_url))
print("Login successful!")
finally:
driver.quit()
if __name__ == "__main__":
main()
处理不同的验证码类型
reCAPTCHA v3
def solve_recaptcha_v3(site_key, page_url, action="verify"):
resp = requests.get("https://ocr.captchaai.com/in.php", params={
"key": API_KEY,
"method": "userrecaptcha",
"googlekey": site_key,
"pageurl": page_url,
"version": "v3",
"action": action
})
task_id = resp.text.split("|")[1]
# ... same polling logic
Cloudflare Turnstile
def solve_turnstile(site_key, page_url):
resp = requests.get("https://ocr.captchaai.com/in.php", params={
"key": API_KEY,
"method": "turnstile",
"sitekey": site_key,
"pageurl": page_url
})
task_id = resp.text.split("|")[1]
# ... same polling logic
故障排除
| 问题 | 原因 | 处理方式 |
|---|---|---|
| 令牌被拒绝 | 提交前令牌已过期 | 120秒内注入并提交 |
| 找不到站点密钥 | 验证码动态加载 | 添加 WebDriverWait 更长的超时时间 |
NoSuchElementException |
选择器错误 | 检查页面以找到正确的元素 |
| ChromeDriver版本不匹配 | Chrome 已更新 | 下载匹配的 ChromeDriver 版本 |
| 尽管令牌正确,仍检测到机器人 | 超越验证码的反机器人 | 添加隐身选项,使用 unDetected-chromedriver |
常问问题
我可以使用 CaptchaAI 在无头模式下运行 Selenium 吗?
是的。 CaptchaAI 解决了服务器端的验证码 - 浏览器只需要加载页面即可提取站点密钥。无头模式工作正常。
我需要点击验证码复选框吗?
不会。CaptchaAI 返回您直接注入表单的令牌。不需要与验证码小部件进行视觉交互。
带回调的 reCAPTCHA 怎么样?
有些网站使用 JavaScript 回调而不是表单提交。使用 driver.execute_script() 使用已解决的令牌触发回调。看如何解决reCAPTCHA v2回调。