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:
- Extract the original captcha image.
- Send the image to SolveCaptcha with
lang=zh. - Poll the API until recognition is complete.
- 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:
- Obtain the original captcha image.
- Encode it in Base64 or upload it as multipart form data.
- Submit it to
https://api.solvecaptcha.com/in.php. - Use
method=base64ormethod=post. - Add
lang=zh. - Save the returned task ID.
- Poll
https://api.solvecaptcha.com/res.php. - Wait five seconds when the response is
CAPCHA_NOT_READY. - Insert the returned Chinese text into the captcha field.
- 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.