Cómo eludir Cloudflare
En este artículo aprenderás cómo eludir la página de Cloudflare "Verifying you are human" usando NodeJS con automatización del navegador Playwright.

Primero comprendamos brevemente cómo funciona Cloudflare. Sin Cloudflare, los administradores de sitios web alojan sus páginas en un servidor con una dirección IP pública. Sus nombres de dominio se resuelven a esa dirección IP y tu navegador se conecta directamente a su servidor.
Cuando utilizan Cloudflare, delegan la gestión de DNS a Cloudflare, que comienza a resolver los nombres de dominio hacia sus propias direcciones IP. En estas direcciones IP ejecutan servidores proxy especiales que filtran las solicitudes HTTP y HTTPS entrantes.
Los nuevos visitantes ven la conocida página con el texto: "Verifying you are human. This may take a few seconds.". Durante esta verificación, es posible que debas resolver un captcha. Anteriormente usaban reCAPTCHA, pero ahora utilizan su propio captcha llamado Turnstile.
Una vez que se pasa la verificación del captcha, el navegador recibe un token único en una cookie llamada cf_clearance. Tu navegador usará este token para solicitar las páginas del sitio desde el proxy de Cloudflare. Si este token expira, o si Cloudflare decide internamente que el token se comporta como lo haría uno usado por bots, lo invalidará y volverás a ver la verificación captcha.
Nuestro método te ayudará a obtener este token usando una sesión de navegador automatizada. Ten en cuenta que este método no revela la dirección IP real del sitio web; esa información solo la conocen Cloudflare y los administradores del sitio. ¡Y eso está bien!
Así es como hacerlo con NodeJS y Playwright:
// Install packages
// npx install playwright @antiadmin/anticaptchaofficial
import { chromium } from "playwright";
import ac from "@antiadmin/anticaptchaofficial";
// Specify the target website address
const websiteBehindCloudFlare = 'https://yourwebsite.com';
// Set your Anti-Captcha API key here:
ac.setAPIKey('API_KEY_HERE');
ac.setSoftId(0);
let browser = null;
let page = null;
(async () => {
// Opening the browser
try {
console.log('Opening browser ..');
browser = await chromium.launch({ headless: false });
console.log('Creating new page ..');
page = await browser.newPage();
} catch (e) {
console.log("Could not open browser: "+e.toString());
return;
}
let params = null;
try {
// Doing several attempts to inject our code
while (!params) {
console.log('Navigating to the page')
await page.goto(websiteBehindCloudFlare);
console.log('Injecting our proxy code to replace window.turnstile');
await page.evaluate(() => {
window.turnstile = new Proxy(window.turnstile, {
get(target, prop) {
if (prop === "render") {
return function (a, b) {
const p = {
websiteURL: window.location.href,
websiteKey: b.sitekey,
action: b.action,
cData: b.cData,
chlPageData: b.chlPageData,
userAgent: navigator.userAgent,
};
// saving params in window.params
window.params = p;
// assigning callback to a variable
window.cfCallback = b.callback
// calling original render function
return target.render.apply(this, arguments);
};
}
return target[prop];
},
});
});
console.log('Getting params');
params = await page.evaluate(() => {
return new Promise((resolve) => {
setTimeout(() => resolve(window.params || null), 5000);
});
});
if (!params) {
console.log('Retrying..');
await delay(3000);
}
}
console.log("Extracted Turnstile Params:", params);
console.log('Solving Turnstile captcha with Anti-Captcha')
const token = await ac.solveTurnstileProxyless(websiteBehindCloudFlare, params.websiteKey, params.action, params.cData, params.chlPageData);
// Running Cloudflare's callback function we previously assigned to window.cfCallback
await page.evaluate((token) => {
window.cfCallback(token)
}, token);
console.log('Waiting for redirects to finish')
await delay(5000);
// Get all cookies for current page
const cookies = await page.context().cookies();
// Find cf_clearance
const cf_clearance = cookies.filter(c => c.name === 'cf_clearance');
// Output cookies
console.log('Cookies:', cookies);
console.log('cf_clearance:', cf_clearance);
} catch (e) {
console.error('Could not inject proxy code:', e);
}
// close browser when needed
// await browser.close();
})();
function delay(time) {
return new Promise(function(resolve) {
setTimeout(resolve, time)
});
}
Esto es lo que hace nuestro código:
1. Abre una ventana del navegador y navega hasta la página de verificación de Cloudflare.
2. Reemplaza la función render de Turnstile con nuestra función proxy, donde capturamos los parámetros de inicialización así como la devolución de llamada del captcha.
3. Envía los parámetros de inicialización a la API de Anti-Captcha. Trabajadores humanos resuelven el captcha por ti y te proporcionan un token.
4. Llamamos a la función de devolución de llamada guardada anteriormente con el token de Turnstile como parámetro.
5. Cloudflare verifica internamente este token, establece la cookie en nuestro navegador y recarga la página.
6. Con esa cf_clearance, el navegador obtiene el contenido del sitio web desde el proxy de Cloudflare.