Use Cases

Penanganan CAPTCHA Arab dan RTL dengan CaptchaAI

CAPTCHA berskrip Arab, Farsi, dan Ibrani sering membuat OCR generik salah baca — bukan karena kualitas gambarnya, tapi karena huruf Arab menyambung dan berubah bentuk tergantung posisinya dalam kata, sementara arah bacanya kanan-ke-kiri (RTL). CaptchaAI menangani ini lewat solver Image/OCR yang sama dengan CAPTCHA gambar lainnya, cukup dengan parameter language=2 — Anda tidak perlu membangun pipeline OCR RTL sendiri.

Bagi tim scraping dan automation Indonesia yang mengerjakan proyek untuk klien di Timur Tengah — monitoring harga e-commerce, riset kompetitor, atau QA formulir pendaftaran — CAPTCHA RTL ini hambatan yang nyata: satu karakter salah baca, dan submission form gagal total. Panduan ini menunjukkan cara menyelesaikannya dengan Python dan JavaScript, skrip apa saja yang didukung, dan cara menghindari jebakan encoding yang paling umum.

Kenapa CAPTCHA Arab dan RTL Lebih Sulit Diproses

Tantangan Detail
Karakter tersambung Huruf Arab berubah bentuk tergantung huruf di sekitarnya — bentuk awal, tengah, akhir, atau terisolasi
Arah baca kanan-ke-kiri Teks dalam gambar CAPTCHA dibaca dari kanan ke kiri
Arah campuran (bidi) Angka dan teks Latin bercampur dengan huruf Arab dalam satu string
Tanda diakritik Titik dan tanda di atas/bawah karakter menentukan huruf mana yang dimaksud (شاين vs ساين)
Tata letak halaman RTL Posisi elemen form dan CAPTCHA berbeda dari halaman LTR biasa

Skenario yang umum ditemui: formulir pendaftaran atau portal visa berbahasa Arab menampilkan CAPTCHA gambar, dan nama pengguna yang dikirim bersamanya juga harus dalam huruf Arab. Kalau encoding pada request form Anda salah, submission langsung ditolak sebelum CAPTCHA-nya sendiri sempat jadi masalah — jadi header charset=UTF-8 sama pentingnya dengan solver-nya.

Alur Penyelesaian CAPTCHA RTL

Polanya sama seperti CAPTCHA gambar lain di CaptchaAI, hanya dengan satu parameter tambahan:

  1. Kirim gambar CAPTCHA sebagai base64 ke in.php dengan language=2 untuk dukungan karakter non-Latin.
  2. Simpan task_id yang dikembalikan dari respons submit.
  3. Polling res.php setiap beberapa detik sampai statusnya berubah dari CAPCHA_NOT_READY.
  4. Pakai teks hasil (masih dalam skrip Arab, Farsi, atau Ibrani asli) untuk mengisi field form.

Python: Menyelesaikan CAPTCHA Gambar Arab

Fungsi berikut mengirim gambar CAPTCHA berskrip Arab ke solver Image/OCR CaptchaAI dan mengembalikan teks hasilnya dalam encoding UTF-8 asli — lengkap dengan contoh pengiriman formulir langsung dari sesi requests, termasuk header Accept-Language dan charset yang benar:

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_arabic_captcha(image_path: str) -> str:
    """Solve an Arabic script 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,          # Non-Latin character support
        "json": 1,
    }, timeout=30).json()

    if resp.get("status") != 1:
        raise RuntimeError(f"Submit: {resp.get('request')}")

    task_id = resp["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")


def solve_arabic_captcha_from_url(session: requests.Session,
                                   captcha_url: str) -> str:
    """Download and solve an Arabic CAPTCHA from a URL."""
    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")


# --- RTL-aware form submission ---

def submit_form_with_arabic_captcha(
    form_url: str,
    captcha_url: str,
    form_data: dict,
    captcha_field: str = "captcha",
) -> requests.Response:
    """Complete an Arabic website form with CAPTCHA."""
    session = requests.Session()
    session.headers.update({
        "Accept-Language": "ar-SA,ar;q=0.9",
        "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
    })

    # Load the form page to establish session
    session.get(form_url, timeout=15)

    # Solve the CAPTCHA
    captcha_text = solve_arabic_captcha_from_url(session, captcha_url)
    print(f"Arabic CAPTCHA solved: {captcha_text}")

    # Submit with the solved text
    form_data[captcha_field] = captcha_text
    response = session.post(form_url, data=form_data, timeout=30)

    return response


# --- Usage ---

# Simple Arabic image CAPTCHA
text = solve_arabic_captcha("arabic_captcha.png")
print(f"Arabic text: {text}")

# Form submission on Arabic site
response = submit_form_with_arabic_captcha(
    form_url="https://example.sa/registration",
    captcha_url="https://example.sa/captcha/generate",
    form_data={
        "name": "اسم المستخدم",
        "email": "user@example.com",
    },
)

JavaScript: Pengaturan Token di Halaman RTL

Untuk automasi browser dengan Playwright, polanya serupa — bedanya Anda perlu mencari elemen CAPTCHA dan input field lewat selector CSS, karena tata letak RTL bisa menukar posisi kiri-kanan elemen dibanding halaman LTR 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 solveArabicCaptcha(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");
}

// Inject CAPTCHA token into RTL page with Playwright
async function solveAndInjectRTL(page) {
  // RTL pages may position the CAPTCHA differently
  const captchaImg = await page.locator("img[id*='captcha'], img[class*='captcha']");
  const imgSrc = await captchaImg.getAttribute("src");

  // Download the image
  const buffer = await (await fetch(imgSrc)).arrayBuffer();
  const imageB64 = Buffer.from(buffer).toString("base64");

  // Solve
  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) {
      // Fill the input — RTL input handles text direction automatically
      await page.locator("input[name*='captcha']").fill(poll.request);
      return poll.request;
    }
    throw new Error(`Solve: ${poll.request}`);
  }
}

// Usage
const text = await solveArabicCaptcha("arabic_captcha.png");
console.log(`Arabic text: ${text}`);

Skrip RTL yang Didukung: Arab, Farsi, dan Ibrani

Skrip Bahasa Contoh karakter
Arab Arab, Urdu, Pashto عربي - أبجدية
Farsi/Persia Farsi فارسی - حروف
Ibrani Ibrani עברית - אותיות

Farsi memakai aksara Arab plus empat huruf tambahan (پ, چ, ژ, گ) yang tidak ada dalam alfabet Arab standar. Tidak perlu parameter berbeda untuk ini — language=2 yang sama sudah mencakup kumpulan karakter yang diperluas, baik untuk CAPTCHA Arab, Farsi, maupun Ibrani. Karena semuanya lewat solver Image/OCR yang sama, waktu penyelesaiannya juga sama: biasanya di bawah 0.5 detik dengan tingkat keberhasilan tinggi, persis seperti CAPTCHA gambar berhuruf Latin biasa.

Masalah Umum dan Cara Mengatasinya

Masalah Penyebab Solusi
Pengiriman formulir gagal untuk input Arab Ketidakcocokan encoding Set charset=UTF-8 di header Content-Type
Teks Arab terbalik saat ditampilkan Client menampilkan teks RTL sebagai LTR Bungkus output dengan \u202B (RTL embedding) atau pakai tampilan yang mendukung RTL
Tanda diakritik hilang dari hasil Resolusi gambar terlalu rendah Pakai gambar CAPTCHA beresolusi lebih tinggi
Teks dua arah (Arab + angka) tercampur Algoritma BiDi diterapkan tidak konsisten Tangani karakter arah secara eksplisit dengan penanda Unicode
Posisi CAPTCHA meleset dari yang diharapkan Tata letak RTL mencerminkan posisi elemen halaman Pakai selector CSS atau ID, jangan deteksi berbasis posisi

Pertanyaan Umum

Apakah CaptchaAI juga menangani CAPTCHA Ibrani, bukan cuma Arab?

Ya. Solver Image/OCR yang sama menangani Arab, Farsi, dan Ibrani lewat parameter language=2 — tidak ada endpoint atau metode terpisah untuk masing-masing skrip.

Apakah waktu penyelesaian CAPTCHA Arab lebih lama dibanding CAPTCHA huruf Latin?

Tidak. Dari sisi solver, ini tetap CAPTCHA gambar/OCR biasa — biasanya selesai di bawah 0.5 detik dengan tingkat keberhasilan tinggi, terlepas dari skrip yang dipakai.

Apakah tata letak RTL bisa bikin skrip automasi saya salah menemukan elemen CAPTCHA?

Bisa, kalau skrip Anda mengandalkan posisi visual (misalnya "elemen paling kiri"). Tata letak RTL mencerminkan halaman, jadi form dan CAPTCHA bisa muncul di sisi berlawanan dibanding halaman LTR. Pakai selector CSS atau ID untuk menemukan elemen, bukan koordinat posisi.

Untuk volume tinggi di banyak halaman situs Arab, apakah biaya CaptchaAI naik per CAPTCHA yang diselesaikan?

Tidak. CaptchaAI memakai harga berbasis thread, bukan per solve. Paket BASIC ($15/bulan, 5 thread) sudah mencakup solve tanpa batas per thread selama masa berlangganan, jadi biaya Anda tetap terprediksi walau volume CAPTCHA Arab yang diproses naik.

Langkah Selanjutnya

Solusi RTL sudah siap dipakai — dapatkan API key CaptchaAI Anda dan mulai selesaikan CAPTCHA Arab, Farsi, atau Ibrani dari skrip Python atau JavaScript yang sama dengan CAPTCHA lainnya.

Panduan terkait:

Komentar dinonaktifkan untuk artikel ini.