Solucionador de captcha para
Puppeteer
Resolva o desafio dentro da execução em vez de deixar o job falhar. Um exemplo funcional em Node.js e os três fatores que decidem se o seu token é aceito.
import puppeteer from "puppeteer";
const CAPTCHANO_KEY = "cn-YOUR_API_KEY";
async function solve(task) {
const headers = {
Authorization: `Bearer ${CAPTCHANO_KEY}`,
"Content-Type": "application/json",
};
const res = await fetch("https://api.captchano.com/v1/solve?wait=60", {
method: "POST",
headers,
body: JSON.stringify(task),
});
let data = await res.json();
// A solve can outlast the 60 s wait: poll the task until it finishes.
while (data.status === "queued" || data.status === "solving") {
await new Promise((r) => setTimeout(r, 5000));
const poll = await fetch(`https://api.captchano.com/v1/task/${data.id}`, { headers });
data = await poll.json();
}
if (data.status !== "ready") throw new Error(JSON.stringify(data.error ?? data));
return data.solution; // { token, userAgent }
}
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto("https://example.com/signup");
const sitekey = await page.$eval("[data-sitekey]", (el) => el.getAttribute("data-sitekey"));
const { token, userAgent } = await solve({ type: "turnstile", sitekey, url: page.url() });
// Turnstile binds the token to a user agent: replay the one it was minted with.
if (userAgent) await page.setUserAgent(userAgent);
await page.evaluate((t) => {
document.querySelector('[name="cf-turnstile-response"]').value = t;
}, token);
await page.click('button[type="submit"]');O que decide se o token é aceito
- Repasse seu proxy. O token deve ser gerado por trás do mesmo IP de saída que o envia. Em sistemas que avaliam a sessão, isso é obrigatório, não uma otimização.
- Use o mesmo user agent. O Turnstile e vários sistemas anti-bot vinculam o token a um user agent. Retornamos o que foi usado para que você possa reutilizá-lo exatamente.
- Solicite no último momento. Os tokens expiram em cerca de 120 segundos. Peça um quando estiver pronto para enviar.
Bloqueante ou polling
O exemplo usa ?wait=60, então a chamada retorna a resolução pronta e a sua etapa no Puppeteer continua linear. Se você preferir não manter uma conexão aberta, remova o parâmetro, guarde o id retornado e faça polling em GET /v1/task/{id} a cada cinco segundos. Um token pelo qual você já pagou continua disponível por dez minutos, então uma conexão perdida não faz você perder a resolução.
Custo
$0.00598 por resolução bem-sucedida de reCAPTCHA v2, e resoluções que falham nunca são cobradas. Veja os preços de todos os tipos de desafio ou a referência da API para o formato completo da requisição.
Como a resolução se encaixa no Puppeteer
O Puppeteer controla o Chromium a partir do Node.js. A resolução é um único fetch entre page.goto e o clique de envio, e page.evaluate coloca o token onde a página espera.
- 01Inicie com seu proxy
Inicie o Chromium com --proxy-server e defina o user agent que você vai informar à resolução.
- 02Leia a sitekey
page.$eval('[data-sitekey]', el => el.dataset.sitekey) e o nome do callback, se existir.
- 03Resolva
Faça fetch na API com ?wait=60; a resposta traz o token e o user agent utilizado.
- 04Injete e envie
Use page.evaluate para gravar o token e disparar o callback, depois clique em enviar.
Colocando o token na página
page.evaluate define o campo de resposta e chama o callback no contexto da página.
Onde as integrações costumam dar errado
O Chromium ignora credenciais em --proxy-server. Use page.authenticate no navegador e passe a URL completa do proxy para a resolução.
O widget fica em um iframe, mas o campo de resposta está no frame principal. Injete no frame principal.
Tokens são de uso único. Se o envio falhar, resolva novamente em vez de reutilizar o primeiro token.
Perguntas frequentes sobre captcha no Puppeteer
Preciso do puppeteer-extra ou de um plugin de captcha?
Não. Um único fetch para a API e uma chamada a page.evaluate bastam, e você mantém controle total sobre quando a resolução acontece e quanto ela custa.
Funciona em modo headless?
Sim. O token é gerado pela nossa infraestrutura, não pelo seu navegador, então headless ou não, não faz diferença para a resolução em si. Os sites podem tratar navegadores headless com mais desconfiança, por isso passar um user agent realista ainda ajuda.
Posso usar com o Playwright para Node?
Sim. O código é quase idêntico; page.evaluate e page.locator do Playwright substituem os equivalentes do Puppeteer.
Como resolver o Cloudflare Turnstile no Puppeteer?
Leia a sitekey do widget do Turnstile, envie type turnstile com a URL da página e, em seguida, defina o input cf-turnstile-response e chame o callback, se a página declarar um.
Guias que ajudam
Pronto para começar?
Comece com um teste grátis de 3 dias e depois pague por resolução bem-sucedida conforme seu tráfego cresce. Não é preciso cartão para o teste.