CAPTCHAs de imagens complexas usam letras conectadas, caracteres sobrepostos, fontes variadas e ruído para evitar OCR. Veja como abordá-los com CaptchaAI.
Tipos comuns de complexidade
| Tipo | Descrição | Dificuldade |
|---|---|---|
| Texto limpo | Sem distorção, fonte uniforme | Fácil |
| Texto distorcido | Letras giradas individualmente/scaled | Médio |
| Letras conectadas | Os caracteres se sobrepõem ou se tocam | Difícil |
| Multi-fonte | Fontes diferentes por caractere | Difícil |
| Ruído + linhas | Ruído de fundo, linhas tachadas | Médio |
| Variação de cor | Cores diferentes por personagem | Médio |
| Expressão matemática | Números + operadores, resultado esperado | Médio |
Envio de CAPTCHAs complexos
Para CAPTCHAs padrão de vários caracteres, envie via base64 com dicas apropriadas:
import requests
import base64
import time
import os
API_KEY = os.environ["CAPTCHAAI_API_KEY"]
def solve_complex_image(image_b64, hints=None):
"""Solve a complex multi-character image CAPTCHA."""
payload = {
"key": API_KEY,
"method": "base64",
"body": image_b64,
"json": 1,
}
if hints:
payload.update(hints)
resp = requests.post(
"https://ocr.captchaai.com/in.php",
data=payload,
timeout=30,
)
result = resp.json()
if result.get("status") != 1:
raise RuntimeError(f"Submit failed: {result.get('request')}")
task_id = result["request"]
time.sleep(8)
for _ in range(24):
resp = requests.get("https://ocr.captchaai.com/res.php", params={
"key": API_KEY,
"action": "get",
"id": task_id,
"json": 1,
}, timeout=15)
data = resp.json()
if data.get("status") == 1:
return data["request"]
if data["request"] != "CAPCHA_NOT_READY":
raise RuntimeError(data["request"])
time.sleep(5)
raise TimeoutError("Solve timeout")
Estratégia: Letras Conectadas
Letras conectadas são as mais difíceis para OCR básico, mas não para CaptchaAI:
def solve_connected_letters(image_path):
"""Solve CAPTCHA with connected/overlapping characters."""
with open(image_path, "rb") as f:
b64 = base64.b64encode(f.read()).decode("ascii")
return solve_complex_image(b64, hints={
"textinstructions": "Characters may be connected or overlapping",
"minLen": 4,
"maxLen": 8,
})
Estratégia: Caso Misto com Ruído
def solve_noisy_mixed(image_path):
"""Solve CAPTCHA with background noise and mixed case."""
with open(image_path, "rb") as f:
b64 = base64.b64encode(f.read()).decode("ascii")
return solve_complex_image(b64, hints={
"regsense": 1, # Case-sensitive
"language": 2, # Latin characters
"textinstructions": "Ignore background lines and noise",
})
Estratégia: texto com várias fontes
def solve_multi_font(image_path):
"""Solve CAPTCHA using multiple fonts per character."""
with open(image_path, "rb") as f:
b64 = base64.b64encode(f.read()).decode("ascii")
return solve_complex_image(b64, hints={
"textinstructions": "Each character may use a different font or style",
"minLen": 5,
"maxLen": 7,
})
Pré-processamento de imagem para mais adequado resultados
O pré-processamento antes do envio pode aprimorar a precisão:
# preprocess.py
from PIL import Image, ImageFilter, ImageEnhance
import io
import base64
def preprocess_for_ocr(image_path):
"""Preprocess image to improve OCR accuracy."""
img = Image.open(image_path)
# Convert to grayscale
img = img.convert("L")
# Increase contrast
enhancer = ImageEnhance.Contrast(img)
img = enhancer.enhance(2.0)
# Sharpen
img = img.filter(ImageFilter.SHARPEN)
# Binarize (threshold)
threshold = 128
img = img.point(lambda p: 255 if p > threshold else 0)
# Encode back to base64
buffer = io.BytesIO()
img.save(buffer, format="PNG")
return base64.b64encode(buffer.getvalue()).decode("ascii")
Estratégia de repetição com relatórios
# retry_strategy.py
def solve_with_retry(image_b64, hints, max_retries=3):
"""Retry solving with fallback strategies."""
strategies = [
hints, # Original hints
{**hints, "textinstructions": ""}, # Without instructions
{**hints, "numeric": 0, "regsense": 0}, # Relaxed constraints
]
for i, strategy in enumerate(strategies[:max_retries]):
try:
result = solve_complex_image(image_b64, strategy)
return {"text": result, "strategy": i, "success": True}
except RuntimeError:
continue
return {"text": None, "strategy": -1, "success": False}
def report_bad_answer(task_id):
"""Report incorrect answer for quality feedback."""
requests.get("https://ocr.captchaai.com/res.php", params={
"key": API_KEY,
"action": "reportbad",
"id": task_id,
}, timeout=10)
Solução de problemas
| Problema | Causa | Correção |
|---|---|---|
| Personagens ausentes | Letras conectadas mal interpretadas | Adicione textinstructions sobre texto conectado |
| Personagens extras | Ruído interpretado como texto | Pré-processamento: remova o ruído antes do envio |
| Caso errado | Caso não preservado | Definir regsense=1 |
| Resultado matemático retornado como expressão | Faltando calc=1 |
Ative o modo de cálculo para CAPTCHAs matemáticos |
| Consistentemente errado em um site específico | Fonte específica do site | Relate respostas ruins para aprimorar o modelo |
Perguntas frequentes
Devo pré-processar as imagens antes de enviar?
Somente se você estiver obtendo resultados ruins. CaptchaAI lida com a maioria das distorções nativamente. O pré-processamento ajuda em imagens com muito ruído ou baixo contraste.
E se o mesmo tipo de imagem continuar falhando?
Relate respostas ruins com reportbad para ajudar a aprimorar a precisão. Tente também adicionar textinstructions específico descrevendo as características do CAPTCHA.
Existe um limite de caracteres para CAPTCHAs de imagem?
CaptchaAI pode lidar com CAPTCHAs de até 20 caracteres. A maioria tem de 4 a 8 caracteres.
Guias Relacionados
- Resolva CAPTCHAs de imagens complexas -comece com CaptchaAI.*