跳转到内容

用 token 完成 reCAPTCHA

YesCaptcha 返回的 gRecaptchaResponse 就是你在网页上点完验证码后、Google 交给网页的那个结果。拿到它之后,你需要像浏览器一样把它提交给目标网站(不是提交给 Google 或 YesCaptcha),网站拿去向 Google 核实后放行。有两种做法:直接发请求提交,或者在浏览器里填进页面再提交。

正常访问时的流程:

  1. 网页加载 reCAPTCHA,用户完成验证;
  2. Google 给网页一个 token,网页把它放进 g-recaptcha-response 文本框(或交给回调函数);
  3. 用户提交表单,token 随表单发给网站服务器;
  4. 网站服务器拿 token 向 Google 核实,通过就放行。

用 YesCaptcha 时,第 1、2 步由我们完成:你用 websiteURL、websiteKey 创建任务,拿到 token,然后从第 3 步接着做。

token 一次性使用,约 120 秒内有效,建议拿到后 60 秒内提交。

方法一:直接发请求提交(推荐)

Section titled “方法一:直接发请求提交(推荐)”
  1. 在浏览器里正常操作一次:按 F12 打开 Network 面板,完成验证码并提交,找到提交表单的那个请求。
  2. 在请求的 Payload(或 Form Data)里找到携带 token 的字段,通常叫 g-recaptcha-response,token 以 03A 开头;有的网站会改名,例如 grecaptcharesponse、captcha。
  3. 在你的程序里发一个一样的请求,把字段的值换成 YesCaptcha 返回的 token。其他字段、Cookie、请求头也要和浏览器的一致,网站往往同时检查它们。

Google 演示页的完整例子:先识别,再把 token 用 g-recaptcha-response 字段提交回演示页:

recaptcha_requests.py
"""Solve reCAPTCHA v2 on Google's demo page and submit the token with plain HTTP (no browser).
Run: pip install requests
export YESCAPTCHA_CLIENT_KEY=your_client_key
python recaptcha_requests.py
Each run creates one NoCaptchaTaskProxyless task (charged per the price list).
"""
import os
import time
import requests
CLIENT_KEY = os.environ["YESCAPTCHA_CLIENT_KEY"]
API = "https://api.yescaptcha.com"
WEBSITE_URL = "https://www.google.com/recaptcha/api2/demo"
WEBSITE_KEY = "6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-"
def call(method, payload):
data = requests.post(f"{API}/{method}", json={"clientKey": CLIENT_KEY, **payload}, timeout=30).json()
if data.get("errorId"):
raise RuntimeError(f"{data.get('errorCode')}: {data.get('errorDescription')}")
return data
def get_token():
task = {"type": "NoCaptchaTaskProxyless", "websiteURL": WEBSITE_URL, "websiteKey": WEBSITE_KEY}
task_id = call("createTask", {"task": task})["taskId"]
for _ in range(36): # poll every 5 seconds, for up to about 3 minutes
time.sleep(5)
result = call("getTaskResult", {"taskId": task_id})
if result.get("status") == "ready":
return result["solution"]["gRecaptchaResponse"]
raise TimeoutError(task_id)
token = get_token()
print("token:", token[:40], "...")
# Submit the token the same way the browser does: the demo form posts the field
# "g-recaptcha-response" back to the page. Check your own site's request in DevTools > Network.
page = requests.post(WEBSITE_URL, data={"g-recaptcha-response": token}, timeout=30)
print("passed" if "Verification Success" in page.text else "not passed", page.status_code)

方法二:在浏览器里填入(Selenium 等)

Section titled “方法二:在浏览器里填入(Selenium 等)”

用 Selenium、Playwright 之类的工具操作真实浏览器时:

  1. 从页面读出 data-sitekey,用它创建任务拿到 token。
  2. 把 token 写进页面里的 g-recaptcha-response 文本框。
  3. 如果页面设置了回调函数(data-callback="..."),调用它并传入 token;有的网站只有调用了回调,提交按钮才会变成可点击。
  4. 提交表单。
// 第 2 步:写入 token(在页面里执行)
document.getElementById('g-recaptcha-response').value = 'TOKEN';
// 第 3 步:有回调函数时调用,例如 data-callback="onSuccess"
onSuccess('TOKEN');

页面上有多个 reCAPTCHA 时,文本框的 id 可能是 g-recaptcha-response-1 这样的;找不到这个文本框时,先手动完成一次验证,在 Elements 里搜 03A,看结果被放在哪里。回调函数怎么找见 查找 reCAPTCHA 参数。

完整例子(Selenium 4):

recaptcha_selenium.py
"""Solve reCAPTCHA v2 on Google's demo page in a real browser with Selenium 4:
get a token from YesCaptcha, put it into the page, then submit the form.
Run: pip install requests selenium
export YESCAPTCHA_CLIENT_KEY=your_client_key
python recaptcha_selenium.py
Each run creates one NoCaptchaTaskProxyless task (charged per the price list).
"""
import os
import time
import requests
from selenium import webdriver
from selenium.webdriver.common.by import By
CLIENT_KEY = os.environ["YESCAPTCHA_CLIENT_KEY"]
API = "https://api.yescaptcha.com"
WEBSITE_URL = "https://www.google.com/recaptcha/api2/demo"
def call(method, payload):
data = requests.post(f"{API}/{method}", json={"clientKey": CLIENT_KEY, **payload}, timeout=30).json()
if data.get("errorId"):
raise RuntimeError(f"{data.get('errorCode')}: {data.get('errorDescription')}")
return data
def get_token(website_url, website_key):
task = {"type": "NoCaptchaTaskProxyless", "websiteURL": website_url, "websiteKey": website_key}
task_id = call("createTask", {"task": task})["taskId"]
for _ in range(36):
time.sleep(5)
result = call("getTaskResult", {"taskId": task_id})
if result.get("status") == "ready":
return result["solution"]["gRecaptchaResponse"]
raise TimeoutError(task_id)
driver = webdriver.Chrome() # Selenium 4 downloads a matching chromedriver automatically
try:
driver.get(WEBSITE_URL)
site_key = driver.find_element(By.CSS_SELECTOR, "[data-sitekey]").get_attribute("data-sitekey")
token = get_token(WEBSITE_URL, site_key)
# Put the token where reCAPTCHA keeps it ...
driver.execute_script(
"document.getElementById('g-recaptcha-response').value = arguments[0];", token
)
# ... and, if the page uses a callback (data-callback="..."), call it:
callback = driver.find_element(By.CSS_SELECTOR, "[data-sitekey]").get_attribute("data-callback")
if callback:
driver.execute_script(f"window[{callback!r}](arguments[0]);", token)
driver.find_element(By.ID, "recaptcha-demo-submit").click()
time.sleep(2)
print("passed" if "Verification Success" in driver.page_source else "not passed")
finally:
driver.quit()

v3 没有复选框,网页在需要时调用 grecaptcha.execute(网站密钥, {action: '...'}) 拿 token,然后把 token 放进它自己的请求里(字段名由网站决定,常见 g-recaptcha-response、token、recaptchaToken)。做法和方法一相同:在 Network 里找到带 token 的请求照着发;创建任务时 pageAction 要和网页的 action 一致。

  • token 过期了:拿到后尽快提交,不要超过 60 秒。
  • 提交的不是网站检查的那个字段,或者漏了其他字段、Cookie:对照浏览器里的请求逐项检查。
  • 网站同时检查 IP、User-Agent 等:用自带代理的类型(如 NoCaptchaTask),提交时走同一个代理。
  • v3 分数不够:确认 pageAction,或改用固定高分的类型,见 reCAPTCHA v3。
  • 网站的风控还看其他行为信号,token 方式通过率低时,可以改用 图像识别 在浏览器里真实点击,或者用 浏览器插件。