如何绕过 Cloudflare
本文将教你如何使用 NodeJS 和 Playwright 浏览器自动化来绕过 Cloudflare 的“Verifying you are human”页面。

首先我们简要了解一下 Cloudflare 是如何工作的。如果没有 Cloudflare,网站管理员会将网页托管在具有公网 IP 地址的服务器上。它们的域名解析到该 IP,您的浏览器会直接连接到该服务器。
当他们使用 Cloudflare 时,会将 DNS 管理交给 Cloudflare,Cloudflare 会将域名解析为自己的 IP 地址。这些 IP 地址上运行着特殊的代理服务器,用于过滤传入的 HTTP 和 HTTPS 请求。
新访问者会看到一个熟悉的页面,上面写着:“Verifying you are human. This may take a few seconds.”。在这个验证过程中,您可能需要完成验证码。之前他们使用的是 reCAPTCHA,现在则使用他们自家的 Turnstile 验证码。
验证码验证通过后,浏览器会在名为 cf_clearance 的 Cookie 中收到一个唯一的 token。浏览器将使用该 token 从 Cloudflare 的代理服务器请求网站页面。如果该 token 过期,或者 Cloudflare 内部判断该 token 的行为类似于机器人,它将使 token 失效,并再次显示验证码页面。
我们的方法将帮助你通过自动化浏览器会话来获取该 token。请注意,此方法不会泄露网站的真实 IP 地址——该信息仅由 Cloudflare 和网站管理员掌握。这是件好事!
下面是如何使用 NodeJS 和 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)
});
}
我们的代码主要完成以下步骤:
1. 打开浏览器窗口并跳转到 Cloudflare 的验证页面;
2. 用我们自定义的代理函数替换 Turnstile 的 render 函数,在其中拦截初始化参数和验证码完成后的回调函数;
3. 将初始化参数发送到 Anti-Captcha API,由人工工作人员为你解决验证码并返回 token;
4. 使用之前保存的回调函数调用 token 作为参数;
5. Cloudflare 内部验证该 token,在浏览器中设置 Cookie,并重新加载页面;
6. 有了这个 cf_clearance,浏览器就可以通过 Cloudflare 代理访问网站内容。