真正能稳定过5秒盾的只有Playwright/undetected-chromedriver2或tls_client两类方案:前者通过抹除自动化痕迹应对高防护站点,后者靠修正TLS指纹适配中低防护站点。

直接说结论:requests基本没戏,cloudscraper在2026年已大面积失效,真正能稳定过5秒盾的只有两类方案——用Playwright/undetected-chromedriver2抹除自动化痕迹,或用tls_client修正TLS指纹。选哪个,取决于目标站点防护等级和你的资源约束。
为什么cloudscraper.get()总卡在/cdn-cgi/challenge-platform/
这不是代码写错了,是它根本跑不完Cloudflare的JS挑战。新版挑战包含WebAssembly.instantiate()、performance.now()时间差校验、动态Worker创建,而cloudscraper依赖的Node.js环境不支持这些特性。返回HTML里有"Checking your browser"或状态码为403/503,基本可以判定JS执行中途报错。
常见错误现象:
-
scraper.get()反复重定向到/cdn-cgi/challenge-platform/,拿不到cf_clearancecookie - 即使加了
delay=10或browser={"browser": "chrome"},仍被拦截 - 多线程下Node.js子进程崩溃,日志报
ReferenceError: WebAssembly is not defined
根本原因:cloudscraper不改navigator.webdriver(始终为true),也不伪造canvas、audioContext等指纹,现代Cloudflare直接拒绝。
立即学习“Python免费学习笔记(深入)”;
Playwright启动Chromium后仍被秒识别的修复点
无头模式默认暴露太多自动化特征,CF不是靠UA判断,而是读取navigator.hardwareConcurrency、screen.availWidth、WebGLVendor等JS属性——这些值在Playwright里全是固定假数据。
快速生成专业的 Python 脚本和应用代码。一键创建完整项目结构,支持CLI、API、爬虫、Bot、Django等多种项目类型,包含完整的项目结构、配置文件、依赖管理、测试、README和文档。
必须做的几件事:
- 启动时传入
args=["--disable-blink-features=AutomationControlled", "--no-sandbox"] - 用
page.add_init_script()注入脚本,把navigator.webdriver设为undefined - 显式设置
viewport和user_agent,并启用java_script_enabled=True - 首次
page.goto()前加time.sleep(1.5),避免行为链触发速率限制
示例关键行:
page.add_init_script("Object.defineProperty(navigator, 'webdriver', {get: () => undefined})")
page.goto("https://target.com", wait_until="networkidle")
想快又想省资源?试试tls_client修正TLS指纹
对中低防护站点(比如未开“I'm Under Attack”模式的老站),启动浏览器纯属浪费。90%的拦截发生在TLS握手阶段——Python的urllib3用OpenSSL,Cipher Suites顺序、ALPN列表、SNI扩展都和Chrome不一致,CF一眼识别。
tls_client的优势:
- 内置Chrome/Firefox的JA3指纹,
session = tls_client.Session(client_identifier="chrome_120")一行搞定 - 请求头自动按浏览器顺序排列,不用手动
headers.update() - 支持HTTP/2,帧顺序更贴近真实流量
- 比
curl_cffi对中文站点兼容性更好,小红书/知乎部分页面已实测通过
注意:它不处理cf_clearance有效期,需自己缓存cookie并检查Set-Cookie头是否含cf_clearance=字段。
最后提醒一个容易被忽略的点
无论用哪种方案,cf_clearance cookie有效期实际浮动很大——从30分钟到24小时不等,且同一IP下多个会话会互相干扰。别以为拿到一次就能长期复用,建议每次请求前检查response.cookies.get("cf_clearance"),为空就触发完整流程,否则大概率某次请求突然又跳回"Just a moment"页面。

















