ComplexImageTask Recaptcha
此任务无需使用代理服务器。
该对象包含解决谷歌 ReCaptcha2 任务的数据。
请求参数
重要提示:某些参数的值是动态的,即在每次渲染包含 reCAPTCHA 的页面时都会发生变化。
请在创建任务前立即提取这些参数,以避免在解决过程中出现错误。
自动提取参数的示例请参见章节 如何查找任务创建所需的所有参数。
type<string>requiredComplexImageTask
class<string>requiredrecaptcha
imageUrls<array>required(如果未填写 imagesBase64)完整的 4x4、3x3 图像,或验证码中新加载的 1x1 部分(数组形式)。 示例:["https://i.postimg.cc/yYjg75Kv/img1.jpg"]
imagesBase64<array>required(如果未填写 imageUrls)完整的 4x4、3x3 图像,或验证码中新加载的 1x1 部分的 base64 格式数据(数组形式)。
格式应如下:[ "/9j/4AAQSkZJRgABAQEAAAAAAAD…"](不包含前缀 data:image/jpeg;base64,)。
Grid (在 metadata 中)<string>required图像网格大小。 可选值:4x4、3x3、1x1
TaskDefinition(位于 metadata 中)<string>required(如果未填写 Task)用于确定任务类型的技术值
如何获取 TaskDefinition
可在 /recaptcha/{recaptchaApi}/reload 或 /recaptcha/{recaptchaApi}/userverify 请求的响应中找到数据,其中 recaptchaApi 根据 Recaptcha 类型为 "enterprise" 或 "api2"。响应中包含 json,可从中获取已加载验证码的 TaskDefinition 列表。
Task(位于 metadata 中)<string>required(如果未填写 TaskDefinition)可选值:Click on traffic lights 等
任务文本(英文)。
userAgent<string>optional加载图像时使用的浏览器用户代理(如果在 imageUrls 中传递了链接)。需要使用现代浏览器签名,否则谷歌会返回错误并要求更新浏览器。
websiteURL<string>optional解决验证码的页面 URL。
参数说明
imageUrls:图像链接。
imagesBase64:Base64 格式的图像。
Grid (在 metadata 中):与图像网格大小相关的附加元数据。
TaskDefinition (在 metadata 中):任务描述标识符/类型,例如:/m/015qff 表示“点击红绿灯”。

Task(在 metadata 中):与任务相关的附加元数据。
userAgent:用户代理信息。我们的服务当前支持的 userAgent:userAgentPlaceholder
websiteURL:包含验证码的网页地址。
创建任务方法
https://api.capmonster.cloud/createTask
请求示例
{
"clientKey": "API_KEY",
"task": {
"type": "ComplexImageTask",
"class": "recaptcha",
"imageUrls": [
"https://i.postimg.cc/yYjg75Kv/payloadtraffic.jpg"
],
"metadata": {
"Task": "Click on traffic lights",
"Grid": "3x3",
"TaskDefinition": "/m/015qff"
},
"userAgent": "userAgentPlaceholder",
"websiteUrl": "https://mydomain.com/page-with-recaptcha"
}
}
响应示例
{
"errorId":0,
"taskId":407533072
}
获取任务结果方法
使用getTaskResult方法获取验证码解决方案。根据系统负载情况,您将在300毫秒到6秒的时间内收到响应。
https://api.capmonster.cloud/getTaskResult
请求示例
{
"clientKey":"API_KEY",
"taskId": 407533072
}
响应示例
{
"errorId": 0,
"status": "ready",
"solution": {
"answer": [false, false, false, false, true, false, false, false, false]
}
}
| 属性 | 类型 | 描述 |
|---|---|---|
| answer | Array | 包含布尔值的列表,"true" 表示需要点击对应位置的图像。 |
定价:
| 名称 | 每1000张图片的成本, $ | 每1000张新动态图片的费用, $ | |
|---|---|---|---|
| 1 | reCAPTCHA 2 (3*3)
| 0.2 | 0.04 |
| 2 | reCAPTCHA 2 (4*4)
| 0.1 | 不适用 |
如何查找任务创建所需的所有参数
手动方式
- 请在浏览器中访问您的网站,该网站包含验证码功能。
- 右键点击验证码元素,选择 检查(Inspect)。
websitekey:
查找过程与查找 reCAPTCHA V2 和 reCAPTCHA V2 Enterprise 的 websitekey 类似。
imageUrls:
在元素属性中找到链接:

您也可以通过右键点击图像并选择 在新标签页中打开图像 来获取完整的图像 URL。然后,直接从浏览器地址栏复制该 URL。

Task(在 metadata 中)
任务描述。右键点击任务文字,然后在 开发者工具 中找到页面结构中对应的元素:

自动方法
为了自动化获取所需参数,可以通过 浏览器(普通模式或 headless 模式,例如使用 Playwright)进行提取,或直接从 HTTP 请求中获取。由于动态参数的有效时间较短,建议在获取后尽快使用。
所提供的代码片段仅作为获取必要参数的基础示例。具体实现方式取决于包含验证码的网站、本身的页面结构,以及所使用的 HTML 元素和选择器。
- JavaScript
- Python
- C#
显示代码(浏览器端)
const img = document.querySelector('img.rc-image-tile-33') || document.querySelector('img.rc-image-tile-44');
const src = img ? img.src : null;
console.log(src);
// 任务描述
const descEl =
document.querySelector('.rc-imageselect-desc-no-canonical') ||
document.querySelector('.rc-imageselect-desc');
const taskDescription = descEl
? descEl.textContent.trim()
: '未找到任务描述';
console.log(taskDescription);
// 可见的图片块数量
const tiles = document.querySelectorAll('.rc-imageselect-tile');
const visibleTiles = Array.from(tiles).filter(tile => tile.offsetParent !== null);
const tileCount = visibleTiles.length;
let gridSize;
if (tileCount === 9) {
gridSize = '3x3';
} else if (tileCount === 16) {
gridSize = '4x4';
} else if (tileCount === 25) {
gridSize = '5x5';
} else {
gridSize = 'Unknown';
}
console.log(`网格大小:${gridSize}`);
显示代码(Node.js)
import { chromium } from "playwright";
async function extractCaptchaInfo() {
const browser = await chromium.launch({ headless: false });
const page = await browser.newPage();
const url =
"https://lessons.zennolab.com/captchas/recaptcha/v2_simple.php?level=high";
await page.goto(url);
const frames = page.frames();
const checkboxFrame = frames.find((f) => f.url().includes("api2/anchor"));
if (!checkboxFrame) {
console.error("未找到 reCAPTCHA 的复选框 iframe");
await browser.close();
return;
}
const checkbox = await checkboxFrame.waitForSelector("#recaptcha-anchor", {
timeout: 5000,
});
await checkbox.click();
await page.waitForTimeout(1000);
const updatedFrames = page.frames();
const challengeFrame = updatedFrames.find((f) =>
f.url().includes("api2/bframe")
);
if (!challengeFrame) {
console.error("未找到 reCAPTCHA 的挑战 iframe");
await browser.close();
return;
}
// 图像
const img =
(await challengeFrame.$("img.rc-image-tile-33")) ||
(await challengeFrame.$("img.rc-image-tile-44"));
const src = img ? await img.getAttribute("src") : null;
console.log("图像:", src);
// 任务描述
try {
await challengeFrame.waitForSelector(
".rc-imageselect-desc-no-canonical, .rc-imageselect-desc",
{
timeout: 5000,
}
);
const taskDescription = await challengeFrame.$eval(
".rc-imageselect-desc-no-canonical, .rc-imageselect-desc",
(el) => {
const strong = el.querySelector("strong");
const text = strong ? strong.textContent.trim() : "未找到";
return text;
}
);
console.log("任务: 选择所有含有:", taskDescription, " 的图像");
} catch (error) {
console.log("未找到任务描述。");
}
// 网格大小
const tiles = await challengeFrame.$$(".rc-imageselect-tile");
const visibleTiles = await Promise.all(tiles.map((tile) => tile.isVisible()));
const tileCount = visibleTiles.filter(Boolean).length;
let gridSize;
if (tileCount === 9) {
gridSize = "3x3";
} else if (tileCount === 16) {
gridSize = "4x4";
} else if (tileCount === 25) {
gridSize = "5x5";
} else {
gridSize = "Unknown";
}
console.log(`网格大小:${gridSize}`);
await browser.close();
}
extractCaptchaInfo();
显示代码
import asyncio
from playwright.async_api import async_playwright
async def extract_captcha_info():
async with async_playwright() as p:
browser = await p.chromium.launch(headless=False)
page = await browser.new_page()
await page.goto("https://lessons.zennolab.com/captchas/recaptcha/v2_simple.php?level=high")
# 查找复选框 iframe
checkbox_frame = next((f for f in page.frames if "api2/anchor" in f.url), None)
if not checkbox_frame:
print("未找到 reCAPTCHA 的复选框 iframe")
await browser.close()
return
checkbox = await checkbox_frame.wait_for_selector("#recaptcha-anchor", timeout=5000)
await checkbox.click()
await page.wait_for_timeout(1000)
# 查找包含任务的框架
challenge_frame = next((f for f in page.frames if "api2/bframe" in f.url), None)
if not challenge_frame:
print("未找到 reCAPTCHA 的挑战 iframe")
await browser.close()
return
# 图像
img = await challenge_frame.query_selector("img.rc-image-tile-33") or await challenge_frame.query_selector("img.rc-image-tile-44")
src = await img.get_attribute("src") if img else None
print("图像:", src)
# 任务描述
try:
await challenge_frame.wait_for_selector(".rc-imageselect-desc-no-canonical, .rc-imageselect-desc", timeout=5000)
task_text = await challenge_frame.eval_on_selector(
".rc-imageselect-desc-no-canonical, .rc-imageselect-desc",
"el => el.querySelector('strong')?.textContent?.trim() || '未找到'"
)
print("任务: 选择所有含有:", task_text, " 的图像")
except:
print("未找到任务描述。")
# 网格大小
tiles = await challenge_frame.query_selector_all(".rc-imageselect-tile")
visible_count = 0
for tile in tiles:
if await tile.is_visible():
visible_count += 1
if visible_count == 9:
grid = "3x3"
elif visible_count == 16:
grid = "4x4"
elif visible_count == 25:
grid = "5x5"
else:
grid = "Unknown"
print("网格大小:", grid)
await browser.close()
asyncio.run(extract_captcha_info())
显示代码
using System;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Playwright;
class Program
{
public static async Task Main()
{
using var playwright = await Playwright.CreateAsync();
var browser = await playwright.Chromium.LaunchAsync(new() { Headless = false });
var page = await browser.NewPageAsync();
await page.GotoAsync("https://lessons.zennolab.com/captchas/recaptcha/v2_simple.php?level=high");
var checkboxFrame = page.Frames.FirstOrDefault(f => f.Url.Contains("api2/anchor"));
if (checkboxFrame == null)
{
Console.WriteLine("未找到 reCAPTCHA 的复选框 iframe");
await browser.CloseAsync();
return;
}
var checkbox = await checkboxFrame.WaitForSelectorAsync("#recaptcha-anchor");
await checkbox.ClickAsync();
await page.WaitForTimeoutAsync(1000);
var challengeFrame = page.Frames.FirstOrDefault(f => f.Url.Contains("api2/bframe"));
if (challengeFrame == null)
{
Console.WriteLine("未找到 reCAPTCHA 的挑战 iframe");
await browser.CloseAsync();
return;
}
var img = await challengeFrame.QuerySelectorAsync("img.rc-image-tile-33") ?? await challengeFrame.QuerySelectorAsync("img.rc-image-tile-44");
var src = img != null ? await img.GetAttributeAsync("src") : null;
Console.WriteLine("图像: " + src);
try
{
await challengeFrame.WaitForSelectorAsync(".rc-imageselect-desc-no-canonical, .rc-imageselect-desc");
var taskText = await challengeFrame.EvalOnSelectorAsync<string>(
".rc-imageselect-desc-no-canonical, .rc-imageselect-desc",
@"el => {
const strong = el.querySelector('strong');
return strong ? strong.textContent.trim() : '未找到';
}");
Console.WriteLine("任务: 选择所有含有:" + taskText + " 的图像");
}
catch
{
Console.WriteLine("未找到任务描述。");
}
var tiles = await challengeFrame.QuerySelectorAllAsync(".rc-imageselect-tile");
int visibleCount = 0;
foreach (var tile in tiles)
{
if (await tile.IsVisibleAsync())
visibleCount++;
}
string gridSize = visibleCount switch
{
9 => "3x3",
16 => "4x4",
25 => "5x5",
_ => "Unknown"
};
Console.WriteLine("网格大小: " + gridSize);
await browser.CloseAsync();
}
}
使用 SDK 库
- JavaScript
- Python
- C#
显示代码(用于浏览器)
// https://github.com/ZennoLab/capmonstercloud-client-js
import {
CapMonsterCloudClientFactory,
ClientOptions,
RecaptchaV3ProxylessRequest
} from '@zennolab_com/capmonstercloud-client';
document.addEventListener('DOMContentLoaded', async () => {
const cmcClient = CapMonsterCloudClientFactory.Create(
new ClientOptions({ clientKey: 'YOUR_API_KEY' }) // 输入您的 CapMonster Cloud API 密钥
);
// 如有必要,可以检查余额
const balance = await cmcClient.getBalance();
console.log("Balance:", balance);
const complexImageRecaptchaRequest = new ComplexImageRecaptchaRequest({
imageUrls: ['https://i.postimg.cc/yYjg75Kv/payloadtraffic.jpg'], // 替换为实际值
metaData: {
Grid: '3x3',
Task: 'Please click each image containing a mountain',
TaskDefinition: '/m/015qff'
},
websiteURL: 'https://mydomain.com/page-with-recaptcha' // 包含验证码的页面 URL
});
const solution = await cmcClient.Solve(recaptchaV3Request);
console.log('Solution:', solution);
});
显示代码 (Node.js)
// https://github.com/ZennoLab/capmonstercloud-client-js
import { CapMonsterCloudClientFactory, ClientOptions, RecaptchaV3ProxylessRequest } from '@zennolab_com/capmonstercloud-client';
const API_KEY = "YOUR_API_KEY"; // 输入您的 CapMonster Cloud API 密钥
async function solveRecaptchaV3() {
const cmcClient = CapMonsterCloudClientFactory.Create(
new ClientOptions({ clientKey: API_KEY })
);
// 如有必要,可以检查余额
const balance = await cmcClient.getBalance();
console.log("Balance:", balance);
const complexImageRecaptchaRequest = new ComplexImageRecaptchaRequest({
imageUrls: ['https://i.postimg.cc/yYjg75Kv/payloadtraffic.jpg'], // 替换为实际值
metaData: {
Grid: '3x3',
Task: 'Please click each image containing a mountain',
TaskDefinition: '/m/015qff'
},
websiteURL: 'https://mydomain.com/page-with-recaptcha' // 包含验证码的页面 URL
});
const solution = await cmcClient.Solve(recaptchaV3Request);
console.log("Solution:", solution);
}
solveRecaptchaV3().catch(console.error);
显示代码
# https://github.com/Zennolab/capmonstercloud-client-python
import asyncio
from capmonstercloudclient import CapMonsterClient, ClientOptions
from capmonstercloudclient.requests import RecaptchaV3ProxylessRequest
client_options = ClientOptions(api_key="YOUR_API_KEY") # 输入您的 CapMonster Cloud API 密钥
cap_monster_client = CapMonsterClient(options=client_options)
complex_image_recaptcha_request = RecaptchaComplexImageTaskRequest(
imagesUrls=["https://i.postimg.cc/yYjg75Kv/payloadtraffic.jpg"], # 替换为实际值
metadata={
"Task": "Click on traffic lights",
"Grid": "3x3",
"TaskDefinition": "/m/015qff",
}
)
async def solve_captcha():
# 如有需要,可以检查余额
balance = await cap_monster_client.get_balance()
print("Balance:", balance)
solution = await cap_monster_client.solve_captcha(complex_image_recaptcha_request)
return solution
responses = asyncio.run(solve_captcha())
print(responses)
显示代码
// https://github.com/ZennoLab/capmonstercloud-client-dotnet
using System;
using System.Threading.Tasks;
using Zennolab.CapMonsterCloud.Requests;
using Zennolab.CapMonsterCloud;
class Program
{
static async Task Main(string[] args)
{
var clientOptions = new ClientOptions
{
ClientKey = "YOUR_API_KEY" // 输入您的 CapMonster Cloud API 密钥
};
var cmCloudClient = CapMonsterCloudClientFactory.Create(clientOptions);
// 如有必要,可以检查余额
var balance = await cmCloudClient.GetBalanceAsync();
Console.WriteLine("Balance: " + balance);
var complexImageRecaptchaRequest = new RecaptchaComplexImageTaskRequest
{
ImageUrls = new[] { "https://i.postimg.cc/yYjg75Kv/payloadtraffic.jpg" }, // 替换为实际值
Metadata = new RecaptchaComplexImageTaskRequest.RecaptchaMetadata
{
Task = "Click on traffic lights",
Grid = RecaptchaComplexImageTaskRequest.RecaptchaMetadata.GridSize.Grid3x3,
TaskDefinition = "/m/015qff"
}
};
var complexImageRecaptchaResult = await cmCloudClient.SolveAsync(complexImageRecaptchaRequest);
Console.WriteLine("Captcha Solution: " + string.Join(", ", complexImageRecaptchaResult.Solution.Answer));
}
}


