如何检测 Cloudflare Turnstile 参数:sitekey、cData、action
Advanced Bot Mitigation Engineer
TL;DR:
- Cloudflare Turnstile 的配置由少量参数组成,这些参数可以从页面中读取。
sitekey总是存在;action、cData和回调由网站在使用时设置。 - 隐式模式的小部件将参数作为
data-*属性携带。 直接从.cf-turnstile元素读取data-sitekey、data-action、data-cdata和data-callback。 - 显式模式的小部件将参数传递给
turnstile.render()。 在页面运行该调用之前挂钩,此时可以捕获完整的选项对象——sitekey、action、cData和chlPageData。 - 在实际运行中,小部件暴露了
sitekey0x4AAAAAAAW9zqSPAlyOSMfO和一个回调。 渲染钩子保持为空,因为该页面使用隐式模式——参数在 DOM 中而不是在钩子中。 - 请在真实浏览器中执行此操作。 参数仅在小部件脚本运行后存在,因此从已渲染的页面读取它们,而不是原始 HTML。
- 免费开始。 新的 Scrapeless 账户包括免费的 Scraping Browser 运行时——请在 app.scrapeless.com 注册。
引言:配置 Turnstile 小部件的参数
Cloudflare Turnstile 是网站嵌入的用以验证访问者是人类的小部件——是复选框 CAPTCHA 的继任者。当它加载时,由一小组参数进行配置:一个公共 站点密钥 用于识别小部件,一个可选的 操作 标签用于命名受保护的事件,一个可选的 客户数据 负载网站附加,以及一个 回调,该回调在小部件通过后接收令牌。了解如何从页面读取这些参数是理解、测试或自动化任何 Turnstile 保护流程的第一步。
网站可以通过两种方式连接 Turnstile,每种方式以不同的方式公开参数。本指南涵盖两者——在隐式模式中从 DOM 读取它们,以及在显式模式中从 turnstile.render() 调用中捕获它们——并针对真实的 Turnstile 小部件进行实时运行。
参数及其含义
| 参数 | 属性 / 选项 | 含义 |
|---|---|---|
| 站点密钥 | data-sitekey / sitekey |
识别小部件的公共密钥;始终存在(格式 0x…)。 |
| 操作 | data-action / action |
可选标签,用于命名受保护的事件(例如 login)。 |
| cData | data-cdata / cData |
网站附加到挑战的可选客户数据字符串。 |
| 回调 | data-callback / callback |
在小部件通过时接收令牌的函数。 |
| chlPageData | chlPageData |
在某些托管流程的显式渲染中传递的页面数据。 |
站点密钥是公开的——它的设计目的是放在页面中。action 和 cData 值仅在网站选择设置时存在。
为什么选择 Scrapeless Scraping Browser
Scrapeless Scraping Browser 是一个可定制的、反检测的云浏览器,旨在为网络爬虫和 AI 代理服务。对于专门读取小部件参数,它提供了:
- 真正的云端渲染——小部件脚本实际运行,因此参数存在于可读取状态。
- 标准 Puppeteer 连接——
puppeteer.connect()返回普通的Browser;你可以正常检查页面。 evaluateOnNewDocument支持—— 在页面自身脚本运行之前注入一个钩子,这正是显式模式捕获所需的。- 覆盖195多个国家的住宅代理—— 访问仅向其真实小部件提供的页面。
在免费计划中获取你的 API 密钥,网址为 app.scrapeless.com。
前提条件
- Node.js 18 或更新版本
- 一个 Scrapeless 账户和 API 密钥——请在 app.scrapeless.com 注册
- 对 Puppeteer 和 DOM 有基本的了解
安装
bash
npm install puppeteer-core
bash
export SCRAPELESS_API_KEY="your_api_token_here"
隐式模式:从 DOM 中读取参数
常见的情况是隐式小部件:一个 <div class="cf-turnstile" data-sitekey="…"> 元素,Turnstile 自动渲染。参数是元素的 data-* 自定义属性,因此在小部件挂载后读取它们:
javascript
import puppeteer from 'puppeteer-core';
const params = new URLSearchParams({
token: process.env.SCRAPELESS_API_KEY,
sessionTTL: '180',
proxyCountry: 'US',
});
const browser = await puppeteer.connect({
browserWSEndpoint: `wss://browser.scrapeless.com/api/v2/browser?${params}`,
});
const page = await browser.newPage();
await page.goto('https://www.scrapingcourse.com/login/cf-turnstile', {
waitUntil: 'domcontentloaded',
timeout: 60000,
});
await new Promise((r) => setTimeout(r, 6000)); // 让小部件脚本挂载
const widget = await page.evaluate(() => {
const el = document.querySelector('.cf-turnstile, [data-sitekey]');
如果 (!el) 返回 null;
const attrs = {};
for (const a of el.attributes) attrs[a.name] = a.value;
return attrs;
});
console.log(widget);
// {
// id: "waf",
// class: "cf-turnstile",
// "data-sitekey": "0x4AAAAAAAW9zqSPAlyOSMfO",
// "data-callback": "javascriptCallback"
// }
await browser.close();
在实际运行中返回了小部件的 data-sitekey (0x4AAAAAAAW9zqSPAlyOSMfO) 和它的 data-callback。此特定页面没有设置 data-action 或 data-cdata — 这些键根本不存在,这是正常的:只有当网站配置它们时,它们才会出现,并且你可以在出现时以相同的方式读取它们。
在免费计划上获取您的 API 密钥:app.scrapeless.com
显式模式:捕获来自 turnstile.render() 的参数
当一个网站显式地渲染 Turnstile 时,它在 JavaScript 中调用 turnstile.render(container, options),参数存在于那个 options 对象中 — 而不在 DOM 中。要读取它们,请在页面自己的脚本运行之前,使用 evaluateOnNewDocument 和通过 Object.defineProperty 的 属性设置器 来钩住 turnstile.render:
javascript
await page.evaluateOnNewDocument(() => {
window.__tsParams = [];
Object.defineProperty(window, 'turnstile', {
configurable: true,
get() { return this.__ts; },
set(v) {
this.__ts = v;
if (v && v.render && !v.__wrapped) {
const orig = v.render.bind(v);
v.render = (el, opts) => { window.__tsParams.push(opts || {}); return orig(el, opts); };
v.__wrapped = true;
}
},
});
});
await page.goto('https://example.com/turnstile-page', { waitUntil: 'domcontentloaded' });
await new Promise((r) => setTimeout(r, 7000));
const captured = await page.evaluate(() => window.__tsParams);
console.log(captured);
// 显式渲染 → [{ sitekey: "0x…", action: "login", cData: "…", callback: [Function] }]
这个钩子在网站分配 window.turnstile 的瞬间包装 render,因此每个显式渲染都以其完整选项被捕获 — sitekey、action、cData 和 chlPageData(如果存在的话)。在 隐式模式 页面中,这个数组保持为空,因为网站从未自己调用 render() — 这是一个可靠的信号表明应该从 DOM 属性中读取参数。运行两者,使用填充了数据的那个。
注意事项
- 网站密钥是公开的;将
action和cData视为可选项。 应该检查它们的缺失,而不是假设每个小部件都会设置它们。 - 从已渲染页面读取,而不是原始 HTML。 在显式模式下,参数从未出现在提供的标记中 — 它们只有在小部件脚本运行后才存在,这就是为什么需要真正的浏览器。
- 优先选择持久选择器。
.cf-turnstile和[data-sitekey]是稳定的锚点;周围的标记不是。 - 令牌是一个单独的步骤。 读取参数与传递小部件不同 —
cf-turnstile-response令牌由小部件验证后的回调生成,并根据 Cloudflare 的 Turnstile 服务器端验证文档 在服务器端进行验证。
结论:小部件的配置,从页面读取
Turnstile 的参数并不隐藏 — 网站密钥是公开的,action 和 cData 值可以在网站设置它们的地方读取。从隐式模式中的 data-* 属性中读取,或者钩住 turnstile.render() 来捕获显式模式中的选项对象,并同时运行这两者,以便覆盖页面使用的那个。关于操作云浏览器的机制,Scraping Browser 文档覆盖了完整流程,而反机器人方面则在 清除 Cloudflare 挑战 的指南中拆解;文档 涵盖了其余内容。
准备好构建您的 AI 驱动的数据管道吗?
加入我们的社区以索取免费计划,并与正在开发反机器人流程的开发人员连接:Discord · Telegram。
在 app.scrapeless.com 注册以获取免费的 Scraping Browser 运行时,并查看 定价 了解规模。
常见问题
问:Turnstile 小部件有哪些参数?
一个公共 sitekey(始终存在,格式为 0x…),一个可选的 action 标签,一个可选的 cData 字符串,以及一个接收令牌的 callback。显式呈现还可以传递 chlPageData。
问:我在哪里可以找到网站密钥?
在隐式模式下的小部件元素中作为 data-sitekey,或在显式模式下传递给 turnstile.render() 的选项中。在实时运行中,它读取为 0x4AAAAAAAW9zqSPAlyOSMfO。
问:为什么缺少 data-action 或 data-cdata?
因为网站没有设置这两个参数——它们都是可选的。当网站使用它们时,它们会以 data-action / data-cdata(隐式)或 action / cData(显式)的形式出现,读取方式相同。
问:为什么我需要真实浏览器而不是获取 HTML?
在显式模式下,参数通过 JavaScript 传递,永远不会出现在提供的标记中;它们仅在小部件脚本运行后才存在。云浏览器呈现页面,因此这些值是可用的。
问:读取参数是否通过了挑战?
不。参数配置小部件;cf-turnstile-response 令牌是通过小部件验证后由回调单独生成的,并在服务器端进行检查。
在Scrapeless,我们仅访问公开可用的数据,并严格遵循适用的法律、法规和网站隐私政策。本博客中的内容仅供演示之用,不涉及任何非法或侵权活动。我们对使用本博客或第三方链接中的信息不做任何保证,并免除所有责任。在进行任何抓取活动之前,请咨询您的法律顾问,并审查目标网站的服务条款或获取必要的许可。



