速卖通作为全球主流跨境电商平台,其开放平台 API 是合规采集商品价格、库存、促销等核心数据的首选方式;针对无接口权限场景,也可通过合规爬虫补充采集。以下从API 接口接入(核心)、爬虫采集(补充)、数据处理三个维度完整说明。
一、速卖通开放平台 API 核心特性(补充至跨境电商平台体系)
| 维度 | 核心特性 |
|---|---|
| 认证方式 | 基于 App Key + App Secret 的 HMAC-SHA256 签名认证(部分接口支持 OAuth2.0) |
| 核心接口 | 1. 商品详情:aliexpress.product.redefining.getproductdetail2. 价格 / 促销:aliexpress.offer.redefining.getpricelist3. 运费模板:aliexpress.logistics.redefining.getfreighttemplate4. SKU 信息:aliexpress.product.redefining.getskuinfolist |
| 调用限制 | 单 App 每日调用限额(普通开发者约 10 万次 / 天),单接口 QPS≤5,IP 无白名单但高频调用易限流 |
| 数据特点 | 支持多站点(如美国、俄罗斯、西班牙站)、多币种(USD/EUR/RUB 等)、多语言,价格含折扣 / 运费拆分 |
| 合规要求 | 需完成企业开发者认证,遵守《速卖通开放平台服务协议》,禁止商用数据倒卖 |
二、速卖通 API 接口接入(Python 实战)
2.1 前置准备
- 账号与权限申请
- 登录速卖通开放平台,完成企业主体认证(需提供营业执照、跨境电商资质);
- 创建应用,申请上述核心接口的调用权限(审核周期约 1-3 个工作日);
- 记录关键信息:
App Key、App Secret、应用授权码(若需 OAuth2.0)。
- 依赖库安装
bash
运行
pip install requests pycryptodome python-dotenv # 签名/请求/环境变量管理
2.2 Python 封装速卖通 API 客户端(核心代码)
速卖通 API 签名需严格遵循 HMAC-SHA256 算法,且参数需按 ASCII 升序排序,以下是可直接复用的客户端:
python
运行
import requests import time import hmac import hashlib import json from urllib.parse import urlencode, quote from dotenv import load_dotenv import os # 加载环境变量(避免硬编码AppKey/Secret) load_dotenv() APP_KEY = os.getenv("ALI_APP_KEY") APP_SECRET = os.getenv("ALI_APP_SECRET") API_GATEWAY = "https://openapi.aliexpress.com/api" class AliExpressAPIClient: def __init__(self, app_key, app_secret): self.app_key = app_key self.app_secret = app_secret self.session = requests.Session() self.session.headers.update({ "Content-Type": "application/x-www-form-urlencoded; charset=utf-8", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AliExpressAPI/1.0" }) def generate_sign(self, params): """生成速卖通API签名(HMAC-SHA256)""" # 1. 参数按ASCII升序排序 sorted_params = sorted(params.items(), key=lambda x: x[0]) # 2. 拼接为"key=value"格式(value需URL编码) sign_str = "&".join([f"{k}={quote(str(v), safe='')}" for k, v in sorted_params]) # 3. HMAC-SHA256加密 + Base64编码 sign = hmac.new( self.app_secret.encode("utf-8"), sign_str.encode("utf-8"), hashlib.sha256 ).digest() return sign.hex().upper() # 转为十六进制大写 def request(self, api_path, params, method="POST", retry=3, delay=2): """发送API请求(含重试机制)""" try: # 补充公共参数 public_params = { "app_key": self.app_key, "timestamp": int(time.time() * 1000), # 毫秒级时间戳 "format": "json", "v": "2.0", "sign_method": "hmac-sha256" } # 合并公共参数与业务参数 all_params = {**public_params, **params} # 生成签名 all_params["sign"] = self.generate_sign(all_params) # 发送请求 if method == "GET": url = f"{API_GATEWAY}{api_path}?{urlencode(all_params)}" response = self.session.get(url, timeout=15) else: url = f"{API_GATEWAY}{api_path}" response = self.session.post(url, data=all_params, timeout=15) response.raise_for_status() result = response.json() # 处理接口错误 if result.get("error_code"): raise Exception(f"API错误:{result['error_code']} - {result['error_message']}") return result except Exception as e: if retry > 0: time.sleep(delay) # 指数退避重试 return self.request(api_path, params, method, retry-1, delay*2) raise Exception(f"调用失败:{str(e)}") def get_product_detail(self, product_id, country="US", currency="USD"): """获取商品详情(含基础价格、名称、SKU)""" api_path = "/aliexpress/product/redefining/getproductdetail" params = { "product_id": product_id, # 速卖通商品ID(从商品页URL提取) "country": country, # 站点国家编码(US/ES/RU等) "currency": currency # 目标币种 } return self.request(api_path, params) def get_product_price(self, product_id, sku_id=""): """获取商品实时价格(含促销价、折扣)""" api_path = "/aliexpress/offer/redefining/getpricelist" params = { "product_id": product_id, "sku_id": sku_id # 空则返回默认SKU价格 } return self.request(api_path, params) def get_freight_template(self, template_id, country="US"): """解析运费模板(计算商品+运费总成本)""" api_path = "/aliexpress/logistics/redefining/getfreighttemplate" params = { "template_id": template_id, "country": country } return self.request(api_path, params) # 调用示例 if __name__ == "__main__": client = AliExpressAPIClient(APP_KEY, APP_SECRET) # 示例:查询商品详情(替换为实际商品ID) product_id = "10050058089xxxx" try: # 1. 获取商品基础信息 detail = client.get_product_detail(product_id, country="US", currency="USD") # 2. 获取价格信息 price = client.get_product_price(product_id) # 3. 获取运费模板(从商品详情中提取template_id) template_id = detail["data"]["freight_template_id"] freight = client.get_freight_template(template_id, country="US") # 解析核心数据(映射为标准字段) result = { "platform_code": "ALIEXPRESS", "product_id": product_id, "product_name": detail["data"]["product_title"], "original_price": price["data"]["original_price"], "current_price": price["data"]["sale_price"], "currency": "USD", "shipping_fee": freight["data"]["default_freight"], "total_price": float(price["data"]["sale_price"]) + float(freight["data"]["default_freight"]) } print(json.dumps(result, ensure_ascii=False, indent=2)) except Exception as e: print(f"采集失败:{e}")2.3 接口调用关键注意事项
- 多站点 / 多币种适配:
- 不同国家站点的价格、运费差异极大(如俄罗斯站定价用 RUB,运费含本地物流费),需通过
country参数指定目标站点; - 币种转换:可对接第三方汇率接口(如 Open Exchange Rates),将 USD/EUR 等统一转换为 CNY,示例:
python
运行
def convert_currency(amount, from_curr, to_curr="CNY"): # 对接汇率接口获取实时汇率(示例为固定汇率,需替换为真实接口) exchange_rates = {"USD": 7.2, "EUR": 7.8, "RUB": 0.07} return amount * exchange_rates[from_curr]
- 不同国家站点的价格、运费差异极大(如俄罗斯站定价用 RUB,运费含本地物流费),需通过
- 签名排错:
- 若返回 “签名无效”,检查:参数排序是否升序、value 是否 URL 编码、时间戳是否为毫秒级、AppSecret 是否正确;
- 频率控制:
- 新增 Redis 限流逻辑(参考京东 API 的限流代码),控制单接口 QPS≤5,避免触发平台限流(返回 429 错误)。
三、无接口权限时的合规爬虫采集(补充方案)
若暂未获取 API 权限,可通过爬虫采集速卖通商品页数据(需严格遵守 robots 协议,仅用于非商用监控):
3.1 核心爬虫代码(应对动态渲染)
python
运行
import requests from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.support import expected_conditions as EC import time from fake_useragent import UserAgent class AliExpressSpider: def __init__(self): self.ua = UserAgent() # 配置ChromeOptions(反爬) self.options = webdriver.ChromeOptions() self.options.add_argument(f"user-agent={self.ua.random}") self.options.add_argument("--headless") # 无头模式 self.options.add_experimental_option("excludeSwitches", ["enable-automation"]) self.driver = webdriver.Chrome(options=self.options) self.driver.implicitly_wait(10) def get_product_data(self, product_url): """采集商品页数据(示例:价格、名称、运费)""" try: self.driver.get(product_url) # 等待价格元素加载(应对JS动态渲染) price_elem = WebDriverWait(self.driver, 15).until( EC.presence_of_element_located((By.CLASS_NAME, "product-price-value")) ) # 提取数据 product_name = self.driver.find_element(By.CLASS_NAME, "product-title-text").text.strip() current_price = price_elem.text.strip().replace("$", "") shipping_fee = self.driver.find_element(By.CLASS_NAME, "product-shipping-price").text.strip() return { "product_name": product_name, "current_price": current_price, "shipping_fee": shipping_fee, "url": product_url } except Exception as e: raise Exception(f"爬虫采集失败:{e}") finally: self.driver.quit() # 调用示例 if __name__ == "__main__": spider = AliExpressSpider() product_url = "https://www.aliexpress.com/item/10050058089xxxx.html" print(spider.get_product_data(product_url))3.2 爬虫反爬应对策略
- IP 代理轮换:使用跨境代理池(如 911S5、BrightData),避免单 IP 被封(速卖通对境外 IP 更宽松,境内 IP 易受限);
- 请求延迟:每次请求间隔 10-15 秒,避免高频;
- 绕过检测:禁用 Chrome 自动化标识(
enable-automation),配合随机 User-Agent、Cookie 池。
四、数据采集合规与风险控制
- 合规底线:
- 仅采集公开商品数据,禁止爬取用户隐私、订单信息;
- 数据仅用于自身价格监控,禁止倒卖、商用;
- 风险应对:
- API 权限被限:预留备用开发者账号,及时调整调用频率;
- 爬虫被封:优先切换至 API 方案,或降低采集频率;
- 数据延迟:速卖通 API 数据延迟约 5-10 分钟,爬虫数据为实时但稳定性低,建议两者结合校验。
五、总结
速卖通数据采集优先选择开放平台 API(稳定、合规、数据完整),爬虫仅作为临时补充方案;核心需解决多站点 / 多币种适配、签名认证、运费模板解析三大问题,同时严格控制调用频率,确保符合平台规则。若需对接速卖通订单、库存等更深层数据,可进一步申请高级接口权限,并完善数据加密、日志监控体系。