Solve Media é um CAPTCHA de texto em que o desafio é um anúncio: em vez de decifrar "aX3kP", o visitante lê um slogan de marca na imagem e digita a frase. Para quem automatiza formulários, isso muda pouco na prática — continua sendo texto dentro de uma imagem, e é resolvido pelo mesmo caminho de OCR usado em qualquer CAPTCHA de imagem.
O produto foi adquirido e reposicionado (hoje sob Permit.io / Radius Networks), então implantações novas praticamente não existem. Mas ele ainda aparece em formulários antigos: painéis internos que ninguém migrou, plugins de CMS desatualizados, portais legados de cadastro. Se você mantém uma suíte de testes de QA que roda contra sistemas com anos de estrada, é bem provável que um dia esbarre nele.
Por que um CAPTCHA feito de anúncio é mais fácil para OCR
A diferença começa na intenção do produto. O Solve Media nasceu como inventário publicitário: o anunciante paga para que a frase da marca seja lida, o que significa que ela precisa ser legível. Um CAPTCHA de texto tradicional busca o oposto — distorce, sobrepõe ruído e emenda caracteres justamente para atrapalhar leitura automática.
O resultado é um desafio com texto limpo, palavras reais e pouca distorção, exatamente o cenário em que motores de OCR trabalham bem.
| Característica | Solve Media | CAPTCHA de texto tradicional |
|---|---|---|
| Conteúdo do texto | Frases de marca, palavras reais | Caracteres aleatórios |
| Legibilidade | Alta (feita para ser lida) | Baixa (feita para atrapalhar) |
| Distorção | Mínima | Intensa |
| Modelo de receita | Publicidade | Nenhum |
| Dificuldade para OCR | Baixa (texto limpo) | Alta (texto deformado) |
| Experiência do usuário | Melhor (palavras reconhecíveis) | Pior (difícil de ler) |
Como o desafio funciona, passo a passo
- O widget carrega e exibe uma mensagem publicitária como uma imagem
- O usuário lê a frase da marca e a digita na caixa de entrada
- A resposta é verificada pelos servidores da Solve Media
- Se correto, o envio do formulário prossegue
┌─────────────────────────────────┐
│ │
│ "Taste The Rainbow" │
│ │
├─────────────────────────────────┤
│ Type the phrase: [____________] │
│ [Verify] │
└─────────────────────────────────┘
O ponto que importa para automação: a validação roda no servidor da Solve Media, e o formulário envia apenas dois campos ocultos.
Como identificar o Solve Media no HTML da página
Antes de escrever qualquer código, confirme que é mesmo Solve Media. Abra o DevTools e procure estes marcadores:
<!-- Solve Media script -->
<script src="https://api.solvemedia.com/papi/challenge.script"></script>
<!-- Widget container -->
<div id="adcopy-outer"></div>
<!-- Hidden response fields -->
<input type="hidden" name="adcopy_challenge" />
<input type="hidden" name="adcopy_response" />
Qualquer elemento com id começando em adcopy- ou solvemedia é sinal claro.
Antes de partir para OCR, faça uma triagem rápida na página — ela costuma poupar uma requisição inteira:
- Inspecione o campo oculto
adcopy_challenge: em implementações antigas, o texto da frase às vezes já vem no próprio HTML. - Confira a resposta da chamada a
challenge.scriptna aba Network; alguns builds devolvem a frase em texto plano. - Só quando as duas verificações falharem, capture a imagem do widget e siga para o OCR.
Essa ordem importa porque cada consulta evitada é uma thread livre no seu plano e um segundo a menos no tempo total da suíte.
Resolvendo o Solve Media com a CaptchaAI
Como o desafio é texto dentro de uma imagem, ele entra pelo método padrão de OCR — não existe, nem é necessário, um método dedicado.
- Capture a imagem do widget.
- Envie em base64 para o endpoint
in.php. - Consulte o resultado em
res.php. - Digite a frase no campo de resposta.
Python
import requests
import time
import base64
API_KEY = "YOUR_API_KEY"
# Capture the CAPTCHA image
# Method 1: Screenshot the widget
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.get("https://example.com/page-with-solvemedia")
captcha_img = driver.find_element(By.CSS_SELECTOR, "#adcopy-puzzle-image img")
captcha_img.screenshot("solvemedia.png")
# Submit to CaptchaAI
with open("solvemedia.png", "rb") as f:
img_b64 = base64.b64encode(f.read()).decode()
response = requests.post("https://ocr.captchaai.com/in.php", data={
"key": API_KEY,
"method": "base64",
"body": img_b64,
"phrase": 1, # Contains spaces (multi-word phrase)
"json": 1
})
task_id = response.json()["request"]
# Poll for solution
for _ in range(30):
time.sleep(5)
result = requests.get("https://ocr.captchaai.com/res.php", params={
"key": API_KEY, "action": "get", "id": task_id, "json": 1
}).json()
if result.get("status") == 1:
text = result["request"]
print(f"Phrase: {text}")
break
# Type the phrase
driver.find_element(By.CSS_SELECTOR, "#adcopy_response").send_keys(text)
driver.find_element(By.CSS_SELECTOR, "form").submit()
Node.js
const axios = require('axios');
const fs = require('fs');
async function solveSolveMedia(imagePath) {
const imageB64 = fs.readFileSync(imagePath).toString('base64');
const submit = await axios.post('https://ocr.captchaai.com/in.php', null, {
params: {
key: 'YOUR_API_KEY',
method: 'base64',
body: imageB64,
phrase: 1,
json: 1
}
});
const taskId = submit.data.request;
for (let i = 0; i < 30; i++) {
await new Promise(r => setTimeout(r, 5000));
const res = await axios.get('https://ocr.captchaai.com/res.php', {
params: { key: 'YOUR_API_KEY', action: 'get', id: taskId, json: 1 }
});
if (res.data.status === 1) return res.data.request;
}
throw new Error('Timeout');
}
O intervalo de 5 segundos entre consultas é deliberado: o polling agressivo só gasta requisição sem acelerar nada.
Parâmetros que fazem diferença no resultado
A maioria dos erros de OCR com Solve Media não vem do motor de reconhecimento, e sim de parâmetros mal ajustados na requisição.
| Ajuste | Por quê |
|---|---|
Defina phrase=1 |
As frases do Solve Media contêm espaços |
Defina numeric=2 |
Em geral são apenas letras, sem dígitos |
Não defina min_len/max_len |
O comprimento da frase varia bastante |
| Preserve maiúsculas e minúsculas | Nem toda implementação ignora a caixa |
Um cenário prático de QA
Imagine uma equipe em São Paulo que mantém o portal de cadastro de fornecedores de uma empresa — um sistema de 2014, ainda em produção, com Solve Media no formulário. A suíte de regressão precisa criar registros fictícios em staging toda noite, e o widget derruba o teste antes do primeiro assert.
O caminho técnico é o mesmo descrito acima, mas o cuidado de ambiente decide se a suíte fica estável:
- Rode os workers próximos ao alvo. Uma região como
sa-east-1reduz o RTT e evita timeouts falsos na consulta de resultado. - Mantenha o exercício em ambiente de QA autorizado, com dados fictícios e permissão explícita do dono do sistema.
- Se houver dados pessoais em qualquer ponto do fluxo, considere as obrigações da LGPD antes de armazenar qualquer coisa — em Portugal, o equivalente é o RGPD.
Um sintoma comum vale registrar desde já: se o formulário falha apenas no navegador enquanto a API responde normalmente, o problema costuma estar na captura da imagem ou no seletor do campo, não no reconhecimento. Isole as duas camadas antes de culpar o motor de OCR.
Perguntas frequentes
Vale a pena implementar suporte a Solve Media hoje?
Só se você já encontrou um. Implantações novas são raras desde a aquisição, então trate como código de compatibilidade: reaproveite seu fluxo genérico de OCR de imagem em vez de manter um caminho separado.
Qual a diferença entre phrase=1 e o padrão?
Com phrase=1 você avisa que a resposta contém mais de uma palavra, com espaços. Sem esse parâmetro, o resultado tende a vir emendado ou truncado na primeira palavra, e o formulário rejeita o envio.
Como testo isso sem depender de um site de terceiros?
Reproduza o widget em uma página de staging sob seu controle e valide o fluxo ali, chamando o endpoint diretamente a partir do seu formulário de teste. É a forma segura de medir tempo de resolução sem gerar tráfego em sistemas de outra pessoa.
O plano BASIC dá conta desse volume?
Para uma suíte noturna de testes, sim. O limite prático é a concorrência, não a quantidade de solves:
- BASIC (US$ 15/mês, 5 threads) — cinco desafios simultâneos, suficiente para uma suíte em uma máquina.
- STANDARD (US$ 30/mês, 15 threads) — o degrau seguinte quando a regressão roda em paralelo em várias máquinas.
Se ainda não tiver uma chave, comece pelo guia de início rápido da CaptchaAI.
Quais tipos a CaptchaAI cobre além de imagem e OCR?
Os tipos suportados são reCAPTCHA v2 e v3, Cloudflare Turnstile e Cloudflare Challenge, GeeTest v3 e os CAPTCHAs de imagem/OCR, texto e grade de imagens — família à qual o Solve Media pertence. hCaptcha e FunCaptcha não entram nessa lista; GeeTest v4 está anunciado como "em breve". CaptchaFox, Friendly Captcha e Lemin estão disponíveis apenas em beta.