Você digitou o captcha exatamente como apareceu na imagem e mesmo assim o formulário devolveu "código inválido". Na maioria dos casos o problema não é OCR ruim — é confusão de alfabeto. Um "А" de um site russo e um "A" do teclado americano são visualmente idênticos na tela, mas ocupam pontos de código Unicode diferentes (U+0410 contra U+0041), e a validação do formulário compara bytes, não aparência. Este guia mostra como configurar language=2 na API da CaptchaAI para reconhecer cirílico corretamente em russo, ucraniano, búlgaro e sérvio, evitar a armadilha do homóglifo e validar o resultado em Python e JavaScript.
Por que letras cirílicas confundem o OCR (e o seu parser)
Sete pares de letras latinas e cirílicas são visualmente idênticos, mas correspondem a caracteres Unicode diferentes — essa é a raiz de quase todo captcha cirílico que "parece certo" e mesmo assim falha na validação.
| Aparência | Letra latina | Letra cirílica | Observação |
|---|---|---|---|
| A | A (U+0041) | А (U+0410) | Pontos de código diferentes |
| B | B (U+0042) | В (U+0412) | Cirílico é "Ve" |
| C | C (U+0043) | С (U+0421) | Cirílico é "Es" |
| E | E (U+0045) | Е (U+0415) | Codificação diferente |
| H | H (U+0048) | Н (U+041D) | Cirílico é "En" |
| O | O (U+004F) | О (U+041E) | Pontos de código diferentes |
| P | P (U+0050) | Р (U+0420) | Cirílico é "Er" |
Enviar o ponto de código errado faz o formulário rejeitar um texto que, a olho nu, está correto — o erro mais comum ao automatizar cadastro em sites do Leste Europeu.
Testando cadastros do Leste Europeu a partir do Brasil
Cenário comum em QA: ao testar o cadastro de um fornecedor do Leste Europeu em ambiente de staging, com dados fictícios, o captcha aparece em cirílico mesmo quando o resto da página está em inglês. Dois pontos ajudam nesse teste:
- Rode os workers de captcha na região mais próxima do site-alvo — a latência de
sa-east-1(São Paulo) até servidores no Leste Europeu costuma passar de 250 ms, o que pede um timeout de polling mais folgado do que em testes com sites nacionais. - Se o formulário capturar qualquer dado pessoal durante o teste, trate os logs de acordo com a LGPD, mesmo em staging.
Padrões comuns de captcha em cirílico
Nem todo captcha cirílico é uma palavra simples — reconhecer o padrão ajuda a prever como o solver vai se comportar e o que validar na resposta.
| Padrão | Descrição | Exemplo |
|---|---|---|
| Palavra cirílica pura | Palavra russa aleatória | ШКАФ, ПИРОГ |
| Latim misto + cirílico | Os dois alfabetos na mesma imagem | ABСDе (A, B, D latim; С, е cirílico) |
| Dígitos cirílicos por extenso | Número escrito como palavra | ПЯТЬ (cinco), ТРИ (três) |
| Matemática em russo | Conta escrita por extenso | два плюс три = ? |
| Cirílico distorcido | Texto russo com distorção visual | Desafio de OCR padrão, só que em cirílico |
Solução de problemas: erros comuns com captcha cirílico
| Problema | Causa | Correção |
|---|---|---|
| Formulário rejeita um texto que parece certo | Letra latina e cirílica confundidas (homóglifo) | Compare os pontos de código: А (U+0410) ≠ A (U+0041) |
| Caracteres corrompidos na tela | Codificação incorreta | Use UTF-8 do início ao fim; defina response.encoding = 'utf-8' |
| Texto de script misto sai parcialmente errado | O OCR confundiu latim com cirílico | Envie com language=2 para o CaptchaAI distinguir corretamente |
| Faltam caracteres específicos do ucraniano | ґ, є, і, ї não reconhecidos | Já são suportados com language=2 |
| Captcha sensível a maiúsculas/minúsculas | A validação diferencia caixa alta de baixa | Envie exatamente como a CaptchaAI retornou |
Python: resolvendo captcha de imagem em cirílico
O parâmetro language=2 avisa o OCR da CaptchaAI para usar modelos com reconhecimento de cirílico, retornando os pontos de código corretos em vez de aproximar para a letra latina mais parecida. O exemplo cobre três casos:
- Resolver a partir de um arquivo de imagem local.
- Resolver dentro de uma sessão autenticada, direto da URL do captcha.
- Confirmar que o texto devolvido realmente contém caracteres cirílicos antes de enviá-lo ao formulário.
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_cyrillic_captcha(image_path: str) -> str:
"""Solve a Cyrillic text 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_cyrillic_from_session(session: requests.Session,
captcha_url: str) -> str:
"""Solve a Cyrillic CAPTCHA within a session context."""
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")
def verify_cyrillic(text: str) -> bool:
"""Verify that solved text contains Cyrillic characters."""
return any('\u0400' <= ch <= '\u04FF' for ch in text)
# --- Russian website form flow ---
def solve_russian_form(form_url: str, captcha_url: str,
form_data: dict) -> requests.Response:
"""Complete a Russian website form with CAPTCHA."""
session = requests.Session()
session.headers.update({
"Accept-Language": "ru-RU,ru;q=0.9",
})
# Establish session
session.get(form_url, timeout=15)
# Solve CAPTCHA
captcha_text = solve_cyrillic_from_session(session, captcha_url)
print(f"Cyrillic CAPTCHA: {captcha_text}")
if verify_cyrillic(captcha_text):
print("Confirmed: contains Cyrillic characters")
form_data["captcha"] = captcha_text
return session.post(form_url, data=form_data, timeout=30)
# --- Usage ---
text = solve_cyrillic_captcha("russian_captcha.png")
print(f"Solved: {text}")
print(f"Is Cyrillic: {verify_cyrillic(text)}")
print(f"Unicode codepoints: {[hex(ord(c)) for c in text]}")
JavaScript: tratando captcha cirílico em Node.js
A mesma lógica em Node.js: envie a imagem em base64 com language=2, faça o polling em res.php e confirme os codepoints antes de enviar o texto ao formulário. Vale manter o mesmo padrão de retry usado no exemplo Python — 24 tentativas com 5 segundos de intervalo cobrem confortavelmente o tempo típico de resolução de OCR.
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 solveCyrillicCaptcha(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");
}
function isCyrillic(text) {
return /[\u0400-\u04FF]/.test(text);
}
function showCodepoints(text) {
return [...text].map((ch) => `${ch}=U+${ch.codePointAt(0).toString(16).padStart(4, "0")}`);
}
// Usage
const text = await solveCyrillicCaptcha("russian_captcha.png");
console.log(`Solved: ${text}`);
console.log(`Is Cyrillic: ${isCyrillic(text)}`);
console.log(`Codepoints: ${showCodepoints(text).join(", ")}`);
Perguntas frequentes
O CaptchaAI resolve russo, ucraniano, búlgaro e sérvio com a mesma configuração?
Sim. Os quatro usam o alfabeto cirílico e o parâmetro language=2 cobre todos eles, incluindo os caracteres exclusivos do ucraniano (ґ, є, і, ї). Não é preciso trocar de endpoint nem de método por idioma — apenas confirmar o parâmetro no envio.
Por que o texto que resolvi está "certo" e o formulário recusa mesmo assim?
Quase sempre é confusão de alfabeto: a letra que parece igual na tela é cirílica de um lado e latina do outro. Rode verify_cyrillic() (ou o equivalente isCyrillic() em JavaScript) sobre o texto antes de reenviar — se o resultado não bater com o esperado, o problema está nos codepoints, não no solver.
Quanto custa resolver captchas cirílicos com a CaptchaAI?
O preço não muda por tipo de captcha nem por idioma — todos os planos cobram por thread simultânea, com resoluções ilimitadas por thread. O BASIC (US$ 15/mês, 5 threads) já cobre captcha de imagem/OCR com language=2; para volume maior de scraping contínuo, o ADVANCE (US$ 90/mês, 50 threads) costuma ser o ponto de partida.
O CaptchaAI reconhece outros alfabetos além do latim e do cirílico?
Sim — o OCR cobre outros conjuntos de caracteres não latinos. Veja o conjunto de caracteres CAPTCHA de imagem multilíngue e o guia de captcha em sites chineses para os parâmetros específicos de cada idioma.
Preciso mudar algo no meu scraper para não corromper o texto cirílico?
O parâmetro do CaptchaAI já resolve a parte do reconhecimento — o ponto de atenção é o seu lado. Garanta UTF-8 do início ao fim (requisição, resposta e gravação em log ou banco) e não normalize acentos ou maiúsculas antes de enviar o texto ao formulário: isso pode trocar um caractere cirílico pelo latino parecido e derrubar a validação.
Guias relacionados
- Como resolver captcha em sites chineses
- Conjunto de caracteres CAPTCHA de imagem multilíngue
- Localização de CAPTCHA e configurações de idioma
Resolva captchas cirílicos em sites russos, ucranianos, búlgaros e sérvios — crie sua conta na CaptchaAI.