Amazon Product Advertising API:如何将Curl语句转换为Python代码?
以下是导致你从curl转Python代码后出现401错误的核心原因及对应解决方案:
1. 过期的X-Amz-Date导致签名失效
亚马逊PA API采用AWS Signature Version 4签名机制,该签名与请求时间戳强绑定。你代码中直接沿用了curl里的20230301T020028Z,这是一个已过期的时间戳,对应的签名早已失效。
解决方法:
生成当前UTC时间的标准格式时间戳,并基于这个新时间戳重新生成合法的Authorization签名:
from datetime import datetime current_utc_time = datetime.utcnow().strftime("%Y%m%dT%H%M%SZ") headers['X-Amz-Date'] = current_utc_time # 注意:旧的Authorization签名无法复用,必须用新时间戳重新生成
2. 请求体序列化不一致导致签名验证失败
curl中的-d参数是无空格压缩格式的JSON字符串,而Python requests.post的json=参数默认会生成带空格的格式化JSON。两种序列化后的字节内容存在差异,会导致签名哈希值不匹配,触发401错误。
解决方法:
手动将JSON数据序列化为和curl完全一致的无空格格式,使用data=参数传递请求体:
import json # 生成无空格的JSON字符串,匹配curl的格式 json_payload = json.dumps(json_data, separators=(',', ':')) response = requests.post( 'https://webservices.amazon.com/paapi5/searchitems', headers=headers, data=json_payload )
3. Content-Encoding头的潜在冲突
curl中设置了Content-Encoding: amz-1.0,但requests使用json=参数时可能会自动添加或修改编码相关请求头,导致请求头与签名时的预期不一致。
解决方法:
使用data=参数传递手动序列化的JSON字符串时,确保Content-Encoding头与curl完全一致,可通过打印请求头确认:
print(response.request.headers)
关键提示
亚马逊PA API的签名会校验所有请求头、请求体、请求时间戳的一致性,任何细微差异都会导致401错误。不要直接复用curl中的Authorization和过期时间戳,必须针对当前请求重新生成签名。
内容的提问来源于stack exchange,提问作者Katsu
相关产品推荐
相关产品推荐

