使用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渲染和验证:
注意:无头模式下Cloudflare可能检测到自动化标识,需要额外配置禁用自动化特征(比如添加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()--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
相关产品推荐
相关产品推荐

