Captcha solving service blog | SolveCaptcha How to bypass Chinese captcha using solver

How to bypass Chinese captcha with solver

Chinese captchas often contain distorted Chinese characters that must be entered into a text field. Standard OCR tools may struggle with these images because of unusual fonts, overlapping symbols, noise, rotation, and low contrast.

The SolveCaptcha Chinese captcha solver can recognize Chinese characters from an image and return the answer as text through the SolveCaptcha API.

The integration consists of four steps:

  1. Extract the original captcha image.
  2. Send the image to SolveCaptcha with lang=zh.
  3. Poll the API until recognition is complete.
  4. Insert the returned Chinese text into the captcha field.

Use this method only on websites you own or are authorized to test and automate.

What is a Chinese captcha?

A Chinese captcha is usually an image containing one or more Chinese characters.

Examples may include:

汉字
验证码
安全验证

The characters may be modified using:

  • background noise;
  • curved lines;
  • rotation;
  • overlapping symbols;
  • unusual fonts;
  • reduced contrast;
  • image distortion.

The answer returned by SolveCaptcha is a UTF-8 text string that should be entered exactly as recognized.

SolveCaptcha API workflow

SolveCaptcha uses two API endpoints.

Submit the image:

POST https://api.solvecaptcha.com/in.php

Retrieve the result:

GET https://api.solvecaptcha.com/res.php

For a Base64-encoded image, use:

method=base64

For a multipart file upload, use:

method=post

To route the task to workers who can read Chinese, add:

lang=zh

Do not use:

languagePool=zh

languagePool belongs to a different API format. The documented SolveCaptcha parameter is lang.

Required parameters

Submitting a Base64 image

Parameter Required Description
key Yes Your SolveCaptcha API key
method Yes Set to base64
body Yes Base64-encoded image
lang Recommended Set to zh for Chinese
json No Set to 1 for JSON responses
phrase No Set to 1 when the image contains multiple words
min_len No Minimum expected number of characters
max_len No Maximum expected number of characters
textinstructions No Additional instructions for recognition

Retrieving the answer

Parameter Required Description
key Yes Your SolveCaptcha API key
action Yes Set to get
id Yes Task ID returned by in.php
json No Set to 1 for JSON responses

Image requirements

Supported image formats include:

jpg
jpeg
png
gif

The maximum supported file size is:

100 kB

For the best recognition quality:

  • submit the original captcha image;
  • avoid screenshots containing unrelated page elements;
  • do not enlarge a small image artificially;
  • avoid unnecessary compression;
  • preserve the original colors;
  • do not crop characters;
  • verify that the image is not empty;
  • use the correct expected character length when known.

A clean original image generally produces better results than a resized screenshot.

Step 1: Get your API key

Create a SolveCaptcha account and open the account settings.

Copy your API key. It looks similar to:

1abc234de56fab7c89012d34e56fa7b8

Store it in an environment variable rather than placing it directly in source code.

Linux or macOS:

export SOLVECAPTCHA_API_KEY="YOUR_API_KEY"

Windows PowerShell:

$env:SOLVECAPTCHA_API_KEY="YOUR_API_KEY"

Step 2: Convert the captcha image to Base64

Python example:

import base64
from pathlib import Path

image_path = Path("chinese-captcha.png")

image_base64 = base64.b64encode(
    image_path.read_bytes()
).decode("ascii")

print(image_base64)

The resulting value can be submitted through the body parameter.

Do not include a data URL prefix such as:

data:image/png;base64,

Send only the Base64 image content.

Step 3: Submit the image

Example cURL request:

curl --request POST \
  --url https://api.solvecaptcha.com/in.php \
  --data-urlencode "key=YOUR_API_KEY" \
  --data-urlencode "method=base64" \
  --data-urlencode "body=BASE64_IMAGE" \
  --data-urlencode "lang=zh" \
  --data-urlencode "min_len=2" \
  --data-urlencode "max_len=6" \
  --data-urlencode "textinstructions=Enter all Chinese characters exactly as shown" \
  --data-urlencode "json=1"

A successful response contains the task ID:

{
  "status": 1,
  "request": "2122988149"
}

Save the request value. It is required to retrieve the answer.

If task creation fails, the API returns an error code:

{
  "status": 0,
  "request": "ERROR_CODE"
}

Step 4: Retrieve the recognized text

Wait approximately five seconds before requesting the result.

Example:

curl "https://api.solvecaptcha.com/res.php?key=YOUR_API_KEY&action=get&id=2122988149&json=1"

If recognition is still in progress:

{
  "status": 0,
  "request": "CAPCHA_NOT_READY"
}

Wait five seconds and repeat the request using the same task ID.

When recognition is complete:

{
  "status": 1,
  "request": "汉字"
}

The request value contains the recognized Chinese text.

Complete Python example

Install Requests:

python -m pip install requests

Create solve_chinese_captcha.py:

#!/usr/bin/env python3

from __future__ import annotations

import base64
import os
import time
from pathlib import Path
from typing import Any

import requests

CREATE_TASK_URL = (
    "https://api.solvecaptcha.com/in.php"
)

GET_RESULT_URL = (
    "https://api.solvecaptcha.com/res.php"
)

POLL_INTERVAL_SECONDS = 5
MAX_WAIT_SECONDS = 120

class SolveCaptchaError(RuntimeError):
    """Raised when SolveCaptcha returns an API error."""

def parse_response(
    response: requests.Response,
) -> dict[str, Any]:
    response.raise_for_status()

    try:
        result = response.json()
    except ValueError as exc:
        raise SolveCaptchaError(
            "SolveCaptcha returned invalid JSON: "
            f"{response.text[:500]}"
        ) from exc

    if not isinstance(result, dict):
        raise SolveCaptchaError(
            f"Unexpected API response: {result!r}"
        )

    return result

def encode_image(
    image_path: Path,
) -> str:
    if not image_path.is_file():
        raise FileNotFoundError(
            f"Image not found: {image_path}"
        )

    image_size = image_path.stat().st_size

    if image_size == 0:
        raise ValueError(
            "Captcha image is empty"
        )

    if image_size > 100 * 1024:
        raise ValueError(
            "Captcha image exceeds 100 kB"
        )

    supported_extensions = {
        ".jpg",
        ".jpeg",
        ".png",
        ".gif",
    }

    if (
        image_path.suffix.lower()
        not in supported_extensions
    ):
        raise ValueError(
            "Supported formats: "
            "jpg, jpeg, png, gif"
        )

    return base64.b64encode(
        image_path.read_bytes()
    ).decode("ascii")

def create_task(
    session: requests.Session,
    *,
    api_key: str,
    image_base64: str,
    min_length: int | None = None,
    max_length: int | None = None,
) -> str:
    payload: dict[str, str | int] = {
        "key": api_key,
        "method": "base64",
        "body": image_base64,
        "lang": "zh",
        "textinstructions": (
            "Enter all Chinese characters "
            "exactly as shown"
        ),
        "json": 1,
    }

    if min_length is not None:
        payload["min_len"] = min_length

    if max_length is not None:
        payload["max_len"] = max_length

    response = session.post(
        CREATE_TASK_URL,
        data=payload,
        timeout=30,
    )

    result = parse_response(response)

    if result.get("status") != 1:
        raise SolveCaptchaError(
            "Task creation failed: "
            f"{result.get('request')}"
        )

    task_id = str(
        result.get("request", "")
    ).strip()

    if not task_id:
        raise SolveCaptchaError(
            "SolveCaptcha did not return "
            "a task ID"
        )

    return task_id

def get_result(
    session: requests.Session,
    *,
    api_key: str,
    task_id: str,
) -> str | None:
    response = session.get(
        GET_RESULT_URL,
        params={
            "key": api_key,
            "action": "get",
            "id": task_id,
            "json": 1,
        },
        timeout=30,
    )

    result = parse_response(response)

    if result.get("status") == 1:
        answer = str(
            result.get("request", "")
        ).strip()

        if not answer:
            raise SolveCaptchaError(
                "SolveCaptcha returned "
                "an empty answer"
            )

        return answer

    error_code = str(
        result.get(
            "request",
            "UNKNOWN_ERROR",
        )
    )

    if error_code == "CAPCHA_NOT_READY":
        return None

    raise SolveCaptchaError(
        f"Task {task_id} failed: "
        f"{error_code}"
    )

def solve_chinese_captcha(
    image_path: Path,
    api_key: str,
    *,
    min_length: int | None = None,
    max_length: int | None = None,
) -> tuple[str, str]:
    image_base64 = encode_image(
        image_path
    )

    session = requests.Session()

    task_id = create_task(
        session,
        api_key=api_key,
        image_base64=image_base64,
        min_length=min_length,
        max_length=max_length,
    )

    deadline = (
        time.monotonic()
        + MAX_WAIT_SECONDS
    )

    while time.monotonic() < deadline:
        time.sleep(
            POLL_INTERVAL_SECONDS
        )

        answer = get_result(
            session,
            api_key=api_key,
            task_id=task_id,
        )

        if answer is not None:
            return task_id, answer

    raise TimeoutError(
        f"Task {task_id} was not completed "
        f"within {MAX_WAIT_SECONDS} seconds"
    )

def report_result(
    *,
    api_key: str,
    task_id: str,
    accepted: bool,
) -> None:
    action = (
        "reportgood"
        if accepted
        else "reportbad"
    )

    response = requests.get(
        GET_RESULT_URL,
        params={
            "key": api_key,
            "action": action,
            "id": task_id,
            "json": 1,
        },
        timeout=30,
    )

    result = parse_response(response)

    if result.get("status") != 1:
        raise SolveCaptchaError(
            "Unable to report result: "
            f"{result.get('request')}"
        )

def main() -> None:
    api_key = os.environ.get(
        "SOLVECAPTCHA_API_KEY",
        "",
    ).strip()

    if not api_key:
        raise SystemExit(
            "Set SOLVECAPTCHA_API_KEY"
        )

    image_path = Path(
        "chinese-captcha.png"
    )

    task_id, answer = (
        solve_chinese_captcha(
            image_path,
            api_key,
            min_length=2,
            max_length=6,
        )
    )

    print("Task ID:", task_id)
    print("Answer:", answer)

    # Submit the answer to the target form.
    accepted = True

    report_result(
        api_key=api_key,
        task_id=task_id,
        accepted=accepted,
    )

if __name__ == "__main__":
    main()

Run the script:

python solve_chinese_captcha.py

Example output:

Task ID: 2122988149
Answer: 汉字

Python 3 handles Chinese text as Unicode, so the returned answer can be printed, stored, or submitted without manual conversion.

Upload the image as multipart form data

Base64 is not required. You can upload the image directly using:

method=post

Example:

import os

import requests

api_key = os.environ[
    "SOLVECAPTCHA_API_KEY"
]

with open(
    "chinese-captcha.png",
    "rb",
) as image:
    response = requests.post(
        "https://api.solvecaptcha.com/in.php",
        data={
            "key": api_key,
            "method": "post",
            "lang": "zh",
            "textinstructions": (
                "Enter all Chinese characters "
                "exactly as shown"
            ),
            "json": 1,
        },
        files={
            "file": image,
        },
        timeout=30,
    )

response.raise_for_status()
print(response.json())

A successful response again contains the task ID in:

request

The result is retrieved through the same res.php endpoint.

Apply the answer on the page

A Chinese image captcha normally has an associated text input.

Example HTML:

<input
  type="text"
  name="captcha"
  autocomplete="off"
>

With Selenium:

from selenium.webdriver.common.by import By

captcha_field = driver.find_element(
    By.NAME,
    "captcha",
)

captcha_field.clear()
captcha_field.send_keys(answer)

With Playwright:

await page
  .locator('input[name="captcha"]')
  .fill(answer);

Submit the answer in the same browser session where the captcha image was generated.

Do not:

  • refresh the captcha before submitting;
  • reuse an answer for a new image;
  • change the browser session;
  • submit the answer after the challenge expires.

If the image changes, create a new SolveCaptcha task.

Reporting recognition results

After submitting the answer, report whether it was accepted.

Accepted answer:

https://api.solvecaptcha.com/res.php?key=YOUR_API_KEY&action=reportgood&id=TASK_ID

Incorrect answer:

https://api.solvecaptcha.com/res.php?key=YOUR_API_KEY&action=reportbad&id=TASK_ID

Use reportgood when:

  • the website accepts the text;
  • the protected form continues;
  • no captcha error is displayed.

Use reportbad only when the recognized text itself is incorrect.

Do not report an answer as incorrect when the failure was caused by:

  • an expired captcha;
  • a refreshed image;
  • an incorrect input selector;
  • a changed session;
  • another invalid form field;
  • application validation unrelated to captcha.

Reports improve recognition quality and help identify consistently incorrect answers.

Common errors

ERROR_WRONG_USER_KEY

The API key is invalid.

Copy the key again from the SolveCaptcha settings.

ERROR_ZERO_BALANCE

The account balance is insufficient.

Add funds before creating another task.

ERROR_ZERO_CAPTCHA_FILESIZE

The submitted image is empty.

Verify that the image was downloaded correctly before encoding it.

ERROR_TOO_BIG_CAPTCHA_FILESIZE

The image is larger than:

100 kB

Use the original captcha image where possible. If resizing is unavoidable, preserve character clarity and aspect ratio.

ERROR_WRONG_FILE_EXTENSION

The file extension is unsupported.

Use:

jpg
jpeg
png
gif

ERROR_IMAGE_TYPE_NOT_SUPPORTED

The file contents do not match a supported image format.

Verify that the downloaded response is an actual image rather than:

  • an HTML error page;
  • JSON;
  • a redirect response;
  • an empty file.

CAPCHA_NOT_READY

Recognition is still in progress.

Wait five seconds and request the result again using the same task ID.

Incorrect Chinese characters

Check that:

lang=zh

was included in the submission.

Also verify:

  • the complete image was uploaded;
  • no characters were cropped;
  • the expected length is correct;
  • the image is readable;
  • instructions do not contradict the image.

lang and language are different parameters

For Chinese recognition, use:

lang=zh

The older numeric language parameter only distinguishes between:

1 = Cyrillic
2 = Latin

It is not suitable for Chinese characters.

Incorrect:

language=zh

Correct:

lang=zh

Improve recognition quality

Specify the language

Always submit:

lang=zh

This routes the task to workers who support Chinese.

Set the expected length

When the captcha always contains four characters, add:

min_len=4
max_len=4

Do not set an incorrect length. It can prevent a correct answer from being returned.

Provide clear instructions

Example:

Enter all Chinese characters exactly as shown

Other possible instructions include:

Enter only the red Chinese characters
Ignore numbers and enter Chinese characters only

Keep instructions short and unambiguous.

Preserve the original image

Do not apply aggressive:

  • sharpening;
  • thresholding;
  • scaling;
  • color removal;
  • JPEG compression.

Image processing can remove character strokes that are essential for Chinese recognition.

Validate the downloaded content

Before submitting an automatically downloaded image, check:

  • HTTP status;
  • Content-Type;
  • file size;
  • image signature;
  • session cookies;
  • Referer requirements.

A captcha endpoint may return an error page instead of an image when called outside the active browser session.

Frequently asked questions

Which SolveCaptcha method should I use?

For a Base64 image:

method=base64

For multipart upload:

method=post

Which parameter specifies Chinese?

Use:

lang=zh

Which endpoints should I use?

Submit the image:

https://api.solvecaptcha.com/in.php

Retrieve the answer:

https://api.solvecaptcha.com/res.php

Can I use ImageToTextTask?

The documented SolveCaptcha integration in this guide uses in.php with method=base64 or method=post.

Do not use unsupported API names such as:

ImageToTextTask
createTask
getTaskResult
languagePool

How often should I request the result?

Wait approximately five seconds between result requests.

Where is the recognized text returned?

With json=1, the answer is returned in:

request

Example:

{
  "status": 1,
  "request": "验证码"
}

Can SolveCaptcha recognize simplified and traditional Chinese?

The API routes lang=zh tasks to workers who support Chinese. Recognition depends on image quality and the worker’s ability to read the characters shown.

Should I submit a screenshot?

Submit the original captcha image whenever possible. A screenshot may introduce scaling, unrelated elements, or reduced clarity.

Can I reuse an answer?

No. Each answer belongs to the specific image submitted with the task.

Should I report results?

Yes. Use reportgood for accepted answers and reportbad only for genuinely incorrect recognition.

Conclusion

Solving a Chinese image captcha with SolveCaptcha requires the standard image-recognition workflow:

  1. Obtain the original captcha image.
  2. Encode it in Base64 or upload it as multipart form data.
  3. Submit it to https://api.solvecaptcha.com/in.php.
  4. Use method=base64 or method=post.
  5. Add lang=zh.
  6. Save the returned task ID.
  7. Poll https://api.solvecaptcha.com/res.php.
  8. Wait five seconds when the response is CAPCHA_NOT_READY.
  9. Insert the returned Chinese text into the captcha field.
  10. Report whether the answer was accepted.

Use the SolveCaptcha API documentation for the complete image captcha parameter list and the Chinese captcha solver for service details.