为何该API请求在Insomnia/Postman可用但Python Requests返回400?
问题排查与解决方案
核心问题原因
a1Data头格式错误
cURL命令中的"是Shell环境下对双引号的转义手段,实际发送给服务器的头值是标准JSON格式(使用正常双引号")。但你的Python代码直接将"写入字符串,导致服务器收到的a1Data头包含"而非正常双引号,无法解析该JSON结构,直接返回400错误。次要潜在问题:参数类型一致性
虽然cURL和Python代码中都将布尔型参数(如detailed、fc)以字符串"true"/"false"传递,但部分API会严格校验参数类型。不过这不是本次400错误的主因,修复a1Data后若仍有问题可进一步排查。
解决方案
步骤1:修正a1Data头
将a1Data头中的"替换为正常双引号,同时确保Python字符串语法正确:
import requests url = "https://api.reserveamerica.com/jaxrs-json/products/AK/1180246" querystring = { "prdId": "2400", "detailed": "true", "gal": "14", "fc": "true", "gad": "2023-06-27", "next": "false", "displayGISMap": "true", } headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/114.0", "Accept": "application/json", "Accept-Language": "en-US,en;q=0.5", "Accept-Encoding": "gzip, deflate, br", # 修正a1Data:替换所有"为正常双引号,用单引号包裹字符串避免语法冲突 "a1Data": '{"sessionID":"4D441B5AE76AE0D435FBE1F3A32380FE.ue1-prod-aspiraone-web-10","sessionType":"SELFSERVICE","maxInactive":1800000,"AWSALB":"3MbtREdsquTV2MIZtkGpTIuB8kVWmwiOf+Q9GK0mWy6OsjQ8VBr6sSGzhiE2Xa/iPoTilVAH0sML5EK6NMLgipGThJ+z6rQKpGj5e2HI2Y2/6xjyrHr+ViXh58I4","AWSALBCORS":"3MbtREdsquTV2MIZtkGpTIuB8kVWmwiOf+Q9GK0mWy6OsjQ8VBr6sSGzhiE2Xa/iPoTilVAH0sML5EK6NMLgipGThJ+z6rQKpGj5e2HI2Y2/6xjyrHr+ViXh58I4"}', "Authorization": "eyJraWQiOiJiOUZPc0pUblF1NTRBdVEzWlR1NE55Ylkzakp3cVg5WFJZZ3NvQlBDOThBPSIsImFsZyI6IlJTMjU2In0.eyJzdWIiOiJjNDVlZjJkMy0yZjc4LTRhZTUtODcxNS1iODM1Yjk0OTVmNTMiLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwiYWRkcmVzcyI6eyJmb3JtYXR0ZWQiOiJBRERSRVNTIDExMTEifSwiaXNzIjoiaHR0cHM6XC9cL2NvZ25pdG8taWRwLnVzLWVhc3QtMS5hbWF6b25hd3MuY29tXC91cy1lYXN0LTFfbHVzbDZPSmFkIiwicGhvbmVfbnVtYmVyX3ZlcmlmaWVkIjp0cnVlLCJjb2duaXRvOnVzZXJuYW1lIjoiYzQ1ZWYyZDMtMmY3OC00YWU1LTg3MTUtYjgzNWI5NDk1ZjUzIiwib3JpZ2luX2p0aSI6ImRhNWU0NGI4LWE5YjUtNDQyNi1iNTIxLWRhODNiZWRhM2EzMyIsImF1ZCI6IjM3NGY1aGxiaGJwNnJhczZmNW5haTRwNDIwIiwiZXZlbnRfaWQiOiIwZWYyYWI2Ni02MGM2LTQ3N2MtYTQyNS03Zjg0ZTNiM2JmZjkiLCJ0b2tlbl91c2UiOiJpZCIsImF1dGhfdGltZSI6MTY4NjY5NjMzNiwibmFtZSI6Ikd1ZXN0VXNlciIsInBob25lX251bWJlciI6IisxNTU1NTU1NTU1NSIsImV4cCI6MTY4NjY5OTkzNiwiaWF0IjoxNjg2Njk2MzM2LCJqdGkiOiI5MGVhNTU4YS05YWQ2LTQxMWMtYWFmMS1mYzE4YzZlZjE0OTIiLCJlbWFpbCI6InByb2RndWVzdHVzZXJAYXNwaXJhY29ubmVjdC5jb20ifQ.b1d--A6EMth6jz5f0yMJjRW6IlIzZSUdUWT-AIk1ElduvuTi7AxGQu7pJbxC8MMZrX75k0xg8tXcKhyc85BwrME1lBoZ-hCejPGKbqgku3aiHLyMU0X5A0-IaLLblW1FnvQktEQT_ukbs-vASUSnNIALCZZUG25SIpeWxe3XcZrX7n1I60jIGN8ZSAre4l-5lOz5fmFyuT7Ac4fREByBNczng6Whr5Z6PqeMzRbqXuFAeNhHEuwfBWSwcOEZF63F0pkwnf2NzhXkukMq5pbMfDJ57uqoWGehTVpkLqoCitOLDM97B5UtWttBCxEIuvU_hH6Hcqm-stEYnondSJO5jQ", } response = requests.request("GET", url, headers=headers, params=querystring) # 打印响应状态码和内容 print(response.status_code) print(response.json())
步骤2:调试请求差异(可选)
如果修复后仍有问题,可开启Requests的调试日志,对比实际发送的请求与cURL的差异:
import logging import http.client # 开启调试日志 http.client.HTTPConnection.debuglevel = 1 logging.basicConfig() logging.getLogger().setLevel(logging.DEBUG) requests_log = logging.getLogger("requests.packages.urllib3") requests_log.setLevel(logging.DEBUG) requests_log.propagate = True # 执行请求代码...
额外注意事项
- 确保
Authorization令牌未过期,令牌通常有有效期,若修复后仍返回401/403需重新获取。 - 部分API会校验请求的
Referer或Origin头,若调试中发现缺失可从cURL/Postman中复制添加。
内容的提问来源于stack exchange,提问作者Mike B
相关产品推荐
相关产品推荐

