Капча на арабском, фарси или иврите не решается тем же способом, что и капча на латинице: одна и та же буква меняет форму в зависимости от места в слове, текст читается справа налево, а сама форма и капча на странице могут стоять зеркально относительно привычной LTR-верстки. Ниже — рабочий подход через Image/OCR-решатель CaptchaAI: код на Python и Node.js, разбор типичных ошибок и то, на что обращать внимание в RTL-верстке при автоматизации.
На практике с этим чаще всего сталкиваются команды, которые в контуре QA или staging проверяют регистрацию на арабоязычных версиях порталов — от визовых и государственных сервисов до локальных маркетплейсов Персидского залива. Капча там нередко смешивает арабские буквы с цифрами (двунаправленный текст), а поля формы стоят в обратном от привычного порядке. Если нужно прогонять несколько вариантов формы параллельно, для этого достаточно тарифа BASIC ($15/мес, 5 потоков) — CaptchaAI тарифицирует по одновременным потокам, а не по числу решённых капч. И как обычно при работе с формами, где есть email или ФИО, стоит заранее убедиться, что вы обрабатываете только те персональные данные, которые вправе обрабатывать (152-ФЗ и аналогичные требования для трансграничных команд) — это не юридическая консультация, а просто разумная предварительная проверка.
Частые вопросы
Чем капча на фарси отличается от арабской?
Фарси использует тот же базовый арабский алфавит, но добавляет несколько букв — پ, چ, ژ, گ. Для обеих капч подходит один и тот же параметр language=2: CaptchaAI распознаёт расширенный набор символов автоматически, отдельно настраивать язык не нужно.
Поддерживает ли CaptchaAI капчу на иврите?
Да. Image/OCR-решатель обрабатывает изображения с ивритом так же, как арабские и фарси-капчи — через тот же base64-запрос с language=2. Иврит — тоже RTL-скрипт, но алфавит и правила соединения букв у него свои, отдельного эндпоинта под него не требуется.
Почему арабский текст в ответе API выглядит перевёрнутым?
Это почти всегда проблема отображения на стороне клиента, а не решения капчи: браузер или консоль показывает RTL-строку как LTR. Решённый текст от CaptchaAI приходит корректным — оберните его в управляющий символ RTL-embedding (U+202B) или выводите через компонент, который понимает направление письма.
Как искать капчу на странице, если RTL-верстка меняет расположение полей?
Не полагайтесь на визуальную позицию — на RTL-сайте она зеркальна относительно привычного LTR-макета. Используйте CSS-селекторы или атрибуты id/class (как в примере с Playwright ниже), это не зависит от того, в какую сторону отражена верстка.
Нужно ли менять кодировку запроса при работе с арабскими формами?
Да. Если в форме есть арабский, фарси или ивритский текст, заголовок Content-Type должен явно указывать charset=UTF-8 — иначе сервер сайта может отклонить отправку или исказить символы при разборе тела запроса.
Почему капча на арабском и других RTL-языках — отдельная задача
| Сложность | В чём проблема |
|---|---|
| Связанное написание букв | Арабская буква меняет форму в зависимости от соседних символов — начальная, срединная, конечная или изолированная позиция |
| Чтение справа налево | Текст в капче читается справа налево, а не слева направо |
| Двунаправленный текст | Цифры и латиница смешиваются с арабским текстом в одной строке |
| Диакритические знаки | Точки и знаки над и под буквами — например, ش и س различаются только положением точки |
| RTL-верстка страницы | Поля формы и расположение капчи зеркальны относительно LTR-сайтов |
Ниже — рабочий пример на Python: скрипт отправляет base64-изображение с арабским текстом в CaptchaAI, опрашивает результат и подставляет решённый текст в форму сайта. Параметр language=2 (поддержка не-латинских символов) обязателен для капчи с произвольным набором символов — арабских, в том числе с диакритикой.
Решение арабской image-капчи на Python
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": "[email protected]",
},
)
Node.js и Playwright: подстановка результата в RTL-форму
То же самое на Node.js, плюс пример инъекции решённого текста в поле формы через Playwright. Это удобно, когда капча встроена в RTL-размеченную страницу и элемент нужно искать не по координатам, а по CSS-селектору или атрибуту — 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}`);
Какие RTL-скрипты распознаёт CaptchaAI
| Скрипт | Языки | Пример |
|---|---|---|
| Арабский | арабский, урду, пушту | عربي — أبجدية (арабский — алфавит) |
| Фарси/Persian | фарси — добавляет буквы پ, چ, ژ, گ к арабскому алфавиту | فارسی — حروف (фарси — буквы) |
| Иврит | иврит | עברית — אותיות (иврит — буквы) |
Для всех трёх скриптов при отправке в CaptchaAI используется один и тот же параметр language=2 — отдельного режима для фарси или иврита настраивать не нужно, решатель сам определяет расширенный набор символов.
Типичные проблемы и как их решить
| Проблема | Причина | Решение |
|---|---|---|
| Арабский текст в ответе выводится задом наперёд | Клиентский код отображает RTL-текст как LTR | Оберните вывод в управляющий символ RTL-embedding (юникод U+202B) или используйте RTL-совместимый виджет отображения |
| Пропадают точки и диакритические знаки | Низкое разрешение изображения капчи | Запрашивайте капчу более высокого разрешения перед отправкой |
| Двунаправленный текст (арабский + цифры) перепутан местами | Алгоритм BiDi применяется непоследовательно | Обрабатывайте направленные символы явно, через Unicode-маркеры |
| Отправка формы с арабским текстом завершается ошибкой | Несовпадение кодировки запроса | Указывайте charset=UTF-8 в заголовке Content-Type |
| Капча стоит не там, где ожидалось | RTL-верстка зеркалирует расположение элементов | Ищите капчу по CSS-селектору или id, а не по позиции на странице |
Следующие шаги
Начните с быстрого старта CaptchaAI, а затем возьмите готовые примеры для конкретных типов капчи, которые часто встречаются на тех же сайтах, что и арабские image-капчи: