浏览器访问API返回200但requests.get请求返回403错误是什么原因
Cloudflare识别两类请求的核心逻辑
- TLS指纹(JA3/JA4)校验:不同客户端发起HTTPS握手时,携带的加密套件列表、扩展顺序、椭圆曲线参数等特征存在差异,原生requests的TLS指纹和真实浏览器指纹完全不同,Cloudflare可通过指纹直接识别非浏览器请求,这是触发1020错误的最常见原因。
- HTTP协议层特征差异:如果目标站点启用HTTP/2,原生requests默认仅支持HTTP/1.1,即使Header完全匹配,HTTP/2的帧发送顺序、流ID规则、帧优先级设置等协议层特征也存在明显差异,会被Cloudflare的指纹系统识别。
- 出口环境差异:如果浏览器访问时使用了代理、VPN等网络环境,Python代码未同步配置相同网络出口,不同的IP地址也会触发Cloudflare的拦截规则。
遗漏的配置项修复方案
- 首先修正请求URL的格式错误,你当前代码中请求地址未携带
https://协议头,会导致requests地址解析异常,Host校验不通过:
# 修正前 r = requests.get("api.site.com/data?key=my_key", headers=headers) # 修正后 r = requests.get("https://api.site.com/data?key=my_key", headers=headers)
- 替换HTTP请求库,解决TLS指纹与HTTP/2适配问题:
优先使用curl_cffi库,可直接模拟浏览器的完整TLS指纹和HTTP特征,示例代码如下:
from curl_cffi import requests headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:92.0) Gecko/20100101 Firefox/92.0", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", "Accept-Language": "en-US,en;q=0.5", "Accept-Encoding": "gzip, deflate, br", "Connection": "keep-alive", "DNT": "1", "Host": "api.site.com", "Upgrade-Insecure-Requests": "1", "Sec-Fetch-Dest": "document", "Sec-Fetch-Mode": "navigate", "Sec-Fetch-Site": "none", "Sec-Fetch-User": "?1" } # impersonate参数指定模拟的浏览器版本,和你Header中的Firefox版本对应 r = requests.get("https://api.site.com/data?key=my_key", headers=headers, impersonate="firefox92") print(r.status_code)
- 同步网络出口环境:确保Python代码的代理配置和浏览器使用的代理完全一致,避免IP差异触发拦截。
内容的提问来源于stack exchange,提问作者asdasd31
相关产品推荐
相关产品推荐

