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

使用Python Requests库请求Udemy返回403响应(Cloudflare拦截),与Chrome请求头一致但结果不同的问题排查

排查 Requests 访问 Udemy 遭遇 Cloudflare 403 拦截的思路

遇到Cloudflare的403拦截太常见了——哪怕你抄了完整请求头,它的反爬检测可不止看这些表面信息。我帮你梳理几个针对性的排查方向,一步步来:

1. 补全请求头里的关键遗漏字段

你已经配置了基础请求头,但还有几个容易被忽略的核心项:

  • Cookie 绝对不能少:Chrome访问时会生成Udemy和Cloudflare的会话Cookie,这是Cloudflare验证你是“真实用户”的关键。打开Chrome开发者工具(F12),在Network面板找到该请求,复制完整的Cookie字符串,加到headers里:
    headers['Cookie'] = '这里粘贴你从Chrome复制的Cookie内容'
    
  • Referer 头要对应:很多网站会检查请求的来源页面,比如如果是从Udemy主页跳转过来的,就加上:'Referer': 'https://www.udemy.com/'
  • 调整 Accept-Encoding:你用的gzip, deflate和Chrome实际支持的有差异,改成gzip, deflate, br(Chrome支持Brotli压缩),同时确保Requests能处理压缩(默认支持,但可以显式设置allow_redirects=True)

2. 模拟浏览器的TLS握手细节(对应你怀疑的证书/协议/密码套件)

Cloudflare对TLS指纹非常敏感,默认的Requests配置和真实浏览器的握手逻辑不一样:

  • 指定TLS版本和密码套件:Chrome 98用的是TLS 1.2或1.3,你可以通过urllib3手动指定匹配的协议和密码套件:
    import requests
    import ssl
    from urllib3.util.ssl_ import create_urllib3_context
    
    # 匹配Chrome 98的TLS 1.3和密码套件
    ctx = create_urllib3_context(
        ssl_version=ssl.PROTOCOL_TLSv1_3,
        ciphers='ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305'
    )
    session = requests.Session()
    # 挂载自定义SSL上下文到HTTPS请求
    session.mount('https://', requests.adapters.HTTPAdapter(ssl_context=ctx))
    req1 = session.get('你的目标URL', headers=headers)
    
  • 同步CA证书:Requests默认的证书库可能和Chrome不一致,你可以用certifi库同步最新证书:
    import certifi
    req1 = requests.get(url, headers=headers, verify=certifi.where())
    

3. 处理Cloudflare的JS验证挑战

如果上面的步骤还是不行,大概率是Cloudflare触发了JavaScript人机验证——Requests不执行JS,自然绕不过:

  • 改用真实浏览器自动化工具,比如playwright或selenium,它们会自动处理JS渲染和验证:
    from playwright.sync_api import sync_playwright
    
    with sync_playwright() as p:
        # 先不开无头模式,看看是否需要手动过验证
        browser = p.chromium.launch(headless=False)
        page = browser.new_page()
        page.set_extra_http_headers(headers)
        page.goto('https://www.udemy.com/join/signup-popup/?displayType=ajax&display_type=popup&returnUrlAfterLogin=https&showSkipButton=1')
        print(page.content())
        browser.close()
    
    注意:无头模式下Cloudflare可能检测到自动化标识,需要额外配置禁用自动化特征(比如添加--disable-blink-features=AutomationControlled参数)。

4. 修正URL的参数格式问题

你提供的URL里有&,这是HTML转义后的&,实际请求时要换成普通的&,否则服务器可能解析参数错误,直接拒绝请求:
正确的URL应该是:

https://www.udemy.com/join/signup-popup/?displayType=ajax&display_type=popup&returnUrlAfterLogin=https&showSkipButton=1

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 13:47:46