Situs web berbahasa Arab, Farsi, dan Ibrani menyajikan CAPTCHA dengan skrip kanan-ke-kiri (RTL) yang menantang standar OCR dan injeksi teks. Karakter Arab terhubung secara berbeda berdasarkan posisi — bentuk awal, medial, akhir, atau terisolasi — membuat pengenalan gambar CAPTCHA menjadi lebih sulit. Dikombinasikan dengan tata letak halaman RTL yang memengaruhi posisi elemen, situs-situs ini memerlukan penanganan khusus.
Tantangan RTL CAPTCHA
| Tantangan | Detil |
|---|---|
| Koneksi karakter | Huruf arab berubah bentuk berdasarkan karakter yang berdekatan |
| Pembacaan dari kanan ke kiri | Teks dalam CAPTCHA dibaca dari kanan ke kiri |
| Arah campuran | Campuran angka dan teks latin dengan bahasa arab (dua arah) |
| Tanda diakritik | Titik dan tanda di atas karakter /below (شاين vs ساين) |
| Tata letak halaman RTL | Elemen bentuk dan penempatan CAPTCHA berbeda dengan LTR |
Python: Gambar Arab CAPTCHA
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: Arab dan RTL CAPTCHA
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
| Skrip | Bahasa | Contoh karakter |
|---|---|---|
| Arab | Arab, Urdu, Pashto | عربي - أبجدية |
| Farsi/Persian | Farsi | ÙØ§Ø±Ø³ÛŒ - ØØ±ÙˆÙ |
| Ibrani | Ibrani | עברית - ×ותיות |
Pemecahan Masalah
| Masalah | Penyebab | Solusi |
|---|---|---|
| Teks Arab dibalik dalam keluaran | Klien menampilkan teks RTL sebagai LTR | Bungkus output dalam \u202B (penyematan RTL) atau gunakan tampilan yang mendukung RTL |
| Tanda diakritik hilang | Gambar beresolusi rendah | Gunakan gambar CAPTCHA dengan resolusi lebih tinggi |
| Teks dua arah (Arab+angka) campur aduk | Algoritma BiDi diterapkan secara tidak konsisten | Tangani karakter arah secara eksplisit dengan penanda Unicode |
| Pengiriman formulir gagal dengan masukan bahasa Arab | Ketidakcocokan pengkodean | Gunakan charset=UTF-8 di header Tipe Konten |
| Posisi CAPTCHA berbeda dari yang diharapkan | Tata letak RTL mencerminkan posisi elemen | Gunakan pemilih CSS daripada deteksi berbasis posisi |
Pertanyaan Umum
Apakah CaptchaAI menangani skrip Arab yang terhubung?
Ya. Karakter Arab terhubung ketika berdekatan — huruf yang sama terlihat berbeda tergantung pada posisinya dalam sebuah kata. Pemecah Image/OCR CaptchaAI mengenali aksara Arab yang terhubung termasuk bentuk huruf awal, tengah, akhir, dan terisolasi.
Bagaimana cara menangani CAPTCHA Farsi vs. CAPTCHA Arab?
Keduanya menggunakan aksara Arab tetapi dengan karakter tambahan (seperti Ù¾, Ú†, Ú˜, Ú¯ dalam bahasa Farsi). Gunakan language=2 untuk keduanya. CaptchaAI mengenali kumpulan karakter yang diperluas secara otomatis.
Apakah tata letak halaman RTL memengaruhi deteksi CAPTCHA?
Tata letak RTL mencerminkan halaman – formulir dan CAPTCHA mungkin muncul di sisi yang berlawanan dibandingkan dengan halaman LTR. Gunakan pemilih atau ID CSS untuk menemukan elemen CAPTCHA daripada mengandalkan posisi visual.
Langkah Selanjutnya
Pecahkan CAPTCHA di situs web berbahasa Arab dan RTL — dapatkan kunci API CaptchaAI Anda dan tangani kumpulan karakter RTL apa pun.
Panduan terkait:
- Memecahkan CAPTCHA di Situs Web China
- Lokalisasi CAPTCHA dan Pengaturan Bahasa