You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何绕过Cloudflare的503错误(需启用JavaScript)

解决Cloudflare 503拦截:绕过JS检测并模拟浏览器请求

问题背景

Cloudflare返回503并提示"请启用JavaScript并重载页面",拦截requests、curl等程序请求,但同一主机的Chrome(含无痕模式)可正常访问。已尝试cloudscraper、复制请求头、mechanize、requests_html执行JS等方法均无效,且Chrome存在三次302跳转流程:无Cookie请求触发带cookieSet=1的跳转并设Cookie → 带Cookie访问跳转URL后跳回原URL → 最终带Cookie访问原URL返回200,但curl无-L时直接返回503。

核心识别机制分析

Cloudflare能区分浏览器与程序请求,核心原因可能是以下几点:

  • TLS指纹差异:浏览器与requests/curl的TLS握手参数(如Cipher Suites、扩展字段顺序)不同,Cloudflare会通过该指纹识别非浏览器请求
  • 请求行为细节:程序处理跳转的速度、请求头顺序、动态生成的浏览器特有请求头(如sec-fetch-*)与真实浏览器不一致
  • JS环境特征:模拟JS执行的库(如requests_html)缺少真实浏览器的环境属性(如navigator对象的细节、Canvas指纹)

可行解决方案

1. 使用真实浏览器驱动(最可靠)

直接调用真实Chrome浏览器,完全模拟其TLS握手、跳转逻辑、JS执行环境,Cloudflare无法区分。推荐用Playwright或Selenium,示例代码(Playwright):

from playwright.sync_api import sync_playwright

# 启动无头Chrome(headless=True可改为False查看窗口)
with sync_playwright() as p:
    browser = p.chromium.launch(headless=True)
    page = browser.new_page()
    # 模拟Chrome无痕模式的请求行为
    page.goto("目标URL")
    # 等待页面加载完成(可根据目标页面调整等待条件)
    page.wait_for_load_state("networkidle")
    # 获取页面内容
    content = page.content()
    print(content)
    browser.close()

2. 匹配浏览器TLS指纹

使用支持自定义TLS指纹的请求库,模拟Chrome的TLS握手参数,绕过指纹检测。示例用tls-client库:

import tls_client

# 初始化会话,指定Chrome版本的TLS指纹
session = tls_client.Session(
    client_identifier="chrome118",  # 可根据目标Chrome版本调整
    random_tls_extension_order=True  # 模拟浏览器随机的TLS扩展顺序
)

# 发送请求,自动处理跳转和Cookie
response = session.get("目标URL")
print(response.status_code)
print(response.text)

3. 手动复现完整跳转流程(适合轻量场景)

严格模拟Chrome的三次302跳转逻辑,注意每一步的请求头顺序、Cookie携带、微小延迟:

import requests
import time

headers = {
    # 完全复制Chrome无痕模式的请求头,包括sec-fetch-*、Accept等字段的顺序
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36",
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
    "Accept-Language": "zh-CN,zh;q=0.9",
    "Accept-Encoding": "gzip, deflate, br",
    "Sec-Fetch-Dest": "document",
    "Sec-Fetch-Mode": "navigate",
    "Sec-Fetch-Site": "none",
    "Sec-Fetch-User": "?1",
    "Upgrade-Insecure-Requests": "1",
    "Connection": "keep-alive"
}

session = requests.Session()
session.headers.update(headers)

# 第一步:无Cookie请求原URL,获取跳转地址和Cookie
first_resp = session.get("目标URL", allow_redirects=False)
if first_resp.status_code == 302:
    redirect_url = first_resp.headers["Location"]
    # 等待100ms,模拟浏览器跳转延迟
    time.sleep(0.1)
    
    # 第二步:携带Cookie访问跳转URL
    second_resp = session.get(redirect_url, allow_redirects=False)
    if second_resp.status_code == 302:
        final_url = second_resp.headers["Location"]
        time.sleep(0.1)
        
        # 第三步:访问最终URL
        final_resp = session.get(final_url)
        print(final_resp.status_code)
        print(final_resp.text)

为什么之前的方法失效?

  • cloudscraper:版本迭代慢,模拟的TLS指纹和JS环境已被Cloudflare识别
  • 复制请求头:可能遗漏了动态生成的请求头,或未严格遵循浏览器的请求头顺序(Cloudflare会检查字段顺序)
  • requests_html:JS执行环境为简化版,缺少真实浏览器的环境特征(如Canvas指纹、特定API支持)

内容的提问来源于stack exchange,提问作者Cosmo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 09:45:25