Skip to main content
Are you experiencing issues obtaining the token?
Contact support

portugal_text_find_icon

Attention!

Using proxy servers is not required for this task.


The request must contain a single image in base64 format, consisting of 5 horizontally merged images (without text) arranged in the order of their display. A detailed example of the stitching process is shown below. Additionally, the TaskArgument parameter specifies the task text — the target icon to find.

Request parameters


IMPORTANT: obtain the base64 image directly before creating the task to avoid errors during solving (see section Automated recognition and solving examples).


type<string>required

ComplexImageTask


class<string>required

recognition


imagesBase64<array>required

Image encoded in base64 format.


Task (inside metadata)<string>required

Task name: "portugal_text_find_icon"


TaskArgument (inside metadata)<string>required

Task text that defines which icon must be found. Example: "Clique no(a) quadrado."

Important: some characters in the task text must be properly escaped to avoid processing or solving errors. For example, for the text "Por favor, clique no(a) avião." you must pass "Por favor, clique no(a) avi\\u00E3o." (see example in section Automated recognition and solving examples).

Create task method

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

Request

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

Response

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

Example task:

The example shows 5 icons and the task text: "Encontre o(a) avião." (Find the airplane).

You must send an image in base64 format that represents 5 horizontally merged icon images:

Get task result method

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

Request

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

Response: the returned index is the number of the icon that must be clicked. Icon indexing starts from 1 and ends at 5:

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

Automated recognition and solving examples

Examples in Python using requests and Playwright, demonstrating the full captcha workflow: from retrieving the task and extracting images to processing, preparing, and sending them to CapMonster Cloud for recognition, as well as obtaining the final result.

Important

These examples are for demonstration purposes and illustrate the general logic of working with your website. In real projects, the code may require adaptation to a specific site, its requests, and headers.

Sensitive data (API keys, proxy settings, etc.) should be stored in .env files or environment variables.

Show code
import os
import io
import time
import base64
import csv
import json
import re
import requests
from PIL import Image

# ===================== CONFIGURATION =====================
# It is recommended to store sensitive data in .env

# Base URL of internal captcha 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 to simulate a real browser request
HEADERS = {
"User-Agent": "userAgentPlaceholder",
"Referer": BASE + "/",
"Accept": "image/avif,image/webp,image/apng,image/*,*/*;q=0.8",
"Connection": "keep-alive"
}

# Directory for saving data (images, logs, CSV)
SAVE_DIR = "captcha_results"
os.makedirs(SAVE_DIR, exist_ok=True)

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

# ===================== UTILITIES =====================

def serialize_json(text):
"""
Converts a string into a JSON-safe format.
"""
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):
"""
Sends a POST request with a JSON body and returns the server response.
"""
return requests.post(url, json=payload).json()

# ===================== CAPTCHA FETCHING =====================

def get_captcha():
"""
Requests a new captcha from the site internal 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):
"""
Builds a list of captcha image URLs based on session and answers.
"""
return [
f"{BASE}/api.php?action=img&s={data['session']}&c={ans}"
for ans in data["answers"]
]

# ===================== IMAGE PROCESSING =====================

def download_images(urls):
"""
Downloads captcha images from a list of URLs.
"""
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):
"""
Merges multiple images into one (horizontal concatenation).
"""
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):
"""
Converts an image to a base64 string.
"""
buf = io.BytesIO()
img.save(buf, format="PNG")
return base64.b64encode(buf.getvalue()).decode()


def save_csv(prompt, urls):
"""
Saves captcha log (prompt + image URLs) into a CSV file.
"""
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):
"""
Creates a CapMonster Cloud task for image recognition.
"""
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):
"""
Waits for task completion and returns the result.
"""
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...")

# ===================== MAIN PROCESS =====================

def main():

# fetch captcha
data = get_captcha()
prompt = data["question_i"]
print("[PROMPT]:", prompt)

# build image URLs
urls = build_image_urls(data)
save_csv(prompt, urls)

# download images
images = download_images(urls)
if not images:
print("No images found")
return

# merge images into one
merged = merge_images(images)

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

# convert image to base64
base64_img = to_base64(merged)

# create task in CapMonster Cloud
task_id = create_task(base64_img, prompt)
if not task_id:
print("createTask error")
return

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

# get result
result = get_result(task_id)

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


if __name__ == "__main__":
main()