Curl命令请求成功,但Python Requests调用返回403 Forbidden求助
解决Requests返回403但Curl正常的问题
这种情况我踩过无数坑了!核心原因几乎都是网站的反爬机制把你的Python请求识别成了机器人——毕竟curl和requests的默认请求头差异很大,网站一眼就能看出来“这不是人类在访问”。下面给你几个逐步排查的方案:
1. 完全复刻Curl的请求头
这是最有效的第一步。先运行带-v参数的curl命令,看看它发送的所有请求头:
curl -v 你的目标URL
把输出里> 开头的请求头全部复制下来,放到requests的headers字典里。比如:
import requests headers = { 'User-Agent': 'curl/7.81.0', # 或者直接用浏览器的User-Agent,伪装效果更好 'Accept': '*/*', 'Host': '目标网站域名', # 把curl里的其他请求头也逐一加进来 } response = requests.get('你的目标URL', headers=headers)
重点注意User-Agent、Accept、Host这几个字段,很多网站会靠它们识别请求来源。
2. 带上Curl里的Cookie
如果你的curl命令里用了-b参数或者本身带了Cookie请求头,那说明网站需要会话验证。把这些Cookie复制到requests里:
- 方法一:直接加到headers中
headers['Cookie'] = '这里放curl里的完整Cookie内容' - 方法二:用
cookies参数单独传入cookies = {'cookie_key1': 'cookie_value1', 'cookie_key2': 'cookie_value2'} response = requests.get('目标URL', cookies=cookies)
3. 模拟Curl的其他细节行为
有些容易被忽略的小细节也会触发403:
- Curl默认会跟随重定向,requests默认也是,但如果网站有特殊重定向逻辑,可以手动显式设置
allow_redirects=True。 - 如果curl用了
--compressed参数,记得在headers里加Accept-Encoding: gzip, deflate, br,让requests支持压缩请求。 - 部分网站会检查
Referer字段,要求请求来自本站页面,加上Referer: 来源页面的URL会更稳妥。
4. 使用Session对象保持会话
如果需要多次请求或者网站依赖会话Cookie,用requests.Session()能模拟浏览器的会话状态,自动处理Cookie和请求头的复用,减少被识别的概率:
import requests session = requests.Session() # 一次性设置好所有通用请求头 session.headers.update({ '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,*/*;q=0.8' }) # 发起请求,会话会自动维护Cookie response = session.get('目标URL')
5. 排查是否需要CSRF Token
如果是POST请求返回403,大概率是缺少CSRF Token。你需要先GET一次目标页面,从页面HTML里提取出CSRF Token(通常在<input name="csrf_token" value="xxx">这类标签里),然后在POST请求时将Token放到参数或请求头里。
先从第一步开始试,90%的情况复刻请求头就能解决问题!如果还是不行,再逐步排查Cookie、会话这些细节。
内容的提问来源于stack exchange,提问作者nirgn
相关产品推荐
相关产品推荐

