亚马逊作为全球最大的跨境电商平台,其数据采集 API 经历了从 MWS API(旧版) 到 SP-API(Selling Partner API,新版) 的迭代。目前 MWS 已逐步停止维护,SP-API 是官方推荐的唯一合规采集方式,支持卖家 / 开发者采集商品、销量、评价、库存等核心数据,适配全球各站点(北美、欧洲、日本等)。
以下是针对亚马逊 SP-API 的完整接入指南、核心接口解析、代码实操及避坑要点,兼顾新手入门与进阶需求:
一、核心前提:SP-API vs MWS API(选择正确的 API 版本)
| 对比维度 | MWS API(旧版) | SP-API(新版) |
|---|---|---|
| 状态 | 2023 年起停止新用户接入,逐步淘汰 | 官方主推,持续更新 |
| 认证方式 | 开发者 ID + 卖家授权 Token | IAM 角色授权 + OAuth 2.0 |
| 安全性 | 较低(明文 Token 传输) | 较高(AWS IAM 加密授权) |
| 接口覆盖 | 基础商品 / 订单 / 库存数据 | 覆盖 MWS 全部功能,新增广告、评价、合规数据 |
| 适配站点 | 部分站点支持 | 全球所有亚马逊站点(北美、欧洲、日本等) |
| 接入难度 | 简单 | 稍复杂(需配置 AWS IAM) |
结论:无论新老用户,优先选择 SP-API,MWS 用户需尽快迁移至 SP-API(亚马逊已关闭 MWS 新接口申请)。
二、接入 SP-API 的前期准备(4 个关键步骤)
1. 必备资质与账号
- 核心账号:
- 亚马逊卖家账号(专业卖家账号最佳,个人卖家部分接口权限受限);
- AWS 账号(亚马逊云服务账号,用于配置 IAM 角色,免费注册即可);
- 亚马逊开发者账号
- 资质要求:
- 企业 / 个体工商户资质(需与卖家账号主体一致);
- 完成开发者账号与卖家账号的关联(验证企业信息、税务信息)。
2. 注册与配置流程(核心步骤)
(1)注册 AWS 账号并创建 IAM 角色
- 注册账号,完成实名认证;

- 登录 AWS 控制台,搜索「IAM」服务,进入「角色」→「创建角色」;
- 信任实体选择「AWS 服务」→ 关联「Selling Partner API」(或直接搜索「sellingpartnerapi」);
- 附加权限策略:根据需求选择(如
AmazonSellingPartnerAPIFullAccess全权限,或细分权限如AmazonSellingPartnerAPIProductAccess); - 创建角色后,记录「Role ARN」(格式:
arn:aws:iam::账号ID:role/角色名),后续用于开发者账号授权。
(2)注册亚马逊开发者账号并关联卖家账号
- 登录,完成账号注册(需验证邮箱、手机号);
- 进入「Selling Partner API」→「Develop Apps」→「Create a new app」;
- 填写 App 信息(名称、描述、隐私政策 URL),在「AWS IAM Role ARN」中填入步骤 1 的「Role ARN」;
- 提交审核后,亚马逊会发送授权邮件,点击邮件中的链接完成卖家账号与开发者账号的关联;
- 审核通过后,获取核心凭证:
LWA Client ID、LWA Client Secret(用于 OAuth 2.0 授权)。
(3)获取访问令牌(Access Token)
SP-API 调用需通过 OAuth 2.0 获取临时访问令牌(有效期 1 小时),步骤:
- 构造授权请求 URL(替换占位符):
plaintext
https://sellercentral.amazon.com/apps/authorize/consent?client_id=LWA_CLIENT_ID&scope=sellingpartnerapi::migration&response_type=code - 用卖家账号登录该 URL,同意授权后,会跳转至你填写的「回调 URL」,并携带
code参数(授权码,有效期 5 分钟); - 用授权码兑换 Access Token 和 Refresh Token(Refresh Token 有效期 1 年,可用于刷新 Access Token):
- 请求地址:
https://api.amazon.com/auth/o2/token - 请求参数(POST 表单):
plaintext
grant_type=authorization_code&code=授权码&client_id=LWA_CLIENT_ID&client_secret=LWA_CLIENT_SECRET - 响应示例(成功后保存
refresh_token):json
{ "access_token": "Atza|...", // 访问令牌(1小时有效) "refresh_token": "Atzr|...", // 刷新令牌(1年有效) "token_type": "bearer", "expires_in": 3600 }
- 请求地址:
3. 工具与依赖准备
- 开发语言:Python(推荐,有成熟 SDK)、Java、Node.js 等;
- Python 依赖(核心库):
boto3:AWS 官方 SDK,用于 SP-API 调用;requests-oauthlib:处理 OAuth 2.0 授权;python-dotenv:管理配置文件(存储凭证,避免硬编码)。
安装依赖:
bash
运行
pip install boto3 requests-oauthlib python-dotenv
三、SP-API 核心接口解析(按业务场景分类)
SP-API 接口按功能分为多个模块,以下是电商数据采集高频接口,涵盖商品、销量、评价、库存等核心场景:
| 业务场景 | 核心接口 | 可采集数据 | 调用条件 |
|---|---|---|---|
| 商品基础信息 | catalog-items-v2022-04-01 | 商品标题、SKU、ASIN、类目、品牌、规格、主图 URL | 无需特殊权限,关联卖家账号即可 |
| 商品价格与库存 | listings-items-v2021-08-01 | 售价、促销价、库存数量、配送时效 | 需卖家账号拥有该商品的销售权限 |
| 销量与订单数据 | orders-v0 | 订单 ID、买家信息、订单金额、发货状态 | 专业卖家账号,需申请orders权限 |
| 用户评价数据 | reviews-v2021-01-01 | 评价内容、评分、追评、晒图、评价时间 | 需申请reviews权限,仅能采集自身商品评价(竞品评价需通过其他合规方式) |
| 竞品监控(ASIN) | product-pricing-v2022-05-01 | 竞品 ASIN 的价格、配送方式、卖家信息 | 需申请product_pricing权限,需提供目标 ASIN |
| 市场趋势数据 | sales-performance-v2022-04-01 | 商品销量趋势、销售额、转化率 | 专业卖家账号,仅能查看自身商品数据 |
关键说明:
- 接口版本:SP-API 接口有版本号(如
v2022-04-01),需使用最新版本(亚马逊会定期淘汰旧版本); - 限流规则:不同接口限流不同(如
catalog-items接口默认每秒 5 次请求),超限流会返回429 Too Many Requests; - 区域端点:不同亚马逊站点对应不同接口端点(避免跨区域调用失败),核心端点如下:
| 站点区域 | 接口端点 |
|---|---|
| 北美(美国、加拿大、墨西哥) | https://sellingpartnerapi-na.amazon.com |
| 欧洲(英、德、法、意、西) | https://sellingpartnerapi-eu.amazon.com |
| 日本 | https://sellingpartnerapi-jp.amazon.com |
| 澳大利亚 | https://sellingpartnerapi-au.amazon.com |
四、Python 实操:SP-API 调用示例(核心场景)
以下以 采集商品基础信息(Catalog Items API) 和 采集自身商品评价(Reviews API) 为例,展示完整代码(含 Token 刷新、接口调用、数据解析)。
1. 配置文件(.env):存储核心凭证
创建.env文件,避免硬编码凭证:
env
# LWA凭证
LWA_CLIENT_ID=你的LWA_CLIENT_ID
LWA_CLIENT_SECRET=你的LWA_CLIENT_SECRET
REFRESH_TOKEN=你的REFRESH_TOKEN
# SP-API端点(北美站点为例)
SP_API_ENDPOINT=https://sellingpartnerapi-na.amazon.com
# AWS IAM凭证(可选,boto3会自动读取~/.aws/credentials)
AWS_ACCESS_KEY_ID=你的AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY=你的AWS_SECRET_ACCESS_KEY
2. 封装 SP-API 基础调用类(处理 Token 刷新 + 请求签名)
python
运行
import os
import time
import requests
from dotenv import load_dotenv
from oauthlib.oauth2 import BackendApplicationClient
from requests_oauthlib import OAuth2Session
# 加载环境变量
load_dotenv()
class AmazonSPAPIClient:
def __init__(self):
self.lwa_client_id = os.getenv("LWA_CLIENT_ID")
self.lwa_client_secret = os.getenv("LWA_CLIENT_SECRET")
self.refresh_token = os.getenv("REFRESH_TOKEN")
self.sp_api_endpoint = os.getenv("SP_API_ENDPOINT")
self.access_token = None
self.token_expire_time = 0 # 记录Token过期时间
def _refresh_access_token(self):
"""刷新Access Token(过期前自动刷新)"""
current_time = time.time()
# 若Token未获取或剩余有效期<300秒,刷新Token
if not self.access_token or (self.token_expire_time - current_time) < 300:
url = "https://api.amazon.com/auth/o2/token"
data = {
"grant_type": "refresh_token",
"refresh_token": self.refresh_token,
"client_id": self.lwa_client_id,
"client_secret": self.lwa_client_secret
}
response = requests.post(url, data=data, timeout=10)
if response.status_code == 200:
token_data = response.json()
self.access_token = token_data["access_token"]
self.token_expire_time = current_time + token_data["expires_in"]
print("Token刷新成功,有效期至:", time.ctime(self.token_expire_time))
else:
raise Exception(f"Token刷新失败:{response.status_code} - {response.text}")
return self.access_token
def call_api(self, method, path, params=None, data=None):
"""通用API调用方法(处理Token、签名、请求)"""
access_token = self._refresh_access_token()
headers = {
"Authorization": f"Bearer {access_token}",
"Content-Type": "application/json",
"x-amz-access-token": access_token # 部分接口需额外携带该Header
}
url = f"{self.sp_api_endpoint}{path}"
try:
if method.upper() == "GET":
response = requests.get(url, headers=headers, params=params, timeout=15)
elif method.upper() == "POST":
response = requests.post(url, headers=headers, json=data, timeout=15)
else:
raise ValueError("仅支持GET/POST请求")
# 处理响应(限流时重试)
if response.status_code == 429:
retry_after = int(response.headers.get("Retry-After", 5))
print(f"触发限流,{retry_after}秒后重试...")
time.sleep(retry_after)
return self.call_api(method, path, params, data)
response.raise_for_status() # 抛出HTTP错误(4xx/5xx)
return response.json()
except Exception as e:
raise Exception(f"API调用失败:{str(e)}")
3. 场景 1:采集商品基础信息(通过 ASIN 查询)
使用catalog-items-v2022-04-01接口,根据 ASIN 查询商品标题、品牌、类目等信息:
python
运行
def get_product_details(client, asin_list):
"""
采集商品基础信息
:param client: SP-API客户端实例
:param asin_list: ASIN列表(如["B07VGFG35C", "B08X7Z3X7Q"])
:return: 商品详情列表
"""
path = "/catalog/2022-04-01/items"
params = {
"asin": ",".join(asin_list),
"marketplaceIds": "ATVPDKIKX0DER", # 北美市场ID(美国),其他市场ID见下文
"includedData": "attributes,identifiers,images" # 需返回的数据类型
}
response = client.call_api("GET", path, params=params)
product_details = []
# 解析响应数据
for item in response.get("items", []):
asin = item["asin"]
attributes = item.get("attributes", {})
images = item.get("images", {}).get("primary", [])
product_details.append({
"asin": asin,
"title": attributes.get("title", [{"value": "未知"}])[0]["value"],
"brand": attributes.get("brand", [{"value": "未知"}])[0]["value"],
"category": attributes.get("productType", [{"value": "未知"}])[0]["value"],
"main_image_url": images[0]["url"] if images else "无",
"price": attributes.get("listPrice", [{"value": 0}])[0]["value"] # 标价
})
return product_details
# 调用示例
if __name__ == "__main__":
client = AmazonSPAPIClient()
# 目标ASIN列表(美国站点商品)
asin_list = ["B07VGFG35C", "B08X7Z3X7Q"]
product_data = get_product_details(client, asin_list)
for product in product_data:
print(f"ASIN:{product['asin']}")
print(f"标题:{product['title']}")
print(f"品牌:{product['brand']}")
print(f"主图URL:{product['main_image_url']}")
print("-" * 50)
4. 场景 2:采集自身商品评价(通过 ASIN 查询)
使用reviews-v2021-01-01接口,采集自身店铺商品的用户评价(仅支持自身商品,竞品评价需合规申请):
python
运行
def get_product_reviews(client, asin, page_size=10):
"""
采集自身商品评价
:param client: SP-API客户端实例
:param asin: 商品ASIN
:param page_size: 每页评价数(最大100)
:return: 评价列表
"""
path = "/reviews/2021-01-01/reviews"
params = {
"asin": asin,
"marketplaceIds": "ATVPDKIKX0DER",
"pageSize": page_size,
"sortOrder": "NEWEST" # 排序:NEWEST(最新)、HELPFUL(最有帮助)
}
response = client.call_api("GET", path, params=params)
reviews = []
# 解析评价数据
for review in response.get("reviews", []):
reviews.append({
"review_id": review["reviewId"],
"asin": review["asin"],
"rating": review["rating"], # 评分(1-5)
"review_text": review.get("reviewText", ""),
"reviewer_name": review.get("reviewerName", "匿名用户"),
"review_date": review["reviewDate"],
"verified_purchase": review.get("verifiedPurchase", False) # 是否为真实购买
})
return reviews
# 调用示例
if __name__ == "__main__":
client = AmazonSPAPIClient()
asin = "B07VGFG35C"
reviews = get_product_reviews(client, asin, page_size=20)
print(f"ASIN {asin} 的评价(共{len(reviews)}条):")
for idx, review in enumerate(reviews, 1):
print(f"\n{idx}. 评分:{review['rating']}星 | 日期:{review['review_date']}")
print(f"用户:{review['reviewer_name']} | 真实购买:{review['verified_purchase']}")
print(f"评价内容:{review['review_text']}")
5. 场景 3:采集竞品价格(通过 ASIN 查询)
使用product-pricing-v2022-05-01接口,查询竞品 ASIN 的当前售价、配送方式等信息:
python
运行
def get_competitor_price(client, asin_list):
"""
采集竞品价格信息
:param client: SP-API客户端实例
:param asin_list: 竞品ASIN列表
:return: 价格列表
"""
path = "/products/pricing/v2022-05-01/offer-prices"
params = {
"asin": ",".join(asin_list),
"marketplaceIds": "ATVPDKIKX0DER",
"itemCondition": "New" # 商品状态:New(新品)、Used(二手)
}
response = client.call_api("GET", path, params=params)
price_data = []
for item in response.get("offerPrices", []):
asin = item["asin"]
# 提取最低售价(新品)
lowest_price = item.get("lowestPrices", [{}])[0]
price_data.append({
"asin": asin,
"currency": lowest_price.get("currency", "USD"),
"amount": lowest_price.get("amount", 0),
"shipping": lowest_price.get("shipping", {}).get("amount", 0),
"total_price": lowest_price.get("amount", 0) + lowest_price.get("shipping", {}).get("amount", 0),
"offer_count": item.get("offerCount", 0) # 在售卖家数量
})
return price_data
# 调用示例
if __name__ == "__main__":
client = AmazonSPAPIClient()
competitor_asins = ["B08X7Z3X7Q", "B07VGFG35C"]
price_data = get_competitor_price(client, competitor_asins)
for price in price_data:
print(f"ASIN:{price['asin']}")
print(f"最低售价:{price['currency']} {price['amount']}")
print(f"运费:{price['currency']} {price['shipping']}")
print(f"总价:{price['currency']} {price['total_price']}")
print(f"在售卖家数:{price['offer_count']}")
print("-" * 50)
五、关键避坑指南(亚马逊 SP-API 常见问题)
1. 权限相关问题
- 接口调用返回
403 Forbidden:- 检查 IAM 角色权限是否完整(如采集价格需
product_pricing权限); - 确认卖家账号与开发者账号已完成关联(未关联会导致权限不足);
- 部分接口(如
orders)需亚马逊人工审核权限,需在开发者平台提交申请。
- 检查 IAM 角色权限是否完整(如采集价格需
2. 限流与重试机制
- SP-API 严格限流(如
catalog-items接口每秒 5 次),超限流会返回429:- 代码中必须加入重试机制(参考示例中的
call_api方法),根据Retry-After头信息延时重试; - 控制请求频率(如每秒 1-2 次),避免高频调用;
- 批量查询时,使用接口支持的批量参数(如
asin参数支持多 ASIN 逗号分隔),减少请求次数。
- 代码中必须加入重试机制(参考示例中的
3. 区域与市场 ID 匹配
- 不同站点对应不同
marketplaceIds,错误会导致400 Bad Request:站点 marketplaceIds 美国 ATVPDKIKX0DER 加拿大 A2EUQ1WTGCTBG2 英国 A1F83G8C2ARO7P 德国 A1PA6795UKMFR9 日本 A1VC38T7YXB528
4. Token 管理
- Access Token 有效期 1 小时,需定时刷新(示例中已实现自动刷新);
- Refresh Token 有效期 1 年,需妥善保存(丢失后需重新授权);
- 避免频繁刷新 Token(如每次调用都刷新),仅在过期前刷新。
5. 合规性要求
- 禁止采集用户敏感信息(如买家手机号、地址),评价内容需匿名化处理;
- 数据仅可用于自身运营或市场分析,不可用于恶意竞争(如恶意低价、虚假宣传);
- 遵守亚马逊《开发者协议》,禁止滥用 API(如批量爬取大量无关 ASIN 数据)。
六、进阶优化:提升采集效率与稳定性
1. 批量采集优化
- 利用接口的批量参数(如
asin支持多 ASIN 批量查询),减少请求次数; - 分页数据处理:接口返回
nextToken时,循环调用获取全部数据(如评价分页)。
2. 异常处理增强
- 捕获常见错误(如网络超时、接口返回格式异常),加入日志记录(使用
logging模块); - 对敏感操作(如订单数据采集)加入数据备份机制,避免数据丢失。
3. 数据存储与分析
- 采集数据存储到数据库(如 MySQL、PostgreSQL),方便后续查询与分析;
- 结合之前提到的数据分析方法(价格趋势、评价情感分析),挖掘业务价值。
总结
亚马逊 SP-API 是合规采集亚马逊电商数据的唯一官方渠道,核心优势是数据精准、稳定、合规,适合长期监控商品、销量、评价等数据。接入的关键是完成 AWS IAM 配置、开发者账号授权、Token 管理,再根据业务场景选择对应的接口。



被折叠的 条评论
为什么被折叠?



