Перейти к основному содержимому
Возникают проблемы с получением токена?
Свяжитесь с поддержкой

portugal_text_find_icon

Внимание!

Использование прокси-серверов для данной задачи не требуется.


В запросе необходимо передать одно изображение в формате base64, представляющее собой 5 горизонтально объединённых изображений (без текста), расположенных в порядке их отображения. Подробный пример склейки приведён ниже. Дополнительно в параметре TaskArgument указывается текст задания — выбор нужной иконки.

Параметры запроса


ВАЖНО: получайте base64 готового изображения непосредственно перед созданием задачи, чтобы избежать ошибок при решении (см. раздел Примеры автоматического распознавания и решения).


type<string>required

ComplexImageTask


class<string>required

recognition


imagesBase64<array>required

Изображение в кодировке base64.


Task (внутри metadata)<string>required

Название задания: "portugal_text_find_icon"


TaskArgument (внутри metadata)<string>required

Текст задания, который указывает, какую иконку нужно найти. Например: "Clique no(a) quadrado."

Важно: некоторые символы в тексте задания необходимо сериализованно экранировать, чтобы избежать ошибок при обработке и решении задачи. Например, для текста "Por favor, clique no(a) avião." необходимо передать строку "Por favor, clique no(a) avi\\u00E3o." (см. пример в разделе Примеры автоматического распознавания и решения).

Создание задачи

POST
https://api.capmonster.cloud/createTask

Запрос

{
"clientKey": "API_KEY",
"task": {
"type": "ComplexImageTask",
"class": "recognition",
"imagesBase64": [
"iVBORw0KGgoAAAA...SuQmCC"
],
"metadata": {
"Task": "portugal_text_find_icon",
"TaskArgument": "Encontre o(a) avi\\u00E3o."
}
}
}

Ответ

{
"errorId":0,
"taskId":143998457
}

Пример задания:

В примере представлены 5 иконок и текст задания: "Encontre o(a) avião." (Найдите самолёт).

Передавать нужно картинку в формате base64, которая представляет собой горизонтально объединённые 5 изображений-иконок:

Получение результата задачи

POST
https://api.capmonster.cloud/getTaskResult

Запрос

{
"clientKey":"API_KEY",
"taskId": 143998457
}

Ответ: возвращаемый индекс — это номер иконки, по которой необходимо выполнить клик. Нумерация иконок начинается с 1 и заканчивается 5:

{
"solution": {
"answer": [4],
"metadata": {
"AnswerType": "NumericArray"
}
},
"status": "ready",
"errorId": 0,
"errorCode": null,
"errorDescription": null
}

Примеры автоматического распознавания и решения

Примеры на Python с использованием requests и Playwright, демонстрирующие полный процесс работы с капчей: от получения задания и извлечения изображений до их обработки, подготовки и отправки в CapMonster Cloud для распознавания, а также получения итогового результата.

Важно

Примеры носят демонстрационный характер и показывают общую логику работы с вашим сайтом. В реальных проектах код может потребовать адаптации под конкретный сайт, его запросы и заголовки.

Важные данные (API‑ключи, настройки прокси и т.п.) рекомендуется хранить в .env или переменных окружения.

Показать код
import os
import io
import time
import base64
import csv
import json
import re
import requests
from PIL import Image

# ===================== КОНФИГУРАЦИЯ =====================
# Рекомендуется хранить чувствительные данные в .env

# Базовый URL внутреннего API капчи
BASE = "https://www.example.com"

# CapMonster Cloud API
API_KEY = "YOUR_API_KEY"
CREATE_TASK_URL = "https://api.capmonster.cloud/createTask"
GET_RESULT_URL = "https://api.capmonster.cloud/getTaskResult"

# Заголовки для имитации браузерного запроса
HEADERS = {
"User-Agent": "userAgentPlaceholder",
"Referer": BASE + "/",
"Accept": "image/avif,image/webp,image/apng,image/*,*/*;q=0.8",
"Connection": "keep-alive"
}

# Директория для сохранения данных (изображения, логи, CSV)
SAVE_DIR = "captcha_results"
os.makedirs(SAVE_DIR, exist_ok=True)

session = requests.Session()
session.headers.update(HEADERS)

# ===================== УТИЛИТЫ =====================

def serialize_json(text):
"""
Преобразует строку в безопасный JSON-совместимый формат.
"""
json_str = json.dumps(text, ensure_ascii=True)[1:-1]
return re.sub(r'\\u([0-9a-f]{4})', lambda m: '\\u' + m.group(1).upper(), json_str)


def post_json(url, payload):
"""
Отправляет POST-запрос с JSON телом и возвращает ответ сервера.
"""
return requests.post(url, json=payload).json()

# ===================== ПОЛУЧЕНИЕ КАПЧИ =====================

def get_captcha():
"""
Запрашивает новую капчу с внутреннего API сайта.
"""
url = f"{BASE}/api.php?action=new"
res = session.get(url)
data = res.json()
print("[CAPTCHA]:", data)
return data


def build_image_urls(data):
"""
Формирует список URL изображений капчи на основе session и answers.
"""
return [
f"{BASE}/api.php?action=img&s={data['session']}&c={ans}"
for ans in data["answers"]
]

# ===================== РАБОТА С ИЗОБРАЖЕНИЯМИ =====================

def download_images(urls):
"""
Загружает изображения капчи по списку URL.
"""
images = []
for url in urls:
r = session.get(url)

if "image" not in r.headers.get("Content-Type", ""):
continue

if len(r.content) < 100:
continue

try:
img = Image.open(io.BytesIO(r.content)).convert("RGBA")
images.append(img)
except:
pass

return images


def merge_images(pil_images):
"""
Объединяет несколько изображений в одно (горизонтальная склейка).
"""
widths, heights = zip(*(img.size for img in pil_images))

result = Image.new("RGBA", (sum(widths), max(heights)))

x = 0
for img in pil_images:
result.paste(img, (x, 0))
x += img.size[0]

return result


def to_base64(img):
"""
Конвертирует изображение в base64 строку.
"""
buf = io.BytesIO()
img.save(buf, format="PNG")
return base64.b64encode(buf.getvalue()).decode()


def save_csv(prompt, urls):
"""
Сохраняет лог капчи (prompt + image URLs) в CSV файл.
"""
with open(os.path.join(SAVE_DIR, "captcha.csv"), "w", newline="", encoding="utf-8") as f:
writer = csv.writer(f)
writer.writerow(["prompt", "image_url"])
for url in urls:
writer.writerow([prompt, url])

# ===================== CAPMONSTER CLOUD API =====================

def create_task(base64_image, prompt):
"""
Создаёт задачу в CapMonster Cloud для распознавания изображения.
"""
payload = {
"clientKey": API_KEY,
"task": {
"type": "ComplexImageTask",
"class": "recognition",
"imagesBase64": [base64_image],
"metadata": {
"Task": "portugal_text_find_icon",
"TaskArgument": serialize_json(prompt)
}
}
}

res = post_json(CREATE_TASK_URL, payload)
print("[createTask]:", res)
return res.get("taskId")


def get_result(task_id):
"""
Ожидает завершения задачи и возвращает результат.
"""
while True:
time.sleep(2)

res = post_json(GET_RESULT_URL, {
"clientKey": API_KEY,
"taskId": task_id
})

if res.get("status") == "ready":
return res

print("[...] waiting for result...")

# ===================== ОСНОВНОЙ ПРОЦЕСС =====================

def main():

# получаем капчу
data = get_captcha()
prompt = data["question_i"]
print("[PROMPT]:", prompt)

# формируем URL изображений
urls = build_image_urls(data)
save_csv(prompt, urls)

# скачиваем изображения
images = download_images(urls)
if not images:
print("No images found")
return

# объединяем изображения в одно
merged = merge_images(images)

filepath = os.path.join(SAVE_DIR, f"captcha_{int(time.time())}.png")
merged.save(filepath)
print("[+] Saved image:", filepath)

# переводим изображение в base64
base64_img = to_base64(merged)

# создаём задачу в CapMonster Cloud
task_id = create_task(base64_img, prompt)
if not task_id:
print("createTask error")
return

print("[+] taskId:", task_id)

# получаем результат
result = get_result(task_id)

print("\n=== FULL RESULT ===")
print(json.dumps(result, indent=2, ensure_ascii=False))


if __name__ == "__main__":
main()