API Tutorials

Jenis CAPTCHA Kustom: Mengirimkan Challenge Tidak Biasa ke CaptchaAI

Slider yang harus digeser tepat sasaran, gambar yang harus diputar tegak, ikon yang mesti diklik berurutan, sampai tantangan audio — semua CAPTCHA kustom itu bisa Anda tangani lewat satu jalur yang sama di CaptchaAI: ambil screenshot elemennya, encode ke base64, lalu kirim bersama instruksi teks ke endpoint in.php. Anda tidak perlu solver berbeda untuk tiap widget aneh. Artikel ini menunjukkan pola universal itu dengan Python — dari mengenali jenis tantangan di halaman, mengirim gambar plus instruksi, sampai memetakan jawaban kembali ke aksi Selenium untuk slider, rotasi, urutan klik, dan audio.


Kapan pendekatan gambar + instruksi teks masuk akal

Sebagian tipe sudah punya method khusus di API dan sebaiknya Anda tangani lewat panduannya sendiri, bukan pola di artikel ini:

  • reCAPTCHA v2/v3 → method userrecaptcha
  • Cloudflare Turnstile → method turnstile
  • GeeTest v3 → method geetest

Pola gambar + instruksi teks di sini justru untuk tantangan yang tidak punya method khusus:

  • Widget JavaScript buatan situs
  • Slider bergaya jigsaw
  • Rotasi orientasi gambar
  • Soal aritmatika yang dirender sebagai gambar

Kuncinya sederhana. Selama tantangan bisa Anda tangkap sebagai gambar dan jelaskan dengan kalimat, Anda bisa mengirimnya ke jalur OCR (method=base64) dengan parameter textinstructions. Ini realistis untuk pekerjaan lapangan: tim price-monitoring dan freelancer scraping di Jakarta atau Bandung kerap menemui slider atau rotasi di form pendaftaran ketika membangun QA otomatis pada lingkungan staging.example.com milik sendiri — dan pola inilah yang menanganinya tanpa harus menulis pemecah khusus per situs.


Kenali jenis CAPTCHA kustom di halaman

Sebelum menulis kode, petakan dulu tantangan yang Anda hadapi ke pendekatan yang tepat. Tabel ini merangkum tipe kustom yang paling sering muncul:

Tipe Karakteristik Pendekatan
Slider CAPTCHA Geser ke posisi Screenshot sebagai gambar, pakai instruksi teks
Puzzle (jigsaw) Geser potongan agar pas Dapat dipetakan ke solve bergaya GeeTest v3
Audio CAPTCHA Dengarkan dan ketik Kirim file audio
Rotasi gambar Putar ke orientasi benar Screenshot + instruksi
Pilih berurutan Klik item satu per satu Pakai pendekatan grid gambar
Persamaan matematika Selesaikan aritmatika Pakai parameter calc=1
Widget interaktif kustom Widget JS khusus situs Screenshot + instruksi teks

Pola universal: kirim gambar base64 plus instruksi

Fungsi berikut adalah inti dari semua contoh sesudahnya. Alurnya mengikuti frame empat langkah yang sama seperti solve CAPTCHA lain di CaptchaAI:

  1. Kirim task berisi gambar base64 dan instruksi ke in.php
  2. Simpan task ID dari respons
  3. Polling res.php sampai status siap
  4. Pakai jawaban yang dikembalikan

Bedanya, di sini Anda menyertakan textinstructions yang memberi tahu solver apa persisnya yang harus dikembalikan — angka, koordinat, teks, atau daftar urutan.

import requests
import base64
import time
import os

API_KEY = os.environ["CAPTCHAAI_API_KEY"]


def solve_custom_captcha(image_b64, instructions):
    """Solve any visual CAPTCHA using image + text instructions."""
    resp = requests.post("https://ocr.captchaai.com/in.php", data={
        "key": API_KEY,
        "method": "base64",
        "body": image_b64,
        "textinstructions": instructions,
        "json": 1,
    }, timeout=30)

    result = resp.json()
    if result.get("status") != 1:
        raise RuntimeError(result.get("request"))

    task_id = result["request"]

    time.sleep(10)
    for _ in range(30):
        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(5)

    raise TimeoutError("Solve timeout")

Semakin spesifik instruksi Anda, semakin bersih jawaban yang kembali. Minta "hanya angka X offset", bukan "jelaskan slider ini".


Slider: ubah jawaban jadi offset drag

Slider meminta Anda menggeser handle ke titik tertentu. Screenshot area CAPTCHA, tanyakan posisi piksel targetnya, lalu terjemahkan angka itu menjadi gerakan drag dengan ActionChains:

# slider_captcha.py
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains


def solve_slider_captcha(driver, captcha_selector):
    """Screenshot slider CAPTCHA and solve via CaptchaAI."""
    captcha = driver.find_element(By.CSS_SELECTOR, captcha_selector)
    image_b64 = captcha.screenshot_as_base64

    result = solve_custom_captcha(
        image_b64,
        "What pixel position should the slider be dragged to? "
        "Return only the X offset number."
    )

    try:
        offset = int(result)
    except ValueError:
        return False

    # Drag slider to position
    slider = driver.find_element(By.CSS_SELECTOR, ".slider-handle")
    ActionChains(driver).click_and_hold(slider).move_by_offset(offset, 0).release().perform()

    return True

Rotasi: hitung derajat lalu klik

Untuk CAPTCHA rotasi, gambar harus diputar tegak. Alurnya dua langkah:

  • Minta solver mengembalikan jumlah derajat searah jarum jam
  • Bagi dengan 90 untuk menentukan berapa kali tombol putar diklik
# rotation_captcha.py


def solve_rotation_captcha(driver, captcha_selector):
    """Solve rotation CAPTCHA."""
    captcha = driver.find_element(By.CSS_SELECTOR, captcha_selector)
    image_b64 = captcha.screenshot_as_base64

    result = solve_custom_captcha(
        image_b64,
        "How many degrees should this image be rotated clockwise "
        "to be in the correct upright orientation? Return only the number."
    )

    try:
        degrees = int(result)
    except ValueError:
        return False

    # Click rotation button the correct number of times
    rotate_btn = driver.find_element(By.CSS_SELECTOR, ".rotate-button")
    clicks = degrees // 90  # Each click rotates 90 degrees

    for _ in range(clicks):
        rotate_btn.click()
        time.sleep(0.3)

    return True

Urutan klik: petakan angka ke elemen

Beberapa CAPTCHA meminta Anda mengklik item dalam urutan tertentu — misalnya angka atau ikon dari kecil ke besar. Minta jawaban sebagai daftar angka posisi (1-indexed) dipisah koma, lalu klik elemen sesuai urutan itu:

# order_captcha.py


def solve_order_captcha(driver, captcha_selector, item_selector):
    """Solve click-in-order CAPTCHA."""
    captcha = driver.find_element(By.CSS_SELECTOR, captcha_selector)
    image_b64 = captcha.screenshot_as_base64

    result = solve_custom_captcha(
        image_b64,
        "What is the correct order? Return as comma-separated "
        "numbers (1-indexed) representing positions left-to-right, top-to-bottom."
    )

    # Parse order
    try:
        order = [int(x.strip()) for x in result.split(",")]
    except ValueError:
        return False

    # Click items in order
    items = driver.find_elements(By.CSS_SELECTOR, item_selector)
    for idx in order:
        if 1 <= idx <= len(items):
            items[idx - 1].click()
            time.sleep(0.5)

    return True

Alternatif audio

Banyak situs menyediakan opsi audio sebagai alternatif aksesibilitas. Unduh file audionya, encode ke base64, lalu kirim lewat fungsi yang sama dengan instruksi transkripsi:

# audio_captcha.py
import requests


def solve_audio_captcha(audio_url):
    """Download and solve an audio CAPTCHA."""
    # Download audio
    resp = requests.get(audio_url, timeout=30)
    audio_b64 = base64.b64encode(resp.content).decode("ascii")

    # Submit as image with instructions
    # CaptchaAI may support audio via the base64 method
    result = solve_custom_captcha(
        audio_b64,
        "This is an audio CAPTCHA. Transcribe the spoken characters."
    )
    return result

Widget CAPTCHA kustom sepenuhnya buatan situs

Kalau tantangannya widget unik yang tidak cocok kategori mana pun, perlakukan seperti kotak hitam. Kode di bawah menjalankan empat langkah:

  • Screenshot seluruh widget
  • Tarik teks instruksi yang terlihat di halaman
  • Kirim gambar dan instruksi ke solver
  • Masukkan jawaban ke input yang tersedia

Pendekatan ini bertahan meski markup situs berubah:

# custom_widget.py
from selenium import webdriver
from selenium.webdriver.common.by import By


def handle_custom_widget(driver, widget_selector):
    """Handle an unknown custom CAPTCHA widget."""

    # Step 1: Screenshot the entire widget
    widget = driver.find_element(By.CSS_SELECTOR, widget_selector)
    image_b64 = widget.screenshot_as_base64

    # Step 2: Get any visible instructions
    try:
        instructions_el = widget.find_element(By.CSS_SELECTOR, ".instructions, .prompt, p")
        visible_instructions = instructions_el.text
    except Exception:
        visible_instructions = "Solve this CAPTCHA"

    # Step 3: Submit with descriptive instructions
    result = solve_custom_captcha(
        image_b64,
        f"CAPTCHA instructions: {visible_instructions}. "
        f"Return the answer text."
    )

    # Step 4: Try to submit result
    try:
        input_el = widget.find_element(By.CSS_SELECTOR, "input")
        input_el.clear()
        input_el.send_keys(result)
    except Exception:
        # No input — try clicking based on result
        driver.execute_script("""
            var input = document.querySelector('input[name*="captcha"]');
            if (input) input.value = arguments[0];
        """, result)

    return result

Deteksi jenis CAPTCHA secara otomatis

Kalau halaman yang Anda proses bisa memuat tantangan yang berbeda-beda, deteksi tipenya lebih dulu lalu arahkan ke handler yang sesuai. Fungsi ini memindai HTML halaman dengan pola regex sederhana dan mengembalikan daftar tipe yang terdeteksi:

# detector.py
import re


def detect_captcha_type(page_html):
    """Detect which CAPTCHA type is on a page."""
    checks = {
        "recaptcha_v2": r'data-sitekey.*g-recaptcha',
        "recaptcha_v3": r'recaptcha/api\.js\?render=',
        "turnstile": r'cf-turnstile|challenges\.cloudflare\.com/turnstile',
        "geetest": r'gt\b.*challenge|geetest',
        "bls": r'method.*bls|bls-captcha',
        "image_text": r'captcha.*\.(png|jpg|gif|jpeg)',
        "slider": r'slider.*captcha|slide.*verify',
        "audio": r'audio.*captcha|captcha.*audio',
    }

    detected = []
    for captcha_type, pattern in checks.items():
        if re.search(pattern, page_html, re.IGNORECASE):
            detected.append(captcha_type)

    return detected if detected else ["unknown"]

Simpan hasil deteksi ini sebagai router sederhana:

  • recaptcha_v2 / recaptcha_v3 / turnstile → arahkan ke method khususnya
  • slider / audio / tipe kustom lain → jatuhkan ke pola gambar + instruksi
  • unknown → gunakan handle_custom_widget sebagai jalur cadangan

Troubleshooting

Sebagian besar kegagalan pada CAPTCHA kustom bersumber dari kualitas screenshot atau instruksi yang ambigu. Tabel ini merangkum masalah yang paling umum:

Masalah Penyebab Perbaikan
ERROR_CAPTCHA_UNSOLVABLE Gambar tidak jelas atau instruksi ambigu Tingkatkan kualitas screenshot dan perjelas instruksi
Format jawaban salah Solver mengembalikan deskripsi, bukan nilai Lebih spesifik: "Kembalikan hanya angkanya"
Widget kustom tidak ter-capture Elemen di luar viewport Scroll ke elemen sebelum screenshot
Interaksi gagal Koordinat klik salah Petakan solusi ke elemen UI sebenarnya dengan teliti

Biaya menyelesaikan CAPTCHA kustom dalam volume tinggi

Karena CAPTCHA kustom biasanya muncul di alur bervolume tinggi seperti QA otomatis atau pemantauan harga, biaya jadi pertimbangan nyata — terutama untuk tim dan freelancer yang sensitif terhadap ongkos. CaptchaAI menagih per thread bersamaan, bukan per solve: satu thread menangani satu CAPTCHA in-flight, dan begitu selesai, thread itu langsung bebas untuk tugas berikutnya. Paket dimulai dari BASIC ($15/bulan, 5 thread) dan naik lewat STANDARD ($30/bulan, 15 thread), ADVANCE ($90/bulan, 50 thread), hingga tier tinggi seperti VIP-3 ($7,500/bulan, 5.000 thread) — dan setiap paket memberi solve tak terbatas per thread selama sebulan. Untuk OCR gambar standar, waktu solve biasanya di bawah 0.5 detik per solve, sehingga throughput ditentukan oleh jumlah thread, bukan tagihan per tantangan. Catatan kepatuhan: sesuai UU Pelindungan Data Pribadi (UU 27/2022), proses hanya data yang berhak Anda akses dan hindari data pribadi.


Pertanyaan Umum

Bisakah satu pola screenshot dipakai untuk slider dan puzzle sekaligus?

Bisa. Selama tantangan dapat ditangkap sebagai gambar dan dijelaskan dengan instruksi teks, fungsi solve_custom_captcha yang sama menanganinya — Anda hanya mengganti kalimat instruksinya (posisi offset untuk slider, potongan yang pas untuk puzzle).

Berapa lama waktu penyelesaian untuk gambar + instruksi teks?

Untuk OCR gambar standar, penyelesaian umumnya di bawah 0.5 detik per solve. Tantangan kustom dengan instruksi kompleks bisa memerlukan beberapa detik lebih dan Anda ambil hasilnya lewat polling res.php, bukan seketika.

Bisakah puzzle geser bergaya GeeTest diselesaikan?

GeeTest v3 didukung secara native lewat method geetest, jadi puzzle bergaya GeeTest bisa ditangani langsung. GeeTest v4 belum tersedia — statusnya masih segera hadir. Untuk puzzle geser non-GeeTest, gunakan pola gambar + instruksi di artikel ini.

Berapa banyak thread yang saya butuhkan untuk scraping paralel?

Tergantung berapa CAPTCHA yang berjalan bersamaan. Satu thread menangani satu solve in-flight; kalau Anda memproses 40 halaman paralel, ADVANCE ($90/bulan, 50 thread) memberi ruang yang cukup dengan solve tak terbatas per thread.


Panduan Terkait


Selesaikan CAPTCHA kustom apa pun — mulai dengan CaptchaAI.

Komentar dinonaktifkan untuk artikel ini.