速卖通作为全球主流跨境电商平台,其开放平台 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(稳定、合规、数据完整),爬虫仅作为临时补充方案;核心需解决多站点 / 多币种适配、签名认证、运费模板解析三大问题,同时严格控制调用频率,确保符合平台规则。若需对接速卖通订单、库存等更深层数据,可进一步申请高级接口权限,并完善数据加密、日志监控体系。


817

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



