Python调用含JSON格式Token请求头的API失败问题解决
解决Python调用API时请求头Token及请求体格式问题
你遇到的问题主要出在两个核心点:请求体的发送格式错误和请求头/URL未与curl请求完全对齐,咱们一步步来修复:
1. 修复请求体的发送方式
你在curl里用-d传递的是JSON格式的请求体,但Python代码里用了data=sems_post_data——这会把字典以application/x-www-form-urlencoded(表单)格式发送,而API明确期望的是application/json格式的请求体。
在requests库中,正确的做法是使用json=sems_post_data参数:它会自动把Python字典序列化为JSON字符串,还会自动帮你设置Content-Type: application/json(当然你手动设置这个头也没问题)。
2. 对齐请求头与URL的细节
- Accept头:你之前设置成了
text/json,但curl里是application/json,建议保持和curl完全一致,避免API返回格式不兼容。 - Token头格式:你尝试的第二种写法
'token': '{"uid": "email@domain.com","timestamp": 0,"token": "","client": "web","version": "","language": "en-GB"}'其实是完全正确的——Python中单引号包裹的字符串里,双引号不需要额外转义,这个格式和curl里的token头完全匹配。之前失败大概率是因为请求体的问题,而非token格式。 - URL一致性:curl里的地址是
http://globalapi.sems.com.cn:82/api/v1/Common/CrossLogin,但你的Python代码里写的是https://globalapi.sems.com.cn/...(缺少端口82),这会直接导致请求无法到达正确的服务端,必须和curl的URL完全一致。
修正后的完整代码
import requests sems_headers = { 'Content-Type': 'application/json', 'Accept': 'application/json', # 直接复用curl中完全一致的JSON字符串作为token值 'token': '{"uid": "email@domain.com","timestamp": 0,"token": "","client": "web","version": "","language": "zh-CN"}' } sems_post_data = { 'account': 'email@domain.com', 'pwd': 'mypassword', 'is_local': True, 'agreement_agreement': 0 } # 确保URL和curl完全一致,包含端口82 response = requests.post( "http://globalapi.sems.com.cn:82/api/v1/Common/CrossLogin", headers=sems_headers, json=sems_post_data # 用json参数发送JSON格式请求体 ) print("响应状态码:", response.status_code) print("响应内容:", response.text)
额外验证小技巧
如果还是不确定请求是否和curl一致,可以用工具打印出完整的请求详情对比:
import requests from requests_toolbelt.utils import dump # 发送请求后执行以下代码 request_details = dump.dump_all(response) print(request_details.decode('utf-8'))
这样就能看到实际发送的请求头、请求体内容,和curl的请求逐一对比即可排查差异。
内容的提问来源于stack exchange,提问作者herrbert
相关产品推荐
相关产品推荐

