Anda sudah mengirim ribuan task image CAPTCHA ke CaptchaAI minggu ini, tapi sebagian jawabannya meleset, dan Anda mulai curiga ke solver-nya. Cek dulu satu hal sebelum pindah provider: kualitas gambar yang Anda kirim. Di hampir semua kasus, itulah akar masalahnya — bukan solver, bukan API, melainkan gambar yang terpotong, buram, salah encoding, atau tanpa hint tambahan. Begitu Anda tahu pola-pola yang biasa terjadi, perbaikannya jauh lebih murah daripada ganti solver: cukup beberapa baris kode tambahan. Panduan ini membedah enam penyebab paling umum satu per satu, lengkap dengan fungsi Python siap pakai untuk validasi gambar, encoding base64, preprocessing, hint API, screenshot elemen presisi, dan penanganan CAPTCHA yang berganti cepat.
Kenapa Image CAPTCHA Mengembalikan Jawaban Salah
| Penyebab | Frekuensi | Solusi |
|---|---|---|
| Elemen CAPTCHA ter-screenshot tidak utuh | Sangat umum | Screenshot elemen penuh, bukan crop koordinat manual |
| Resolusi rendah atau kompresi berlebihan | Umum | Kirim gambar dengan kualitas lebih tinggi |
| Base64 salah encode | Umum | Verifikasi round-trip encoding sebelum submit |
| Hint bahasa/tipe tidak disertakan | Kadang | Tambahkan language atau textinstructions |
| Gambar sudah kedaluwarsa saat submit | Kadang | Ambil gambar baru tepat sebelum solve |
Pola yang sering luput: worker scraping yang di-deploy jauh dari server target — misalnya Selenium headless di region AWS ap-southeast-1 (Singapura) atau GCP asia-southeast2 (Jakarta) sementara halaman target di-hosting di benua lain — punya jeda render CAPTCHA lebih panjang dari biasanya. Screenshot yang diambil sebelum gambar CAPTCHA selesai dimuat menghasilkan persis skenario baris pertama tabel di atas: gambar terpotong atau setengah kosong. Menambah jeda singkat sebelum capture (lihat Solusi 6) biasanya cukup mengatasinya.
Solusi 1: Validasi Kualitas Gambar Sebelum Dikirim ke CaptchaAI
Sebelum request pertama dikirim ke in.php, cek dulu tiga hal yang paling sering jadi biang keladi: resolusi, rasio piksel kosong, dan ukuran file. Fungsi berikut memeriksa ketiganya sekaligus dan mencetak peringatan sebelum submit — jauh lebih murah daripada menunggu task selesai lalu baru sadar jawabannya salah.
import base64
from io import BytesIO
from PIL import Image
def validate_captcha_image(image_path):
"""Check image quality before submitting to CaptchaAI."""
img = Image.open(image_path)
width, height = img.size
issues = []
# Minimum resolution
if width < 50 or height < 20:
issues.append(f"Too small: {width}x{height}px (min 50x20)")
# Check if mostly blank
pixels = list(img.getdata())
if img.mode == "RGB":
white_count = sum(1 for p in pixels if p[0] > 250 and p[1] > 250 and p[2] > 250)
else:
white_count = sum(1 for p in pixels if p > 250)
blank_ratio = white_count / len(pixels)
if blank_ratio > 0.95:
issues.append(f"Image appears blank ({blank_ratio:.0%} white)")
# File size check
img_bytes = BytesIO()
img.save(img_bytes, format="PNG")
size_kb = img_bytes.tell() / 1024
if size_kb < 1:
issues.append(f"File too small ({size_kb:.1f} KB) — may be empty")
if size_kb > 600:
issues.append(f"File too large ({size_kb:.0f} KB) — submit under 600 KB")
return issues
issues = validate_captcha_image("captcha.png")
if issues:
for issue in issues:
print(f"WARNING: {issue}")
else:
print("Image quality OK")
Kalau validate_captcha_image mengembalikan peringatan resolusi di bawah 50×20px atau rasio blank di atas 95%, jangan kirim gambar itu — ambil ulang elemen CAPTCHA-nya dulu (lihat Solusi 5).
Solusi 2: Pastikan Encoding Base64 Tidak Rusak
Bug paling konyol — tapi paling sering terjadi — adalah meng-encode nama file, bukan isi gambarnya. base64.b64encode(b"captcha.png") valid secara sintaks Python, tapi hasilnya adalah encoding dari string teks "captcha.png", bukan byte gambar sesungguhnya. CaptchaAI menerima string base64 itu tanpa error, lalu mencoba membaca gambar yang sebenarnya tidak pernah ada — hasilnya jawaban acak yang terlihat seperti bug di sisi solver, padahal bug-nya ada di baris kode Anda.
import base64
def encode_captcha(image_path):
"""Properly encode a CAPTCHA image to base64."""
with open(image_path, "rb") as f:
raw = f.read()
encoded = base64.b64encode(raw).decode("ascii")
# Verify round-trip
decoded = base64.b64decode(encoded)
assert decoded == raw, "Base64 encoding corrupted the image"
return encoded
# WRONG — encoding a file path string
bad = base64.b64encode(b"captcha.png").decode() # Encodes filename, not image!
# CORRECT — encoding file contents
with open("captcha.png", "rb") as f:
good = base64.b64encode(f.read()).decode()
Selalu verifikasi round-trip encoding seperti pada fungsi encode_captcha di atas sebelum submit ke API — assertion itu langsung gagal kalau ada korupsi, jauh sebelum request terkirim dan menghabiskan satu siklus polling percuma.
Solusi 3: Preprocessing Gambar untuk Akurasi OCR yang Lebih Baik
Preprocessing bukan langkah wajib untuk gambar CAPTCHA standar — CaptchaAI menanganinya dengan baik apa adanya. Tapi untuk gambar kecil, buram, atau kontras rendah (sering terjadi kalau screenshot diambil dari elemen yang belum sepenuhnya render), upscaling dan penajaman kontras bisa mengubah jawaban yang salah menjadi benar.
from PIL import Image, ImageFilter, ImageEnhance
from io import BytesIO
import base64
def preprocess_captcha(image_path):
"""Improve image quality for better OCR accuracy."""
img = Image.open(image_path)
# Convert to RGB if needed
if img.mode != "RGB":
img = img.convert("RGB")
# Upscale small images
width, height = img.size
if width < 200:
scale = 200 / width
img = img.resize(
(int(width * scale), int(height * scale)),
Image.LANCZOS,
)
# Increase contrast
enhancer = ImageEnhance.Contrast(img)
img = enhancer.enhance(1.5)
# Sharpen
img = img.filter(ImageFilter.SHARPEN)
# Convert to PNG bytes
buffer = BytesIO()
img.save(buffer, format="PNG")
return base64.b64encode(buffer.getvalue()).decode()
Perhatikan urutan operasinya: convert ke RGB dulu, baru upscale, baru contrast, baru sharpen. Membalik urutan ini — misalnya sharpen sebelum upscale — justru memperbesar noise, bukan menguranginya, dan malah menurunkan akurasi yang tadinya sudah cukup baik.
Solusi 4: Tambahkan Hint Bahasa, Tipe, dan Panjang Karakter
Kalau gambarnya sudah jernih tapi jawabannya masih meleset, masalahnya mungkin bukan kualitas gambar — solver tidak tahu apa yang harus dicari. Parameter numeric, min_len, max_len, dan textinstructions mempersempit ruang tebakan, dan inilah yang paling sering dilewatkan tim yang baru migrasi dari solver lain.
import requests
def solve_image(api_key, image_base64, **hints):
"""Submit image CAPTCHA with quality hints."""
data = {
"key": api_key,
"method": "base64",
"body": image_base64,
"json": 1,
}
# Add optional hints for better accuracy
if "language" in hints:
data["language"] = hints["language"] # 0=default, 1=Cyrillic, 2=Latin
if "textinstructions" in hints:
data["textinstructions"] = hints["textinstructions"]
if "numeric" in hints:
data["numeric"] = hints["numeric"] # 1=digits only, 2=letters only
if "min_len" in hints:
data["min_len"] = hints["min_len"]
if "max_len" in hints:
data["max_len"] = hints["max_len"]
resp = requests.post("https://ocr.captchaai.com/in.php", data=data, timeout=30)
return resp.json()
# Example: Digits-only CAPTCHA, 4-6 characters
result = solve_image(
"YOUR_API_KEY",
encoded_image,
numeric=1,
min_len=4,
max_len=6,
)
# Example: Case-sensitive text
result = solve_image(
"YOUR_API_KEY",
encoded_image,
textinstructions="Case-sensitive, enter exactly as shown",
)
Hint language khususnya penting untuk CAPTCHA berbasis Cyrillic atau karakter non-Latin — tanpa parameter ini, solver default ke asumsi Latin dan hasilnya berantakan.
Solusi 5: Screenshot Elemen CAPTCHA, Bukan Seluruh Halaman
Screenshot halaman penuh lalu crop manual pakai koordinat piksel adalah sumber kesalahan klasik — begitu layout halaman berubah sedikit saja (banner promo, notifikasi cookie, ukuran viewport berbeda), koordinat crop Anda meleset dan CaptchaAI menerima potongan gambar yang salah.
from selenium import webdriver
from selenium.webdriver.common.by import By
import base64
def capture_captcha_element(driver, selector):
"""Screenshot only the CAPTCHA element, not the full page."""
element = driver.find_element(By.CSS_SELECTOR, selector)
# Element screenshot (better than page crop)
png_bytes = element.screenshot_as_png
# Verify it's not empty
if len(png_bytes) < 500:
raise ValueError("Screenshot too small — element may not be visible")
return base64.b64encode(png_bytes).decode()
# Usage
driver = webdriver.Chrome()
driver.get("https://example.com")
image_b64 = capture_captcha_element(driver, "img#captchaImage")
element.screenshot_as_png di Selenium mengambil elemen persis sesuai boundary render-nya, kebal terhadap perubahan layout di sekitarnya. Cek juga panjang byte-nya — di bawah 500 byte biasanya berarti elemen belum sempat render sempurna saat screenshot diambil.
Solusi 6: Tangani Image CAPTCHA yang Berganti Cepat (Dynamic/Rotating)
Beberapa image CAPTCHA — termasuk yang dipasang di halaman dengan proteksi anti-bot ketat — me-refresh gambarnya setiap beberapa detik. Kalau Anda screenshot gambar lama tapi baru submit setelah gambar berganti, CaptchaAI akan menjawab CAPTCHA yang sudah tidak ada lagi di layar, dan jawabannya otomatis salah meski logikanya benar.
import time
def solve_with_fresh_image(driver, api_key, captcha_selector):
"""Capture and solve CAPTCHA immediately to avoid expiry."""
# Wait for CAPTCHA to load fully
time.sleep(2)
# Capture fresh
element = driver.find_element(By.CSS_SELECTOR, captcha_selector)
png_bytes = element.screenshot_as_png
body = base64.b64encode(png_bytes).decode()
# Submit immediately
resp = requests.post("https://ocr.captchaai.com/in.php", data={
"key": api_key,
"method": "base64",
"body": body,
"json": 1,
}, timeout=30)
result = resp.json()
if result.get("status") != 1:
raise RuntimeError(result.get("request"))
task_id = result["request"]
# Poll — image CAPTCHAs solve fast
time.sleep(5)
for _ in range(12):
resp = requests.get("https://ocr.captchaai.com/res.php", params={
"key": api_key, "action": "get",
"id": task_id, "json": 1,
}, timeout=15)
data = resp.json()
if data.get("status") == 1:
return data["request"]
if data["request"] != "CAPCHA_NOT_READY":
raise RuntimeError(data["request"])
time.sleep(3)
raise TimeoutError("Image solve timeout")
Pola amannya: screenshot dan submit dalam satu alur tanpa jeda, lalu polling dengan interval pendek (di sini setiap 3 detik) supaya Anda dapat token secepat CAPTCHA-nya selesai, bukan menunggu siklus polling berikutnya lewat begitu saja.
Checklist Diagnosa Cepat: Gejala, Penyebab, dan Solusi
| Gejala | Diagnosa | Solusi |
|---|---|---|
| Jawaban omong kosong | Encoding base64 salah | Verifikasi round-trip encoding |
| Jawaban hampir benar tapi salah | Kualitas gambar rendah | Preprocessing: upscale, sharpen, contrast |
| Jawaban dengan jumlah karakter salah | Hint panjang tidak ada | Tambahkan parameter min_len/max_len |
| Jawaban campur huruf/digit | Hint tipe tidak ada | Tambahkan numeric=1 atau numeric=2 |
| Jawaban kosong dikembalikan | Gambar blank/corrupt | Validasi gambar sebelum submit |
| Jawaban benar tapi situs menolak | Sensitivitas huruf besar/kecil | Tambahkan text instructions untuk case |
Pertanyaan Umum Seputar Image CAPTCHA Salah Jawab
Apakah encoding base64 yang benar memengaruhi kecepatan solve?
Ya, secara tidak langsung. Image CAPTCHA di CaptchaAI biasanya clear di bawah 0,5 detik dengan tingkat keberhasilan tinggi pada tipe yang didukung — tapi kalau base64-nya korup atau menyertakan prefix data URI (data:image/png;base64,...) yang tidak dibuang, request langsung ditolak dan Anda kehilangan satu siklus polling penuh untuk mengulang.
Berapa ukuran gambar maksimal yang sebaiknya dikirim ke CaptchaAI?
Rekomendasi praktis: jaga file di bawah 600 KB seperti pada fungsi validasi di Solusi 1. Gambar yang jauh lebih besar dari itu biasanya berarti Anda men-screenshot elemen yang salah — misalnya seluruh viewport, bukan elemen CAPTCHA-nya saja — bukan soal batas teknis API.
Kenapa preprocessing malah membuat jawaban tambah salah?
Preprocessing berlebihan pada gambar yang sebenarnya sudah jernih bisa merusak detail karakter — sharpening ganda atau contrast yang terlalu agresif kadang membuat huruf mirip s dan 5, atau O dan 0, makin sulit dibedakan. Preprocessing di Solusi 3 sebaiknya cuma dipakai untuk gambar yang memang kecil atau buram, bukan diterapkan ke semua gambar secara default.
Bisakah saya melaporkan jawaban yang salah ke CaptchaAI?
Bisa. Gunakan endpoint reportbad dengan task ID untuk melaporkan jawaban yang keliru. Selain membantu meningkatkan akurasi sistem untuk semua pengguna, laporan ini kadang juga mengkredit kembali saldo akun Anda untuk task yang gagal.
Panduan Terkait
Kalau setelah mengikuti keenam solusi di atas tingkat keberhasilan Anda masih menurun secara umum — bukan cuma di image CAPTCHA — diagnosa lebih dalam lewat panduan mendiagnosis success rate CAPTCHA yang menurun.