Ada tiga hal yang menentukan apakah scraper Anda lolos di situs berbahasa Mandarin: OCR yang benar-benar mengenali aksara Han, solver GeeTest v3 untuk teka-teki geser, dan disiplin sesi plus encoding di sisi kode Anda. CaptchaAI menutup dua bagian pertama lewat satu API; bagian ketiga tetap tanggung jawab skrip Anda, dan di situlah sebagian besar kegagalan terjadi.
Halaman ini merangkum polanya: mengirim image CAPTCHA aksara Han ke in.php dengan language=2, memasok gt dan challenge untuk GeeTest v3, lalu membaca hasilnya tanpa merusak teks UTF-8.
Tiga hal yang paling sering menggagalkan solve
- Encoding yang tidak konsisten. Respons dibaca sebagai Latin-1, dan hasil OCR yang sebenarnya benar berubah menjadi karakter kacau.
- Sesi yang terputus. Gambar diambil lewat satu koneksi, form dikirim lewat koneksi lain, dan server menolak token yang sah.
- Masa berlaku yang pendek. Nilai
challengeGeeTest v3 hanya hidup beberapa detik, jadi ekstrak dan kirim segera.
Peta jenis CAPTCHA di situs web China
| Jenis CAPTCHA | Di mana Anda menemuinya | Penanganan di CaptchaAI |
|---|---|---|
| Image aksara Han | Portal pemerintah, database akademis | Image/OCR dengan language=2 |
| Soal aritmatika berbahasa Mandarin | Form pendaftaran | Image/OCR |
| Teka-teki geser GeeTest v3 | Baidu, Bilibili, banyak platform besar | GeeTest v3 |
| Klik karakter sesuai urutan | "Klik aksara Han secara berurutan" | Image/OCR (mode koordinat) |
| reCAPTCHA v2 | Versi internasional situs yang sama | reCAPTCHA v2 |
| GeeTest v4 | Platform yang sudah migrasi dari v3 | Belum didukung, segera hadir |
| Tencent Captcha | Layanan di ekosistem Tencent | Belum didukung |
Dua baris terakhir penting saat merencanakan: kalau target Anda sudah pindah ke GeeTest v4 atau memakai solusi Tencent, siapkan jalur manual. Untuk widget ber-callback JavaScript di versi internasional, polanya berbeda dan dibahas di panduan callback reCAPTCHA v2.
Alur kerja yang sama untuk semua tipe
Apa pun jenis tantangannya, empat langkahnya identik:
- Kirim tantangan ke
in.phpbeserta parameter tipenya (method=base64untuk gambar,method=geetestuntuk teka-teki geser). - Simpan task ID yang dikembalikan pada field
request. - Polling
res.phpsetiap 5 detik sampai statusnya bukan lagiCAPCHA_NOT_READY. - Pakai teks atau token hasilnya di form dan sesi yang sama.
Jeda polling 5 detik adalah titik tengah yang aman: terlalu rapat hanya menambah request, terlalu longgar membuat challenge GeeTest keburu kedaluwarsa. Kalau worker Anda berjalan di AWS ap-southeast-3 (Jakarta) atau ap-southeast-1 (Singapura), tambahkan margin batas waktu untuk latensi lintas wilayah, bukan mempersingkat interval polling.
Python: OCR aksara Han dan GeeTest v3 dalam satu modul
Modul berikut menangani gambar yang sudah ada di disk maupun gambar yang harus diunduh lebih dulu. Fungsi kedua memakai objek Session yang sama, sehingga cookie sesi tetap utuh saat form dikirim. Kalau alur OCR masih baru bagi Anda, mulai dari dasar image CAPTCHA dengan OCR Python.
import requests
import base64
import time
API_KEY = "YOUR_API_KEY"
SUBMIT_URL = "https://ocr.captchaai.com/in.php"
RESULT_URL = "https://ocr.captchaai.com/res.php"
def solve_chinese_image_captcha(image_path: str) -> str:
"""Solve a Chinese character image CAPTCHA."""
with open(image_path, "rb") as f:
image_b64 = base64.b64encode(f.read()).decode()
resp = requests.post(SUBMIT_URL, data={
"key": API_KEY,
"method": "base64",
"body": image_b64,
"language": 2, # 2 = Chinese characters supported
"json": 1,
}, timeout=30).json()
if resp.get("status") != 1:
raise RuntimeError(f"Submit failed: {resp.get('request')}")
task_id = resp["request"]
start = time.monotonic()
while time.monotonic() - start < 120:
time.sleep(5)
poll = requests.get(RESULT_URL, params={
"key": API_KEY, "action": "get",
"id": task_id, "json": 1,
}, timeout=15).json()
if poll.get("request") == "CAPCHA_NOT_READY":
continue
if poll.get("status") == 1:
return poll["request"]
raise RuntimeError(f"Solve failed: {poll.get('request')}")
raise RuntimeError("Timeout")
def solve_chinese_captcha_from_url(captcha_url: str, cookies: dict = None) -> str:
"""Download and solve a Chinese CAPTCHA from a URL."""
session = requests.Session()
if cookies:
session.cookies.update(cookies)
resp = session.get(captcha_url, timeout=15)
image_b64 = base64.b64encode(resp.content).decode()
submit = requests.post(SUBMIT_URL, data={
"key": API_KEY,
"method": "base64",
"body": image_b64,
"language": 2,
"json": 1,
}, timeout=30).json()
if submit.get("status") != 1:
raise RuntimeError(f"Submit: {submit.get('request')}")
task_id = submit["request"]
for _ in range(24):
time.sleep(5)
poll = requests.get(RESULT_URL, params={
"key": API_KEY, "action": "get", "id": task_id, "json": 1,
}, timeout=15).json()
if poll.get("request") == "CAPCHA_NOT_READY":
continue
if poll.get("status") == 1:
return poll["request"]
raise RuntimeError(f"Solve: {poll.get('request')}")
raise RuntimeError("Timeout")
# --- GeeTest on Chinese platforms ---
def solve_geetest_chinese(gt: str, challenge: str, pageurl: str) -> dict:
"""Solve GeeTest v3 commonly found on Baidu, Bilibili, etc."""
resp = requests.post(SUBMIT_URL, data={
"key": API_KEY,
"method": "geetest",
"gt": gt,
"challenge": challenge,
"pageurl": pageurl,
"json": 1,
}, timeout=30).json()
if resp.get("status") != 1:
raise RuntimeError(f"Submit: {resp.get('request')}")
task_id = resp["request"]
for _ in range(36):
time.sleep(5)
poll = requests.get(RESULT_URL, params={
"key": API_KEY, "action": "get", "id": task_id, "json": 1,
}, timeout=15).json()
if poll.get("request") == "CAPCHA_NOT_READY":
continue
if poll.get("status") == 1:
# GeeTest returns challenge, validate, seccode
return poll["request"]
raise RuntimeError(f"Solve: {poll.get('request')}")
raise RuntimeError("Timeout")
# Usage — Chinese government portal
text = solve_chinese_image_captcha("chinese_captcha.png")
print(f"Chinese CAPTCHA text: {text}")
# GeeTest on a Chinese platform
geetest_result = solve_geetest_chinese(
gt="b46d1900d0a894591f1561f8c35670a7",
challenge="dynamic_challenge_string",
pageurl="https://www.example.cn/login",
)
Node.js: alur yang sama untuk pipeline JavaScript
Untuk pipeline Node.js strukturnya sama: satu POST ke in.php, lalu polling res.php dengan jeda tetap. Batas iterasinya berbeda karena GeeTest v3 butuh waktu lebih lama daripada image CAPTCHA biasa.
const API_KEY = "YOUR_API_KEY";
const SUBMIT_URL = "https://ocr.captchaai.com/in.php";
const RESULT_URL = "https://ocr.captchaai.com/res.php";
const fs = require("fs");
async function solveChineseImageCaptcha(imagePath) {
const imageB64 = fs.readFileSync(imagePath, "base64");
const body = new URLSearchParams({
key: API_KEY,
method: "base64",
body: imageB64,
language: "2",
json: "1",
});
const resp = await (await fetch(SUBMIT_URL, { method: "POST", body })).json();
if (resp.status !== 1) throw new Error(`Submit: ${resp.request}`);
const taskId = resp.request;
for (let i = 0; i < 24; i++) {
await new Promise((r) => setTimeout(r, 5000));
const url = `${RESULT_URL}?key=${API_KEY}&action=get&id=${taskId}&json=1`;
const poll = await (await fetch(url)).json();
if (poll.request === "CAPCHA_NOT_READY") continue;
if (poll.status === 1) return poll.request;
throw new Error(`Solve: ${poll.request}`);
}
throw new Error("Timeout");
}
async function solveGeeTest(gt, challenge, pageurl) {
const body = new URLSearchParams({
key: API_KEY,
method: "geetest",
gt,
challenge,
pageurl,
json: "1",
});
const resp = await (await fetch(SUBMIT_URL, { method: "POST", body })).json();
if (resp.status !== 1) throw new Error(`Submit: ${resp.request}`);
const taskId = resp.request;
for (let i = 0; i < 36; i++) {
await new Promise((r) => setTimeout(r, 5000));
const url = `${RESULT_URL}?key=${API_KEY}&action=get&id=${taskId}&json=1`;
const poll = await (await fetch(url)).json();
if (poll.request === "CAPCHA_NOT_READY") continue;
if (poll.status === 1) return poll.request;
throw new Error(`Solve: ${poll.request}`);
}
throw new Error("Timeout");
}
// Usage
const text = await solveChineseImageCaptcha("chinese_captcha.png");
console.log(`Chinese text: ${text}`);
Encoding, sesi, dan jebakan lain saat scraping situs China
| Tantangan | Penanganan |
|---|---|
| Aksara tampil sebagai karakter kacau | Perlakukan request dan respons sebagai UTF-8, bukan encoding default |
| Halaman menuntut cookie sesi | Ambil gambar CAPTCHA di dalam sesi yang sama dengan pengiriman form |
| Parameter GeeTest tersembunyi di JavaScript | Ekstrak gt dan challenge dari skrip halaman atau endpoint API-nya |
| Pembatasan laju permintaan (rate limiting) oleh CDN | Turunkan laju permintaan dan pakai egress jaringan yang diotorisasi di wilayah target |
| Gambar berganti tiap kali halaman dimuat | Unduh gambar sekali, selesaikan, lalu kirim - jangan muat ulang |
Kalau gambar mencampur aksara Han dengan huruf Latin dan angka, atur set karakternya secara eksplisit; detailnya ada di konfigurasi character set multi-bahasa dan pengaturan bahasa dan lokalisasi CAPTCHA.
Diagnosis cepat ketika hasil solve meleset
| Gejala | Penyebab | Perbaikan |
|---|---|---|
| Teks hasil solve tampil kacau di log | Ketidakcocokan encoding | Baca respons sebagai UTF-8 sebelum mencetaknya |
challenge GeeTest ditolak |
TTL tantangan sudah lewat | Ekstrak dan kirim dalam hitungan detik setelah halaman dimuat |
| Hasil OCR tertukar antara Latin dan Han | Gambar mencampur dua sistem tulisan | Atur language=2 agar pengenalan aksara Han aktif |
| Sesi ditolak padahal token benar | Cookie tidak dipertahankan | Pakai satu sesi untuk ambil gambar dan kirim form |
| Akurasi turun di portal pemerintah | Rendering aksara rapat dan tipis | Kirim gambar pada resolusi aslinya, jangan diperkecil |
Berapa thread yang Anda butuhkan
CaptchaAI menagih per thread bersamaan, bukan per solve, dan setiap paket memberi solve tanpa batas selama bulan berjalan. Satu thread berarti satu CAPTCHA yang sedang diproses; begitu selesai, thread itu bebas untuk tantangan berikutnya.
- BASIC ($15/bulan, 5 thread) cukup untuk pekerjaan freelance dan riset berkala yang jalan beberapa jam sehari.
- STANDARD ($30/bulan, 15 thread) masuk akal ketika beberapa worker berjalan paralel sepanjang hari.
- ADVANCE ($90/bulan, 50 thread) untuk pipeline harian yang menyentuh banyak sumber.
Kapasitasnya bisa diperkirakan dari batas waktu per tipe: image CAPTCHA di bawah 0.5 detik, GeeTest v3 di bawah 12 detik. Untuk agensi price monitoring, kontraktor scraping lepas, dan tim data startup di Indonesia yang menghitung biaya per bulan, model biaya tetap ini lebih mudah dianggarkan daripada tarif per solve. Harga selalu dalam USD.
Batas data yang perlu Anda hormati
Menyelesaikan CAPTCHA adalah persoalan teknis; legalitas datanya persoalan lain. Di Indonesia, UU Pelindungan Data Pribadi (UU 27/2022) dan UU ITE membuat pengambilan data pribadi tanpa dasar yang jelas menjadi berisiko, jadi batasi diri pada data publik yang boleh Anda proses. Ini bukan nasihat hukum.
Pertanyaan yang sering muncul
Apakah CaptchaAI mengenali aksara sederhana dan tradisional?
Ya. Solver Image/OCR menangani aksara Han sederhana maupun tradisional; atur language=2 untuk mengaktifkannya. Basis pengenalannya mencakup lebih dari 27.500 varian image CAPTCHA lintas bahasa.
Berapa lama satu image CAPTCHA aksara Han biasanya selesai?
Image CAPTCHA diselesaikan di bawah 0.5 detik dan GeeTest v3 di bawah 12 detik. Angka itu batas layanan, bukan rata-rata, dan belum termasuk latensi jaringan.
Apakah GeeTest v4 sudah bisa diselesaikan?
Belum. GeeTest v4 berstatus segera hadir dan tidak tersedia saat ini. Kalau situs sumber sudah pindah ke v4, siapkan jalur penanganan manual sampai dukungannya dirilis.
Berapa thread yang cukup untuk pekerjaan scraping skala kecil?
Untuk satu atau dua worker beberapa jam sehari, BASIC ($15/bulan, 5 thread) umumnya memadai. Naikkan ke STANDARD ($30/bulan, 15 thread) begitu antrean task menumpuk dan waktu tunggu terasa di worker.
Kenapa hasil OCR saya tercampur huruf Latin dan aksara Han?
Biasanya parameter bahasa belum diatur, atau gambar memuat dua sistem tulisan sekaligus. Atur language=2 dan kirim gambar pada resolusi aslinya sebelum menyimpulkan gambar itu tidak terbaca.
Bacaan lanjutan
- Menyelesaikan CAPTCHA dengan Ruby dan API CaptchaAI
- Menyelesaikan CAPTCHA dengan Scala dan API CaptchaAI
Langkah selanjutnya
Mulai dari satu gambar: ambil satu image CAPTCHA aksara Han, jalankan modul Python di atas, dan pastikan teksnya tampil utuh di terminal. Sisanya tinggal menyambungkan ke worker Anda - ambil API key CaptchaAI Anda.