Explainers

O que é o Solve Media CAPTCHA

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

  1. O widget carrega e exibe uma mensagem publicitária como uma imagem
  2. O usuário lê a frase da marca e a digita na caixa de entrada
  3. A resposta é verificada pelos servidores da Solve Media
  4. 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.script na 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.

  1. Capture a imagem do widget.
  2. Envie em base64 para o endpoint in.php.
  3. Consulte o resultado em res.php.
  4. 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:

  1. Rode os workers próximos ao alvo. Uma região como sa-east-1 reduz o RTT e evita timeouts falsos na consulta de resultado.
  2. Mantenha o exercício em ambiente de QA autorizado, com dados fictícios e permissão explícita do dono do sistema.
  3. 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.


Guias relacionados

Os comentários estão desativados para este artigo.