Skip to content

Popular Captcha 求解器

使用 PopularCaptchaImage 或 PopularClassification 任务类型解决对象交互验证码。questionType 字段决定挑战的处理方式。

支持的模式

questionType说明响应格式
objectClassify从九宫格中选择所有匹配的图片每张图片一个 boolean[]
objectClick点击目标对象的中心{x, y}[] 坐标
objectDrag将拼图块拖到正确位置{start, end}[]
objectTag为图片中的对象打标签标签数组
grid通用九宫格选择布尔数组
bbox边界框检测坐标

创建任务 —— 九宫格分类

POST/createTask
Hostapi.captchasonic.com
Content-Typeapplication/json
{
    "apiKey": "YOUR_API_KEY",
    "task": {
        "type": "PopularCaptchaImage",
        "questionType": "objectClassify",
        "question": "Select all objects with a bridge",
        "queries": ["BASE64_IMG_1", "BASE64_IMG_2"]
    }
}

响应

{
    "code": 200,
    "msg": "",
    "answers": [true, false, true, true, false, true],
    "questionType": "objectClassify",
    "meta": { "pass_report": true, "fail_report": true }
}

创建任务 —— 对象点击

{
    "apiKey": "YOUR_API_KEY",
    "task": {
        "type": "PopularCaptchaImage",
        "questionType": "objectClick",
        "question": "Click on the center of the car",
        "queries": ["BASE64_MAIN_IMAGE"]
    }
}

创建任务 —— 对象拖放

{
    "apiKey": "YOUR_API_KEY",
    "task": {
        "type": "PopularCaptchaImage",
        "questionType": "objectDrag",
        "question": "Drag the puzzle piece to the gap",
        "queries": ["BASE64_BACKGROUND"],
        "examples": ["BASE64_PUZZLE_PIECE"]
    }
}

任务参数

字段类型必填说明
typestring✅PopularCaptchaImage 或 PopularClassification
questionTypestring✅objectClassify、objectClick、objectDrag、objectTag、grid、bbox
questionstring✅挑战指令文本
queriesstring[]✅base64 编码的图片
examplesstring[]仅拖放拖放任务的目标对象
screenshortboolean否若图片是截图,设为 true

视频验证码求解(动态画布)

某些挑战(例如 hCaptcha 变体)包含动态画布动画,而非静态图片。这些挑战通过 PopularCaptchaImage 任务类型的专用变体来解决,需要客户端捕获/记录画布(将多个视频帧融合成单张图片,或提交原始视频)。

为避免在每次挑战中都记录和处理视频,强烈建议实现客户端缓存机制,将目标问题映射到已解析的画布配置。

缓存策略(客户端)

  1. 同形字归一化(Homoglyph Normalization): 在查询或保存到缓存之前,清除 question 文本中的 Unicode 同形字(例如看起来像英文的西里尔/希腊字符)。这确保了缓存键与后端的归一化管道一致。
  2. TTL(生存时间): 24 小时。
  3. 容量: 最多 800 条,基于 LRU(最近最少使用)淘汰算法。
  4. 缓存键: "nc_video_cache",将归一化后的问题文本映射到 canvasParams。

求解工作流

场景 A:缓存未命中(双阶段流)

sequenceDiagram
    participant Client as 客户端
    participant Server as 服务端
    Note over Client: 步骤 1: 检测到验证码
    Client->>Server: POST /createTask (初始标准载荷)
    Server-->>Client: 400 Bad Request (questionVariant: "canvasvideo")
    Note over Client: 步骤 2: 拦截 canvasParams 并保存至缓存
    Note over Client: 步骤 3: 录制画布视频 (例如 2 秒) 并融合帧
    Client->>Server: POST /createTask (丰富后的第二阶段载荷)
    Server-->>Client: 200 OK (已解决的答案坐标)
  1. 初始抓取: 向求解器 API (/createTask) 提交标准的单帧请求。
  2. 后端信号: 如果后端检测到此目标问题是一个视频验证码,它会响应 400 状态码,且 questionVariant 为 "canvasvideo",并包含所需的 canvasParams。
  3. 缓存存储: 在本地保存这些 canvasParams。
  4. 画布录制与融合:
    • 如果 canvasParams.video 为 true,录制指定时间的画布。
    • 根据 canvasParams.format 提取并融合/合并帧。
  5. 第二阶段重新提交: 构建包含 canvasVideo: true、queries 中的融合帧、以及录制的视频 base64 数组的丰富载荷。重新提交给后端以获得 200 成功响应。

场景 B:缓存命中(单阶段流)

sequenceDiagram
    participant Client as 客户端
    participant Server as 服务端
    Note over Client: 步骤 1: 查询缓存 (归一化问题匹配)
    Note over Client: 步骤 2: 立即录制画布并融合帧
    Client->>Server: POST /createTask (直接发送丰富后的载荷)
    Server-->>Client: 200 OK (已解决的答案坐标)
    Note over Client: 退避方案: 若服务端拒绝,使缓存失效并运行双阶段流
  1. 求解前缓存检查: 使用归一化的问题文本查询本地缓存。
  2. 即时画布准备: 如果存在有效的缓存项,立即录制画布并根据缓存的参数融合/合并帧。
  3. 单阶段提交: 在第一次请求中直接提交完整构建的载荷(融合帧 + 视频数据)。
  4. 失效回退: 如果服务端拒绝了请求(例如缓存参数已过期或在服务端已更改),使本地缓存的配置失效/删除,并回退到全新的双阶段流。

载荷结构

1. 初始请求(第一阶段 - 缓存未命中)

在知道需要视频处理之前,首次尝试解决验证码时发送。

{
  "apiKey": "YOUR_API_KEY",
  "task": {
    "type": "PopularCaptchaImage",
    "queries": ["data:image/jpeg;base64,..."],
    "examples": ["data:image/jpeg;base64,..."],
    "question": "Please click on the living room",
    "screenshot": false,
    "questionType": "objectClick",
    "websiteURL": "example.com",
    "websiteKEY": "sitekey-value"
  }
}

2. 响应(指示需要视频验证码)

当后端检测到需要视频验证码时返回。

{
  "code": 400,
  "msg": "canvasvideo",
  "questionVariant": "canvasvideo",
  "questionType": "objectClick",
  "canvasParams": {
    "duration": 2,
    "video": true,
    "format": ["frameMerge"],
    "frames": [0.1, 0.5, 1.0],
    "framecount": null
  }
}

3. 丰富后的请求(第二阶段重新提交 / 单阶段缓存命中)

包含融合后的图片(位于 queries 中)和录制的画布视频。

{
  "apiKey": "YOUR_API_KEY",
  "task": {
    "type": "PopularCaptchaImage",
    "queries": ["data:image/jpeg;base64,..."], // 融合帧结果
    "examples": ["data:image/jpeg;base64,..."],
    "question": "please click on the living room", // 归一化问题
    "screenshot": false,
    "questionType": "objectClick",
    "websiteURL": "example.com",
    "websiteKEY": "sitekey-value",
    "choices": [],
    "canvasVideo": true,
    "format": "frameMerge", // 或 "framecount"
    "video": ["data:video/mp4;base64,..."] // Base64 录制的视频
  }
}

4. 响应(成功求解)

{
  "code": 200,
  "status": "ready",
  "questionType": "objectClick",
  "answers": [
    [
      { "x": 109, "y": 179 },
      { "x": 163, "y": 260 }
    ]
  ],
  "meta": {
    "data": "...",
    "fail_report": true,
    "pass_report": true
  }
}

错误码

错误码错误说明
1KEY_DOES_NOT_EXISTAPI 密钥无效或未找到。
2NO_SLOT_AVAILABLE所有求解器插槽都被占用。
3ZERO_BALANCE账户余额为零。
10ERROR_BAD_PARAMETERS请求字段无效或缺失。
12ERROR_CAPTCHA_UNSOLVABLE无法解决验证码。
14PLAN_EXPIRED您的计划已过期。
16RATE_LIMITED请求过多,请放慢速度。
17DAILY_LIMIT_EXCEEDED达到每日使用上限。
18QUOTA_LIMIT_EXCEEDED计划配额已用完。
21SERVICE_UNAVAILABLE后端暂时不可用。

代码示例

# 第一步:创建任务
RESPONSE=$(curl -s -X POST "https://api.captchasonic.com/createTask" \
  -H "Content-Type: application/json" \
  -d '{
  "apiKey": "YOUR_API_KEY",
  "task": {
    "type": "PopularCaptchaImage",
    "questionType": "objectClassify",
    "question": "Select all objects with a bridge",
    "queries": [
      "BASE64_IMG_1",
      "BASE64_IMG_2"
    ]
  }
}')

echo "Create Task Response: $RESPONSE"
TASK_ID=$(echo $RESPONSE | grep -o '"taskId":"[^"]*"' | cut -d'"' -f4)

# 第二步:轮询结果
while true; do
  RESULT=$(curl -s -X POST "https://api.captchasonic.com/getTaskResult" \
    -H "Content-Type: application/json" \
    -d "{\"apiKey\": \"YOUR_API_KEY\", \"taskId\": \"$TASK_ID\"}")
  echo "Result: $RESULT"
  echo "$RESULT" | grep -q '"status":"processing"' || break
  sleep 2
done

API 演练场

POST
Log in to auto-fill your API key
Payload
Response

Hit Send to see response

⌘ + Enter

Parameters

apiKeystringYOUR_API_KEY
taskobject{...}
└ typestringPopularCaptchaImage
└ questionTypestringobjectClassify
└ questionstringSelect all objects with a brid…
└ queriesarray[2 items]

Error Codes

1KEY_DOES_NOT_EXIST
2NO_SLOT_AVAILABLE
3ZERO_BALANCE
10ERROR_BAD_PARAMETERS
12ERROR_CAPTCHA_UNSOLVABLE
14PLAN_EXPIRED
16RATE_LIMITED
17DAILY_LIMIT_EXCEEDED
18QUOTA_LIMIT_EXCEEDED
21SERVICE_UNAVAILABLE
Code
terminal