如何用 CapSkip SDK 在 Python 中识别 reCAPTCHA v2

reCAPTCHA v2 有三种变体,在 Python 中它们是同一个函数,只是使用不同的关键字参数。Checkbox 是最基本的调用,Invisible 和 Enterprise 是标志参数,两者也可同时设置。Python 还是唯一拥有真正独立异步客户端的 CapSkip SDK,一旦你需要同时识别多个验证码,这一点就很重要。
设置
# 需要 Python 3.10 或更高版本。 pip install capskip
CapSkip 在本地识别,因此请先启动桌面应用,然后将客户端指向其设置中显示的端口:
from capskip import CapSkip
solver = CapSkip(
apiKey="capskip", # any string when key validation is off
host="127.0.0.1",
port=8080,
recaptchaTimeout=300, # seconds
)在生产环境中,改为从环境变量读取这些值:
import os
from capskip import CapSkip
solver = CapSkip(
apiKey=os.getenv("CAPSKIP_API_KEY", "capskip"),
host=os.getenv("CAPSKIP_HOST", "127.0.0.1"),
port=int(os.getenv("CAPSKIP_PORT", "8080")),
)三种变体
| 变体 | 需添加的关键字 |
|---|---|
| 复选框 | 无 |
| 隐形 | invisible=1 |
| Enterprise | enterprise=1 |
| 隐形 Enterprise | 两者 |
# Checkbox: the baseline call.
result = solver.recaptcha(
sitekey="6Lc...YOUR_SITEKEY",
url="https://example.com/login",
)
print(result["code"]) # g-recaptcha-response token
# Invisible.
result = solver.recaptcha(sitekey=sitekey, url=page_url, invisible=1)
# Enterprise, and both together.
result = solver.recaptcha(sitekey=sitekey, url=page_url, enterprise=1)
result = solver.recaptcha(sitekey=sitekey, url=page_url, enterprise=1, invisible=1)返回值是一个普通的 dict,因此 result["code"] 就是 token。还有 result["captchaId"] 如果你想记录是哪次内部识别产生了它。
正确获取 sitekey 和 URL
sitekey 是 data-sitekey 小组件容器上的属性,或者是传给 grecaptcha.render 在没有容器时——它始终以 6L 开头,且是公开的。
URL 必须是小组件实际渲染所在的页面。传入你的表单处理程序或登录后的重定向,是 token 识别顺利却随后验证失败的最常见原因。
提交 token
import requests
response = requests.post(
"https://example.com/login",
data={
"g-recaptcha-response": result["code"],
"username": "...",
"password": "...",
},
)token 有效期约两分钟且只能使用一次,因此请在流程中尽可能晚地识别。如果网站把 token 交给 JavaScript 回调而不是表单字段,识别相同但提交方式不同,这一点我们的 reCAPTCHA v2 回调识别工具 页面有说明。
同时识别多个
这就是 Python 与其他 CapSkip SDK 不同之处。 AsyncCapSkip 是真正的异步实现,而非别名,因此它能真正地并行识别:
import asyncio
from capskip import AsyncCapSkip
async def main():
solver = AsyncCapSkip()
r1, r2 = await asyncio.gather(
solver.recaptcha(sitekey=key_a, url="https://a.example.com"),
solver.recaptcha(sitekey=key_b, url="https://b.example.com"),
)
print(r1["code"], r2["code"])
asyncio.run(main())在 Node.js 和 .NET SDK 中 AsyncCapSkip 只是一个别名,而在 PHP 中它的存在纯粹是为了让移植的代码能编译。Python 是唯一切换到它会真正改变行为的语言。
错误
from capskip import (
CapSkip, ValidationException, NetworkException,
ApiException, TimeoutException,
)
try:
result = solver.recaptcha(sitekey=sitekey, url=page_url)
except ValidationException:
pass # missing or malformed arguments
except NetworkException:
pass # CapSkip is not running
except ApiException:
pass # bad sitekey or pageurl
except TimeoutException:
pass # exceeded recaptchaTimeout这四个都派生自同一个基类,因此 except CapSkipError 如果你更愿意在一处处理失败,它会捕获全部情况。
使用代理
result = solver.recaptcha(
sitekey=sitekey,
url=page_url,
proxy={"type": "HTTPS", "uri": "user:[email protected]:3128"},
)reCAPTCHA、Turnstile 和 极验 支持代理。图片验证码不支持,因为它们是从图片字节中识别的,永远不会到达目标网站。
常见问题
我需要轮询结果吗?
不需要。SDK 会在内部轮询并返回完成的 token,因此 CAPCHA_NOT_READY 永远不会出现在你的代码里。它在 250 毫秒后开始检查并逐步退避,这通常比手写的循环更快。
对于单次识别,AsyncCapSkip 值得使用吗?
不太需要。它在多个识别相互重叠时才重要,或者当你已经处于事件循环内、阻塞调用会拖住它时才重要。如果只是脚本中的一次识别,同步客户端更简单。
支持哪些 Python 版本?
3.10 及更新版本。该包没有繁重的依赖,因此可以直接接入现有的爬虫或自动化项目,而不会拉入一大堆额外的包。
小结
一个函数、三种变体,通过 invisible 和 enterprise选择。读取 result["code"],将其作为 g-recaptcha-response,并在 AsyncCapSkip 批量识别时使用它。
更完整的 Python 接口见 Python 验证码识别 页面,其他语言见 reCAPTCHA v2 识别 页面,还有一个 在线 v2 演示 可供测试。CapSkip 采用 验证码识别工具 在你自己的机器上运行。
