Cas d'Usage

Gérer les CAPTCHA arabes et les interfaces RTL avec CaptchaAI

Les sites en arabe, en farsi ou en hébreu présentent souvent des CAPTCHA image et des interfaces right-to-left qui posent des problèmes différents des pages classiques en alphabet latin. Ici, la difficulté ne vient pas seulement de l'image à lire, mais aussi de la forme contextuelle des lettres, du mélange chiffres plus texte, et de la mise en page RTL qui change la position attendue des champs et des contrôles.

Pour qu'un workflow soit fiable, il faut gérer à la fois l'OCR du captcha et le contexte d'affichage de la page. C'est exactement le type de cas où un traitement générique finit par casser plus vite qu'il ne produit de données propres.

Principaux defis sur les CAPTCHA RTL

Défi Détail
Formes contextuelles Les lettres arabes changent selon leur position dans le mot
Lecture droite-gauche Le texte du CAPTCHA suit une logique RTL
Direction mixte Chiffres et caractères latins peuvent se mélanger à l'arabe
Signes diacritiques Les points et marques changent fortement la lecture
Layout RTL Les formulaires et zones CAPTCHA ne sont pas placés comme sur une page LTR

Python : résoudre un CAPTCHA image en arabe

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 : gérer un CAPTCHA arabe sur une page RTL

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}`);

Écritures RTL prises en charge

Script Langues Exemples de caracteres
Arabe Arabe, ourdou, pachto texte arabe connecte
Farsi / persan Farsi caracteres specifiques au persan
Hebreu Hebreu alphabet hebreu

Dépannage

Probleme Cause probable Correctif
Texte arabe affiché à l'envers Le client rend le RTL comme du LTR Forcez un affichage compatible RTL ou utilisez des marqueurs Unicode adaptés
Les diacritiques disparaissent L'image est trop dégradée Travaillez avec une image plus nette ou moins compressée
Le texte arabe plus chiffres devient illisible Le traitement bidirectionnel est incohérent Gérez les marqueurs directionnels de manière explicite
Le formulaire échoue après saisie Problème d'encodage Assurez-vous d'envoyer charset=UTF-8
Le CAPTCHA n'est pas trouvé au bon endroit La page RTL inverse la disposition attendue Basez-vous sur des sélecteurs CSS ou IDs, pas sur la position visuelle

FAQ

CaptchaAI gère-t-il l'écriture arabe connectée ?

Oui. C'est justement l'un des points critiques de l'OCR sur ces pages : la même lettre change de forme selon sa position. Le solveur Image/OCR de CaptchaAI traite ce type d'écriture connectée bien mieux qu'un OCR basique généraliste.

Faut-il un traitement différent pour le farsi et l'arabe ?

Les deux utilisent la même famille d'écriture, avec quelques caractères supplémentaires côté persan. En pratique, language=2 reste le bon paramètre pour ces cas, et CaptchaAI gère l'ensemble étendu.

Les pages RTL changent-elles vraiment la détection du CAPTCHA ?

Oui. Sur une interface RTL, les formulaires, blocs et zones de saisie sont souvent inversés par rapport à une page LTR. Il faut donc localiser les éléments par sélecteur ou identifiant, pas par hypothèse visuelle.

Prochaines étapes

Si vous ciblez des sites en arabe ou d'autres interfaces RTL, récupérez votre clé API CaptchaAI et adaptez votre pipeline OCR à ces jeux d'écriture au lieu d'utiliser un flux purement latin.

Guides associés :

Les commentaires sont désactivés pour cet article.