Solver de captcha em Node.js: exemplo funcional com fetch (2026)
Um solver de captcha em Node.js é uma única requisição HTTP. O Node 18 e versões posteriores trazem o fetch, então você não precisa de pacote nenhum para chamar a API. Envie o sitekey e a URL da página, aguarde a resposta e coloque o token no formulário. Este guia mostra o fluxo completo para o PopularCaptcha, que a Scarnox resolve hoje de forma proxyless.
Comece com crédito de teste grátis, sem cartão e rode o código abaixo em uma página de teste primeiro.
Requisitos
- Node.js 18 ou mais recente (
node --version). - Uma chave de API da Scarnox. Guarde-a em uma variável de ambiente.
- O sitekey do widget PopularCaptcha da página. Se ainda não o tiver, veja como encontrar o sitekey de um captcha.
O módulo solver
O módulo abaixo é uma única função. Ela envia a requisição para a API com um cabeçalho Bearer, cancela após 185 segundos e lança um erro quando errorId não é 0:
// solver.mjs
const API_URL = "https://api.scarnox.com/api/tasks/create";
export async function solveCaptcha(sitekey, pageUrl, { invisible = false } = {}) {
const body = {
captcha_type: "PopularCaptchaTaskProxyless",
site_key: sitekey,
site_url: pageUrl,
};
if (invisible) body.is_invisible = true;
const res = await fetch(API_URL, {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.SCARNOX_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify(body),
signal: AbortSignal.timeout(185_000), // a chamada retorna quando o token está pronto
});
const data = await res.json().catch(() => null);
if (!data) throw new Error(`HTTP ${res.status}: response was not JSON`);
if (data.errorId !== 0) {
throw new Error(`${data.errorCode}: ${data.errorDescription}`);
}
return data.solution.token;
}
Não há polling. A requisição fica aberta até o token estar pronto, e o token está em solution.token em caso de sucesso.
Retentativas
Uma resolução com falha retorna errorId diferente de 0, e você não é cobrado por ela. Um loop curto de retentativas basta para falhas transitórias. Mantenha o número de tentativas baixo, para que um sitekey ou uma URL de página quebrados não consumam tempo à toa:
export async function solveWithRetry(sitekey, pageUrl, attempts = 3) {
let lastError;
for (let i = 1; i <= attempts; i++) {
try {
return await solveCaptcha(sitekey, pageUrl);
} catch (err) {
lastError = err;
console.warn(`Attempt ${i} failed: ${err.message}`);
await new Promise((r) => setTimeout(r, 1000 * i));
}
}
throw lastError;
}
Para uma política de erros mais completa, veja tratamento de erros do solver de captcha.
Enviando o token
O token vai para o campo do formulário que o site espera. A maioria das páginas com PopularCaptcha lê h-captcha-response, e muitas também leem g-recaptcha-response. Envie os dois por segurança:
// submit.mjs
import { solveWithRetry } from "./solver.mjs";
const pageUrl = "https://example.com/signup";
const token = await solveWithRetry("YOUR-SITEKEY-UUID", pageUrl);
const form = new URLSearchParams({
email: "you@example.com",
"h-captcha-response": token,
"g-recaptcha-response": token,
});
const res = await fetch(pageUrl, {
method: "POST",
body: form,
redirect: "manual",
});
console.log("Status:", res.status);
Execute com:
SCARNOX_API_KEY=scarnox_YOURAPIKEY node submit.mjs
Cookies e sessões
O fetch puro não mantém cookies entre as requisições. Muitas páginas de cadastro e busca vinculam o captcha a um cookie de sessão, então um token enviado sem o cookie correspondente pode ser rejeitado. Há duas formas de lidar com isso:
- Copie os valores de
set-cookieda resposta do GET e envie-os de volta no POST. - Use uma ferramenta de automação de navegador, que mantém a sessão para você. Veja resolução de captcha com Playwright e Puppeteer.
Escolha a primeira quando o formulário for simples e o site não rodar muito JavaScript. Escolha a segunda para qualquer coisa mais complexa.
Uma verificação prática: depois do POST, observe o código de status e a URL final. Um redirecionamento para uma página de sucesso geralmente significa que o token foi aceito. Uma página que mostra o widget de novo geralmente significa que ele foi rejeitado, ou que o cookie do GET não foi enviado. Registre o corpo da resposta nas primeiras execuções para saber em qual dos casos você está.
Tempo
O token expira em cerca de dois minutos. Resolva perto do momento do envio. O erro mais comum é resolver no início de um job longo e enviar depois. Resolva e envie imediatamente em seguida. Expiração de token de captcha cobre isso com mais detalhes.
Captchas invisíveis
Se o widget da página tiver data-size="invisible", passe { invisible: true }. A função então envia is_invisible: true junto com a requisição:
const token = await solveCaptcha("YOUR-SITEKEY-UUID", pageUrl, { invisible: true });
Se a página também anexar um callback ao widget, o formulário pode precisar que essa função seja chamada com o token. Leia o script da página para encontrá-la. O guia captcha invisível cobre os padrões.
Scraping com o solver
Às vezes o captcha aparece em uma página que você faz scraping, e não em um formulário que você envia. O mesmo padrão funciona: detecte o widget no HTML, resolva-o e envie-o para a URL para a qual o widget posta. Mantenha a taxa de requisições baixa e verifique os termos do site antes. Faça scraping com responsabilidade: respeite o robots.txt, evite dados pessoais de que você não precisa e não sobrecarregue o servidor.
Preços
A Scarnox cobra por resolução bem-sucedida. Resoluções com falha não são cobradas. Para os valores atuais, veja a página de preços. Para começar, comece com crédito de teste grátis, sem cartão.