前言 跨境电商运营、ERP 系统对接、竞品深度分析场景下,亚马逊商品详情是核心数据源。目前网络上多数教程仍沿用淘汰的 PAAPI 接口,存在鉴权逻辑老旧、多站点适配差、变体 SKU 解析残缺、参数冗余、无异常熔断等问题,无法适配当下主流 SP-API 规范。本文基于亚马逊最新售卖伙伴接口 一、差异化技术亮点 全量适配 SP-API:摒弃老旧 PAAPI,采用亚马逊现行标准接口,适配全球各区域站点。 令牌自动管理:内置 LWA 令牌有效期检测,临近过期自动刷新,避免服务中断。 变体 SKU 完整解析:深度拆解多规格商品的尺寸、颜色、价格、库存等变体数据,弥补通用教程短板。 按需字段裁剪:通过 异常分级处理:区分令牌失效、签名错误、站点不存在等异常,搭配风控休眠规避限流。 二、接口基础规范 接口地址: 认证方式:LWA 授权令牌 + AWS SigV4 签名 请求方式:GET,UTC 标准时间格式 调用限制:单账号 QPS≤5,批量采集请求间隔≥0.5s 权限要求:亚马逊 SP-API 目录商品读取权限 三、完整 Python 代码 python 四、实战踩坑总结 区分新旧接口:PAAPI 已逐步关停,新项目必须使用 SP-API,二者鉴权、签名规则完全不同。 SigV4 签名必填 Host 头部,缺失会直接导致签名校验失败,是高频踩坑点。 令牌提前刷新:预留 60 秒缓冲时间,杜绝批量采集过程中令牌突然失效。 includedData 按需配置:只请求业务所需字段,避免返回海量冗余数据拖慢接口。 站点区域严格对应:欧洲站统一使用catalog/2022-04-01/items/{asin} 开发,实现SigV4 标准签名、LWA 令牌自动续期、多站点一键切换、变体规格拆解、图文与卖点结构化提取。includedData按需请求数据,缩减报文体积,提升响应速度。https://sellingpartnerapi-{region}.amazon.com/catalog/2022-04-01/items/{asin}
运行import requests
import time
import json
from datetime import datetime, timedelta
from botocore.auth import SigV4Auth
from botocore.awsrequest import AWSRequest
class AmazonItemDetail:
def __init__(self, client_id, client_secret, refresh_token, ak, sk):
self.client_id = client_id
self.client_secret = client_secret
self.refresh_token = refresh_token
self.ak = ak
self.sk = sk
self.token = None
self.token_expire = None
# 主流站点映射
self.site_map = {"us":"na","uk":"eu","de":"eu","jp":"jp"}
self._refresh_token()
def _refresh_token(self):
"""LWA令牌自动刷新"""
url = "https://api.amazon.com/auth/o2/token"
data = {
"grant_type":"refresh_token","refresh_token":self.refresh_token,
"client_id":self.client_id,"client_secret":self.client_secret
}
res = requests.post(url, data=data, timeout=10).json()
self.token = res.get("access_token")
self.token_expire = datetime.utcnow() + timedelta(seconds=res["expires_in"]-60)
def _sigv4_sign(self, url, headers):
"""标准SigV4签名"""
region = url.split("-")[-1].split(".")[0]
req = AWSRequest(method="GET", url=url, headers=headers)
SigV4Auth({"access_key":self.ak,"secret_key":self.sk},
"sellingpartnerapi", region).add_auth(req)
return dict(req.headers)
def get_detail(self, asin, site="us"):
"""获取商品详情、变体、图文、卖点"""
if datetime.utcnow() >= self.token_expire:
self._refresh_token()
if site not in self.site_map:
return {"code":-1,"msg":"暂不支持该站点"}
region = self.site_map[site]
url = f"https://sellingpartnerapi-{region}.amazon.com/catalog/2022-04-01/items/{asin}"
params = {"includedData":"summaries,images,variations,offers"}
headers = {"x-amz-access-token":self.token,"Host":url.split("/")[2]}
headers = self._sigv4_sign(url, headers)
try:
resp = requests.get(url, headers=headers, params=params, timeout=15)
raw = resp.json()
if resp.status_code != 200:
return {"code":-2,"msg":raw.get("message","接口请求失败")}
item = raw.get("items",[{}])[0]
summary = item.get("summaries",[{}])[0]
offer = item.get("offers",[{}])[0].get("price",{})
variations = item.get("variations",[])
img_list = [img.get("link") for img in item.get("images",[{}])[0].get("images",[])]
# 结构化数据输出
ret = {
"asin":asin,"title":summary.get("title"),"brand":summary.get("brand",{}).get("name"),
"price":offer.get("amount"),"currency":offer.get("currencyCode"),
"main_images":img_list,"variations":variations
}
time.sleep(0.5)
return {"code":200,"data":ret}
except Exception as e:
return {"code":-3,"msg":f"程序异常:{str(e)}"}
if __name__ == "__main__":
api = AmazonItemDetail(
client_id="你的ClientID",client_secret="你的ClientSecret",
refresh_token="你的RefreshToken",ak="你的AWS AK",sk="你的AWS SK"
)
result = api.get_detail(asin="B0XXXXXXXXX", site="us")
print(json.dumps(result, ensure_ascii=False, indent=2))eu域名,错误区域会出现 404 路由异常。