Solucionador de captchas para
Puppeteer
Resuelve el desafío dentro de la ejecución en lugar de dejar que falle el trabajo. Un ejemplo funcional en Node.js y las tres cosas que deciden si se acepta tu token.
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"]');Qué decide si se acepta el token
- Pasa tu proxy. El token debe generarse detrás de la misma IP de salida que lo envía. En los sistemas que evalúan la sesión esto es obligatorio, no una optimización.
- Usa el mismo user agent. Turnstile y varios sistemas antibot vinculan el token a un user agent. Te devolvemos el que se usó para que puedas reproducirlo exactamente.
- Pídelo tarde. Los tokens caducan en unos 120 segundos. Solicita uno cuando estés listo para enviar.
Bloqueante o con sondeo
El ejemplo usa ?wait=60, así que la llamada devuelve la resolución terminada y tu paso de Puppeteer sigue siendo lineal. Si prefieres no mantener una conexión abierta, quita el parámetro, guarda el id devuelto y consulta GET /v1/task/{id} cada cinco segundos. Un token que ya pagaste se puede recuperar durante diez minutos, así que una conexión caída no te hace perder la resolución.
Costo
$0.00598 por cada resolución exitosa de reCAPTCHA v2; las resoluciones fallidas nunca se cobran. Consulta los precios de cada tipo de desafío o la referencia de la API para ver la estructura completa de la solicitud.
Cómo encaja la resolución en Puppeteer
Puppeteer controla Chromium desde Node.js. La resolución es un solo fetch entre page.goto y el clic de envío, y page.evaluate coloca el token donde la página lo espera.
- 01Inicia con tu proxy
Arranca Chromium con --proxy-server y configura el user agent que vas a indicar en la resolución.
- 02Lee la sitekey
page.$eval('[data-sitekey]', el => el.dataset.sitekey) y el nombre del callback si existe.
- 03Resuelve
Haz fetch a la API con ?wait=60; la respuesta incluye el token y el user agent utilizado.
- 04Inyecta y envía
Usa page.evaluate para escribir el token y disparar el callback, y luego haz clic en enviar.
Cómo meter el token en la página
page.evaluate rellena el campo de respuesta y llama al callback en el contexto de la página.
Dónde suelen fallar las integraciones
Chromium ignora las credenciales en --proxy-server. Usa page.authenticate para el navegador y pasa la URL completa del proxy a la resolución.
El widget está en un iframe, pero el campo de respuesta está en el frame principal. Inyecta en el frame principal.
Los tokens son de un solo uso. Si el envío falla, vuelve a resolver en lugar de reutilizar el primer token.
Preguntas frecuentes sobre captchas en Puppeteer
¿Necesito puppeteer-extra o un plugin de captchas?
No. Un solo fetch a la API y una llamada a page.evaluate bastan, y mantienes el control total sobre cuándo se hace la resolución y cuánto cuesta.
¿Funciona en modo headless?
Sí. El token lo genera nuestra infraestructura, no tu navegador, así que headless o con interfaz no cambia nada en la resolución en sí. Los sitios pueden tratar los navegadores headless con más sospecha, así que pasar un user agent realista sigue ayudando.
¿Puedo usarlo con Playwright para Node?
Sí. El código es casi idéntico; page.evaluate y page.locator de Playwright sustituyen a sus equivalentes de Puppeteer.
¿Cómo resuelvo Cloudflare Turnstile en Puppeteer?
Lee la sitekey del widget de Turnstile, envía type turnstile con la URL de la página, y luego rellena el input cf-turnstile-response y llama al callback si la página declara uno.
Guías útiles
¿Listo para construir?
Empieza con una prueba gratuita de 3 días y luego paga por cada resolución exitosa a medida que crece tu tráfico. No necesitas tarjeta para la prueba.