亚马逊数据采集 API:从接入到实操(SP-API 为主,合规高效)

部署运行你感兴趣的模型镜像

亚马逊作为全球最大的跨境电商平台,其数据采集 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 + 卖家授权 TokenIAM 角色授权 + 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 角色
  1. 注册账号,完成实名认证;
  2. 登录 AWS 控制台,搜索「IAM」服务,进入「角色」→「创建角色」;
  3. 信任实体选择「AWS 服务」→ 关联「Selling Partner API」(或直接搜索「sellingpartnerapi」);
  4. 附加权限策略:根据需求选择(如AmazonSellingPartnerAPIFullAccess全权限,或细分权限如AmazonSellingPartnerAPIProductAccess);
  5. 创建角色后,记录「Role ARN」(格式:arn:aws:iam::账号ID:role/角色名),后续用于开发者账号授权。
(2)注册亚马逊开发者账号并关联卖家账号
  1. 登录,完成账号注册(需验证邮箱、手机号);
  2. 进入「Selling Partner API」→「Develop Apps」→「Create a new app」;
  3. 填写 App 信息(名称、描述、隐私政策 URL),在「AWS IAM Role ARN」中填入步骤 1 的「Role ARN」;
  4. 提交审核后,亚马逊会发送授权邮件,点击邮件中的链接完成卖家账号与开发者账号的关联;
  5. 审核通过后,获取核心凭证:LWA Client IDLWA Client Secret(用于 OAuth 2.0 授权)。
(3)获取访问令牌(Access Token)

SP-API 调用需通过 OAuth 2.0 获取临时访问令牌(有效期 1 小时),步骤:

  1. 构造授权请求 URL(替换占位符):

    plaintext

    https://sellercentral.amazon.com/apps/authorize/consent?client_id=LWA_CLIENT_ID&scope=sellingpartnerapi::migration&response_type=code
    
  2. 用卖家账号登录该 URL,同意授权后,会跳转至你填写的「回调 URL」,并携带code参数(授权码,有效期 5 分钟);
  3. 用授权码兑换 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)需亚马逊人工审核权限,需在开发者平台提交申请。

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 管理,再根据业务场景选择对应的接口。

您可能感兴趣的与本文相关的镜像

Python3.9

Python3.9

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值