Jawaban singkatnya: gambar berisi huruf acak plus satu kolom input berarti text CAPTCHA, cukup diselesaikan lewat OCR. Kisi foto "pilih semua kotak berisi lampu lalu lintas" berarti image CAPTCHA, dan butuh alur solver per penyedia. Perbedaan ini menentukan endpoint yang Anda panggil, lama script menunggu, dan jumlah thread yang dibeli.
Apa yang terjadi di balik text CAPTCHA
Text CAPTCHA merender karakter acak jadi gambar, lalu membandingkan ketikan pengguna dengan string di sesi server.
Distorsi yang biasa dipakai supaya OCR meleset:
| Teknik | Tujuan |
|---|---|
| Pembengkokan karakter | Melengkungkan huruf agar OCR gagal |
| Derau latar belakang | Garis, titik, atau gradien di belakang teks |
| Karakter tumpang tindih | Menyulitkan pemisahan per karakter |
| Pengacakan font | Beberapa font dan ukuran per tantangan |
| Variasi warna | Warna karakter dan latar diacak |
Urutannya, dari sisi server sampai ke kolom input:
Server generates random string (e.g., "X7mK9p")
↓
Applies distortion: warping, noise, overlap
↓
Renders as PNG/JPEG image
↓
User reads characters, types into input field
↓
Server compares input against stored string (case-insensitive usually)
Validasinya berbasis string dan umumnya mengabaikan huruf besar-kecil, jadi jangan buang hasil OCR karena kapitalisasi.
Apa yang terjadi di balik image CAPTCHA
Image CAPTCHA menyajikan kisi foto berlabel dan meminta pengguna memilih yang cocok dengan satu kategori; validasi terjadi di server penyedia.
Bentuk tantangannya berbeda-beda per penyedia:
| Jenis | Tantangan | Penyedia |
|---|---|---|
| Pemilihan kisi | "Pilih semua kotak dengan lampu lalu lintas" | reCAPTCHA v2 |
| Pelabelan gambar | "Klik semua gambar yang berisi bus" | hCaptcha |
| Penghitungan objek | "Berapa banyak sepeda di gambar ini?" | Kustom |
| Rotasi | "Putar gambar ke orientasi yang benar" | FunCaptcha |
Urutannya berbeda karena penilaian tidak pernah keluar dari server penyedia:
Server selects images from a labeled dataset
↓
Presents 3×3 or 4×4 grid with a text prompt
↓
User clicks matching images
↓
Server validates selections against ground truth
↓
If fading images: new images load in place of selected ones (multi-round)
Pada mode fading, satu tantangan berlangsung beberapa ronde, jadi batas waktu polling perlu lebih longgar.
Mendeteksi jenis CAPTCHA di halaman target
Untuk pekerjaan scraping kontrak, yang ramai di komunitas otomatisasi Indonesia lewat Upwork dan Fastwork, deteksi otomatis lebih hemat daripada membuka DevTools per klien. Tandanya ada di HTML mentah:
- Text CAPTCHA:
<img>ber-srcmengandungcaptchaberdampingan dengan<input>serupa, dirender server. - Image CAPTCHA: script pihak ketiga (
google.com/recaptcha,hcaptcha.com,arkoselabs) plus containerdivyang terisi setelah halaman dimuat.
Deteksi dengan Python
import requests
from bs4 import BeautifulSoup
import re
def detect_captcha_type(url):
"""Detect whether page uses text or image CAPTCHA."""
response = requests.get(url, timeout=10)
soup = BeautifulSoup(response.text, "html.parser")
html = response.text
result = {"text_captcha": False, "image_captcha": False, "provider": None}
# Check for reCAPTCHA (image-based)
if "google.com/recaptcha" in html or "g-recaptcha" in html:
result["image_captcha"] = True
result["provider"] = "reCAPTCHA"
return result
# Check for hCaptcha (image-based)
if "hcaptcha.com" in html or "h-captcha" in html:
result["image_captcha"] = True
result["provider"] = "hCaptcha"
return result
# Check for text CAPTCHA patterns
captcha_images = soup.find_all("img", attrs={
"src": re.compile(r"captcha", re.I)
})
captcha_inputs = soup.find_all("input", attrs={
"name": re.compile(r"captcha", re.I)
})
if captcha_images and captcha_inputs:
# Image with text input = text CAPTCHA
result["text_captcha"] = True
result["provider"] = "custom text CAPTCHA"
return result
# Check for FunCaptcha (image-based rotation)
if "funcaptcha" in html.lower() or "arkoselabs" in html.lower():
result["image_captcha"] = True
result["provider"] = "FunCaptcha"
return result
return result
captcha = detect_captcha_type("https://staging.example.com/qa-login")
print(captcha)
Deteksi dengan Node.js
const axios = require("axios");
const cheerio = require("cheerio");
async function detectCaptchaType(url) {
const { data: html } = await axios.get(url, { timeout: 10000 });
const $ = cheerio.load(html);
const result = { textCaptcha: false, imageCaptcha: false, provider: null };
// reCAPTCHA detection
if (html.includes("google.com/recaptcha") || html.includes("g-recaptcha")) {
result.imageCaptcha = true;
result.provider = "reCAPTCHA";
return result;
}
// hCaptcha detection
if (html.includes("hcaptcha.com") || html.includes("h-captcha")) {
result.imageCaptcha = true;
result.provider = "hCaptcha";
return result;
}
// Text CAPTCHA: image + input with "captcha" in name/class
const captchaImgs = $("img[src*='captcha' i]").length;
const captchaInputs = $("input[name*='captcha' i]").length;
if (captchaImgs > 0 && captchaInputs > 0) {
result.textCaptcha = true;
result.provider = "custom text CAPTCHA";
return result;
}
return result;
}
detectCaptchaType("https://staging.example.com/qa-login").then(console.log);
Simpan hasilnya di database job: saat situs berganti penyedia, Anda tahu script mana yang perlu disesuaikan.
Perbandingan langsung dua jenis
| Dimensi | Text CAPTCHA | Image CAPTCHA |
|---|---|---|
| Keamanan | Rendah, OCR modern menanganinya | Tinggi, perlu pengenalan objek |
| Waktu penyelesaian | 5–10 detik | 10–30 detik |
| Kegagalan (manusia) | 15–20% | 8–15% |
| Aksesibilitas | Buruk bagi tunanetra | Sangat buruk bagi tunanetra |
| Di seluler | Sedang, karakter kecil | Baik, cukup ketuk |
| Kesulitan otomatisasi | Mudah, cukup OCR | Sulit, perlu klasifikasi |
| Biaya penerapan | Gratis, self-hosted | Gratis hingga berbayar |
| Beban integrasi | Minimal, sisi server | Sedang, perlu JavaScript SDK |
| Pengumpulan data | Tidak ada | Bisa melatih model penyedia |
Angka pada tabel bersumber dari pengamatan dan laporan pengguna. Hasil dapat berbeda tergantung lingkungan, volume, dan waktu pengujian.
Menyelesaikan text CAPTCHA dengan CaptchaAI
Text CAPTCHA tetaplah gambar, jadi jalurnya OCR: kirim base64 ke in.php, simpan task ID, polling res.php, pakai teks hasilnya.
import requests
import base64
import time
API_KEY = "YOUR_API_KEY"
# Get the CAPTCHA image
captcha_url = "https://example.com/captcha.png"
image_data = requests.get(captcha_url).content
b64 = base64.b64encode(image_data).decode()
# Submit to CaptchaAI
submit = requests.post("https://ocr.captchaai.com/in.php", data={
"key": API_KEY,
"method": "base64",
"body": b64,
"json": 1,
})
task_id = submit.json()["request"]
# Poll for result
for _ in range(30):
time.sleep(3)
resp = requests.get("https://ocr.captchaai.com/res.php", params={
"key": API_KEY,
"action": "get",
"id": task_id,
"json": 1,
}).json()
if resp.get("status") == 1:
print(f"CAPTCHA text: {resp['request']}")
break
Untuk image CAPTCHA penyedia, yang dikirim adalah sitekey dan URL halaman, bukan berkas gambar — satu fungsi tak cukup.
Yang didukung dan yang belum
- Didukung: CAPTCHA gambar/OCR, grid image, reCAPTCHA v2 dan v3 termasuk varian Enterprise, Cloudflare Turnstile, Cloudflare Challenge, GeeTest v3, dan BLS.
- Beta: CaptchaFox (beta), Friendly Captcha (beta), Lemin (beta).
- Belum didukung: hCaptcha dan FunCaptcha (Arkose Labs). GeeTest v4 berstatus segera hadir.
Bila target Anda memakai hCaptcha atau FunCaptcha, tipe itu perlu layanan lain — pastikan sebelum script produksi terpasang.
Dampaknya pada biaya thread
Anggap Anda memegang kontrak pemantauan harga: 8.000 halaman per hari, 15% memunculkan CAPTCHA, jadi sekitar 36.000 penyelesaian per bulan.
CaptchaAI menagih per thread bersamaan, bukan per penyelesaian, dan tiap paket memberi penyelesaian tak terbatas selama bulan berjalan. Untuk beban itu, ADVANCE ($90/bulan, 50 thread) memberi ruang lega; STANDARD ($30/bulan, 15 thread) memadai bila job berjalan semalaman; BASIC ($15/bulan, 5 thread) cukup untuk script uji.
Jadi campuran text dan image CAPTCHA tidak mengubah tagihan, hanya berapa lama tiap thread ditahan. Image CAPTCHA menahan lebih lama: throughput turun meski biaya tetap, jadi bila target didominasi kisi gambar, tambah thread.
Jenis mana untuk kasus Anda
Jika Anda yang memasang perlindungan, bukan yang mengotomatiskan:
- Text CAPTCHA bila lalu lintas bot rendah dan Anda ingin menghindari pengiriman data pengunjung ke pihak ketiga, pertimbangan yang relevan di bawah UU Pelindungan Data Pribadi (UU 27/2022).
- Image CAPTCHA bila aplikasi memegang data sensitif seperti login atau pembayaran dan hambatan pengguna dapat diterima.
- Keduanya dilewati bila CAPTCHA invisible seperti reCAPTCHA v3 atau Cloudflare Turnstile sudah cukup menyaring lalu lintas tanpa interaksi pengguna. Untuk pasar mobile-first, ini biasanya paling sehat bagi konversi.
Pertanyaan yang sering diajukan
Bagaimana cara cepat mengetahui jenis CAPTCHA di satu halaman?
Cari captcha di source halaman: pasangan <img> dan <input> dalam satu form berarti text CAPTCHA, script google.com/recaptcha atau hcaptcha.com berarti image CAPTCHA penyedia.
Tipe apa saja yang tidak ditangani CaptchaAI?
hCaptcha dan FunCaptcha (Arkose Labs) belum didukung. Yang ditangani: CAPTCHA teks/OCR, grid image, reCAPTCHA v2 dan v3, Cloudflare Turnstile dan Challenge, GeeTest v3, dan BLS; CaptchaFox, Friendly Captcha, Lemin beta.
Berapa thread yang saya butuhkan untuk campuran text dan image CAPTCHA?
Hitung dari durasi tahan thread, bukan jumlah penyelesaian: perkirakan berapa CAPTCHA berjalan bersamaan pada jam puncak, lalu pilih paket dengan thread sebanyak itu.
Kenapa hasil OCR saya sering ditolak server target?
Tiga penyebab umum: token kedaluwarsa karena polling terlalu lama, gambar diambil dari sesi berbeda, atau cookie sesi tidak terkirim. Pakai satu sesi HTTP.
Masih layakkah memasang text CAPTCHA hari ini?
Untuk perlindungan serius, tidak. OCR modern menanganinya dengan andal, dan menaikkan distorsi justru menghukum manusia lebih dulu.
Ringkasan
Keputusan pertama bukan "mana yang lebih baik", melainkan "yang ini jenisnya apa". Text CAPTCHA cukup dikirim sebagai gambar ke Image OCR API CaptchaAI; image CAPTCHA menuntut alur sitekey per penyedia; hCaptcha dan FunCaptcha butuh layanan lain.