如何将指定CURL请求转为Python脚本获取OAuth访问令牌?
解决:Python请求无法获取OAuth令牌的问题
你的问题核心在于请求体的格式不匹配,咱们一步步理清楚:
为什么curl能正常工作?
你运行的curl命令里,-d '{"username": "user","password": "password","scopes": ["download"]}' 是直接把JSON字符串作为请求体发送的,而且curl会自动帮你设置Content-Type: application/json这个关键请求头,服务器能正确识别并处理你的认证请求。
为什么你的Python脚本拿不到令牌?
你用了requests.post(url, data=creds),这里的data参数会把字典转换成表单编码格式(类似username=user&password=password&scopes=download),但你的API期望的是JSON格式的请求体,所以服务器收到的不是它需要的数据,自然不会返回访问令牌。
两种修复方案
方案1:用json参数(推荐,最简洁)
requests库专门提供了json参数,它会自动把字典转换成JSON字符串,同时帮你设置正确的Content-Type请求头:
import requests url = 'https://api.fakedomain.com/v2.0/oauth/token' creds = {"username": "<user>", "password": "<password>", "scopes": ["download"]} # 替换data为json参数 response = requests.post(url, json=creds) print(response.text) # 更方便的是直接解析响应为JSON对象,提取令牌 # auth_result = response.json() # access_token = auth_result.get('access_token') # print(f"获取到的令牌:{access_token}")
方案2:手动构造JSON请求体
如果你想手动控制整个过程,可以用json.dumps()把字典转成JSON字符串,再手动设置请求头:
import requests import json url = 'https://api.fakedomain.com/v2.0/oauth/token' creds = {"username": "<user>", "password": "<password>", "scopes": ["download"]} # 把字典转为JSON字符串 json_payload = json.dumps(creds) # 设置正确的Content-Type请求头 headers = {'Content-Type': 'application/json'} response = requests.post(url, data=json_payload, headers=headers) print(response.text)
额外调试技巧
如果还是有问题,可以打印请求的详细信息来排查:
print("请求头:", response.request.headers) print("实际发送的请求体:", response.request.body) print("响应状态码:", response.status_code)
对比这些信息和curl发送的请求(可以用curl -v查看curl的请求详情),就能快速定位是否还有格式不匹配或者认证信息错误的问题。
内容的提问来源于stack exchange,提问作者GED125




