Skip to content

Python SDK

Verified v1.0.0· 2026-05-28

使用官方 CaptchaSonic SDK 从 Python 中解决验证码 —— 支持 gRPC + HTTP 传输、异步就绪、完整类型提示。

官方 CaptchaSonic Python SDK 将每一种受支持的验证码都变成一次函数调用。它同时提供同步客户端(CaptchaSonic)和异步客户端(AsyncCaptchaSonic),默认通过 gRPC 与我们的基础设施通信(并提供可选的 HTTP 传输),并包含完整的类型提示、针对瞬时错误的自动重试,以及针对令牌类挑战的内置轮询。


安装

pip install captchasonic

默认会安装 gRPC 传输。若还需使用可选的 HTTP/JSON 传输,请安装 extra:

pip install "captchasonic[http]"

TIP

该 SDK 支持 Python 3.10、3.11、3.12 和 3.13,并以 MIT 许可证发布。


身份验证

你需要一个 CaptchaSonic API 密钥。创建账户后,在控制台中获取你的密钥,然后在充值页面为余额充值。

将密钥作为客户端的第一个位置参数传入:

from captchasonic import CaptchaSonic

solver = CaptchaSonic("YOUR_API_KEY")

WARNING

请像对待密码一样对待你的 API 密钥。不要将其提交到版本控制系统 —— 应从环境变量或密钥管理工具中加载,而不要硬编码在代码中。

import os
from captchasonic import CaptchaSonic

solver = CaptchaSonic(os.environ["CAPTCHASONIC_API_KEY"])

快速开始

大多数令牌类验证码(reCAPTCHA、Turnstile、hCaptcha)只需一次调用即可解决。客户端会自动为你轮询,并在任务就绪后返回令牌。

from captchasonic import CaptchaSonic

solver = CaptchaSonic("YOUR_API_KEY")

result = solver.solve_recaptcha_v2_token(
    website_url="https://example.com/login",
    website_key="6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-",
)

print(result["token"])
# 03AGdBq25SxXT...  ← 将其填入 g-recaptcha-response 字段

返回 result["token"] —— 将其作为页面的 g-recaptcha-response 提交。

令牌类方法默认最多轮询 120 秒后才会超时(参见配置)。


受支持的验证码类型

SDK 将方法分为两个系列:

  • 令牌方法*_tokensolve_turnstilesolve_cloudflare)—— 你提供 website_url / website_key,SDK 轮询我们的基础设施并返回可直接提交的 result["token"]
  • 图像 / 交互方法 —— 你自行提供挑战图像,SDK 返回 result["typed_solution"],描述需要点击、拖动或输入的内容。

所有图像参数都接受灵活的 ImageInput 类型 —— 文件路径(str)、pathlib.Path、原始 bytes,或一个已打开的二进制文件对象。

from pathlib import Path

# 以下任意一种都可作为 `images=[...]` 列表中的元素:
Path("captcha.png")        # pathlib.Path
"./captcha.png"            # str 路径
open("captcha.png", "rb").read()  # bytes

reCAPTCHA v2(令牌)

result = solver.solve_recaptcha_v2_token(
    website_url="https://example.com",
    website_key="6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-",
    proxy="http://user:pass@host:port",  # 可选
)
token = result["token"]

返回 result["token"] —— 将其作为页面的 g-recaptcha-response 提交。

reCAPTCHA v3(令牌)

result = solver.solve_recaptcha_v3_token(
    website_url="https://example.com",
    website_key="6Lc_aCMTAAAAAB...",
    proxy="http://user:pass@host:port",  # 可选
)
token = result["token"]

返回 result["token"] —— 将其作为页面的 g-recaptcha-response 提交。

reCAPTCHA v2(图像网格)

当你已经拿到挑战图块时,可直接解决网格并获取需要点击的索引。

result = solver.solve_recaptcha_v2(
    images=[Path("tile.png")],         # ImageInput 列表
    question="traffic lights",          # 标签或 /m/... 实体 ID
    question_type="44",                # "split_33" | "33" | "44"
)
to_click = result["typed_solution"]["grid"]["objects"]  # list[int]

返回 result["typed_solution"]["grid"]["objects"] —— 需要点击的图块索引列表。

Cloudflare Turnstile

result = solver.solve_turnstile(
    website_url="https://example.com",
    website_key="0x4AAAAAAA...",
    proxy="http://user:pass@host:port",  # 可选
)
token = result["token"]

返回 result["token"] —— 将其作为表单的 cf-turnstile-response 提交。

Cloudflare Challenge

完整的 Cloudflare Challenge 必须提供代理。

result = solver.solve_cloudflare(
    website_url="https://example.com",
    website_key="0x4AAAAAAA...",
    proxy="http://user:pass@host:port",  # 必填
)
token = result["token"]

返回 result["token"] —— 用于受保护请求的通行令牌。

solve_popular_captcha 处理交互式图像变体;solve_popular_captcha_token 直接返回令牌。

# 图像 / 交互变体
result = solver.solve_popular_captcha(
    images=[Path("challenge.png")],
    question="Select all traffic lights",
    question_type="grid",  # "objectClassify" | "objectClick" | "objectDrag" | "grid"
)
to_click = result["typed_solution"]["grid"]["objects"]  # list[int]

# 令牌变体
result = solver.solve_popular_captcha_token(
    website_url="https://example.com",
    website_key="00000000-0000-0000-0000-000000000000",
    proxy="http://user:pass@host:port",  # 可选
)
token = result["token"]

图像变体返回 result["typed_solution"]["grid"]["objects"](需要点击的图块索引);令牌变体返回 result["token"]

GeeTest(极验)

result = solver.solve_geetest(
    geetest_type="nine",  # "nine" | "click" | "slide" | "match" | "winlinze"
    question="Select all bicycles",  # "nine" 和 "click" 必填
    images=[Path("tile.png")],        # "nine"、"click"、"slide" 必填
)
solution = result["typed_solution"]  # 结构因 geetest_type 而异

返回 result["typed_solution"] —— 需要执行的操作,其结构由 geetest_type 决定。

AWS WAF

result = solver.solve_aws_waf(
    images=[Path("grid.png")],
    question="grid:vehicles:cars",
)
to_click = result["typed_solution"]["grid"]["objects"]  # list[int]

返回 result["typed_solution"]["grid"]["objects"] —— 需要点击的图块索引列表。

图像转文字(OCR)

result = solver.solve_ocr(
    images=[Path("captcha.png")],
    module="common",       # "common" | "mtcaptcha" | "bls" | "morocco"
    numeric=False,         # 仅期望数字
    case_sensitive=True,   # 保留字母大小写
    min_length=4,
    max_length=8,
)
text = result["typed_solution"]["text"]["texts"][0]  # str

返回 result["typed_solution"]["text"]["texts"][0] —— 需要填入的识别文本。

滑块拼图

传入背景图和拼图块;返回需要滑动的水平像素偏移量。

result = solver.solve_slide_image(
    images=[Path("background.png"), Path("piece.png")],
)
offset_x = result["typed_solution"]["slide"]["x"]  # float(像素)

返回 result["typed_solution"]["slide"]["x"] —— 拖动拼图块所需的水平像素偏移量。

TikTok

result = solver.solve_tiktok(
    type="whirl",  # "click" | "whirl" | "slide"
    images=[Path("outer.png")],
    examples=[Path("inner.png")],  # "whirl" 和 "slide" 必填
)
solution = result["typed_solution"]

返回 result["typed_solution"] —— 需要执行的操作,其结构由 type 决定。

Binance(币安)

result = solver.solve_binance(
    type="grid",  # "grid" | "slide"
    question="Select all bicycles",  # "grid" 必填
    images=[Path("grid.png")],
)
solution = result["typed_solution"]

返回 result["typed_solution"] —— 需要执行的操作,其结构由 type 决定。


异步用法

对于高并发场景(FastAPI 处理函数、Scrapy 爬虫、asyncio 管道),请使用 AsyncCaptchaSonic。它与同步 API 完全一致,但每个解决方法都是可 await 的。请将其用作异步上下文管理器,以便底层通道被自动清理。

import asyncio
from captchasonic import AsyncCaptchaSonic

async def main():
    async with AsyncCaptchaSonic("YOUR_API_KEY") as solver:
        result = await solver.solve_turnstile(
            website_url="https://example.com",
            website_key="0x4AAAAAAA...",
        )
        print(result["token"])

asyncio.run(main())

同步客户端同样支持上下文管理器协议:

with CaptchaSonic("YOUR_API_KEY") as solver:
    result = solver.solve_ocr(images=[Path("captcha.png")])
    print(result["typed_solution"]["text"]["texts"][0])

代理支持

令牌方法接受可选的 proxy 参数(solve_cloudflare 为必填)。使用标准的代理 URL:

proxy = "http://user:pass@host:port"

result = solver.solve_recaptcha_v2_token(
    website_url="https://example.com",
    website_key="6Le-...",
    proxy=proxy,
)

TIP

提供代理可让我们的求解器还原你请求的地理位置和 IP 信誉,从而提高在具有严格反机器人规则的站点上的成功率。


配置

所有选项都传递给客户端构造函数,并同时适用于同步和异步客户端。

solver = CaptchaSonic(
    "YOUR_API_KEY",
    transport="grpc",                # "grpc"(默认)或 "http"
    url="api.captchasonic.com:443",  # 覆盖端点(可选)
    timeout=30.0,                    # 单次调用超时,单位秒
    polling_interval=2.0,            # 任务轮询间隔,单位秒
    polling_timeout=120.0,           # 令牌任务的最长等待时间,单位秒
    secure=True,                     # 为 gRPC 使用 TLS
)
选项默认值说明
transport"grpc"传输协议。"grpc" 发送图像时无 base64 开销;"http"(需要 [http] extra)以 REST/JSON 发送,图像采用 base64 编码。
urlapi.captchasonic.com:443覆盖 API 端点(例如用于自托管或 staging)。
timeout30.0单次调用的网络超时,单位秒。
polling_interval2.0等待令牌任务时的轮询间隔,单位秒。
polling_timeout120.0令牌任务抛出异常前的最长等待时间,单位秒。
secureTrue为 gRPC 通道使用 TLS。

瞬时 gRPC 错误会自动重试(最多 3 次)并采用指数退避,因此你只需处理真正的业务错误。


错误处理

所有 SDK 错误都继承自 SonicError,因此你可以用一个 except 子句捕获全部错误,或针对具体子类分别处理。每个错误还携带一个数字 error_id

from captchasonic.exceptions import (
    SonicError,
    InvalidApiKeyError,
    InsufficientBalanceError,
)

try:
    result = solver.solve_turnstile(
        website_url="https://example.com",
        website_key="0x4AAAAAAA...",
    )
except InsufficientBalanceError:
    print("Top up your balance to continue.")
except InvalidApiKeyError:
    print("Check your API key.")
except SonicError as err:
    print(f"Solve failed (error_id={err.error_id}): {err}")
error_id异常原因操作
1InvalidApiKeyErrorAPI 密钥缺失或无效。控制台中核实密钥。
2InsufficientBalanceError账户余额不足以支付该任务。充值
3DailyLimitExceededError每日配额已用尽。等待每日重置或升级套餐。
4MinuteLimitExceededError达到每分钟速率限制。降低请求速率 / 增加退避。
5QuotaExceededError套餐配额已用尽。升级套餐。
6PlanExpiredError订阅已过期。续订订阅。

账户辅助方法

balance = solver.get_balance()  # 当前余额,单位 USD(float)
print(f"Balance: ${balance:.2f}")

health = solver.health_check()  # HealthCheckResponse —— 验证连接性

可将 health_check() 用作服务中的轻量级就绪探针,并用 get_balance() 在开始消耗额度前对任务进行门控。


故障排查

TIP

使用 HTTP 传输时出现 ModuleNotFoundError HTTP 客户端依赖 httpx,它是一个可选 extra。请使用 pip install "captchasonic[http]" 安装它,并设置 transport="http"

  • 令牌任务在约 120 秒后抛出异常。 这是 polling_timeout。对于较慢的目标可增大它,例如 CaptchaSonic(key, polling_timeout=240.0)
  • solve_cloudflare 立即失败。 Cloudflare Challenge 必须提供 proxy 参数 —— 请提供一个可用的代理 URL。
  • 在企业代理 / 防火墙后出现 gRPC 连接错误。 gRPC 需要通过 443 端口使用 HTTP/2。如果你的网络封锁了它,请切换到 transport="http"
  • 图像方法返回的是索引而非令牌。 交互式方法(solve_recaptcha_v2solve_popular_captchasolve_aws_wafsolve_geetest 等)返回 result["typed_solution"],描述需要执行的操作;只有 *_tokensolve_turnstilesolve_cloudflare 返回 result["token"]

资源