一、背景与需求分析
在跨境电商领域,速卖通 (Aliexpress) 作为全球知名的 B2C 平台,拥有海量的商品数据。对于电商数据分析公司、比价网站或供应链管理系统来说,实时获取速卖通商品数据至关重要。本文将详细介绍如何通过 API 接口安全、高效地接入速卖通平台,获取所需的商品信息。
二、速卖通 API 接入基础
速卖通平台提供了丰富的 API 接口,涵盖商品、订单、物流、营销等多个领域。接入前需要完成以下准备工作:
- 注册开发者账号:访问注册并提交审核
- 创建应用:审核获取 ApiKey 和 ApiSecret
- 申请权限:根据需求申请相应的 API 权限,如商品查询、订单管理等
- 了解 API 文档:熟悉 API 的请求格式、参数说明和返回结构
三、API 安全接入实践
安全是 API 接入的重中之重,速卖通 API 采用了多种安全机制:
- OAuth2.0 授权:通过授权码模式获取访问令牌 (AccessToken) 和刷新令牌 (RefreshToken)
- 签名机制:对请求参数进行签名验证,防止参数被篡改
- HTTPS 协议:所有 API 请求必须通过 HTTPS 协议发送
- 限流策略:对 API 调用频率进行限制,防止恶意调用
下面是一个使用 Python 实现的速卖通 API 安全接入示例:
import hashlib
import hmac
import time
import requests
import json
from urllib.parse import urlencode
class AliexpressAPI:
def __init__(self, app_key, app_secret, redirect_uri):
self.app_key = app_key
self.app_secret = app_secret
self.redirect_uri = redirect_uri
self.access_token = None
self.refresh_token = None
self.token_expire_time = 0
def generate_sign(self, params):
"""生成API请求签名"""
# 对参数名进行字典序排序
sorted_params = sorted(params.items(), key=lambda x: x[0])
# 拼接参数名和参数值
string_to_sign = ''.join([k + str(v) for k, v in sorted_params])
# 使用HMAC-SHA1算法生成签名
sign = hmac.new(
self.app_secret.encode('utf-8'),
string_to_sign.encode('utf-8'),
hashlib.sha1
).hexdigest().upper()
return sign
def get_authorization_url(self, state=None):
"""获取授权页面URL"""
auth_params = {
'response_type': 'code',
'client_id': self.app_key,
'redirect_uri': self.redirect_uri,
'state': state or 'aliexpress_auth'
}
return f'https://auth.aliexpress.com/oauth/authorize?{urlencode(auth_params)}'
def get_access_token(self, auth_code):
"""通过授权码获取访问令牌"""
token_url = 'https://gw.api.alibaba.com/openapi/http/1/system.oauth2/getToken'
token_params = {
'grant_type': 'authorization_code',
'need_refresh_token': 'true',
'client_id': self.app_key,
'client_secret': self.app_secret,
'code': auth_code,
'redirect_uri': self.redirect_uri
}
response = requests.post(token_url, data=token_params)
if response.status_code == 200:
token_data = response.json()
self.access_token = token_data.get('access_token')
self.refresh_token = token_data.get('refresh_token')
self.token_expire_time = int(time.time()) + token_data.get('expires_in', 0)
return token_data
else:
raise Exception(f"获取访问令牌失败: {response.text}")
def refresh_access_token(self):
"""刷新访问令牌"""
if not self.refresh_token:
raise Exception("没有刷新令牌可用")
token_url = 'https://gw.api.alibaba.com/openapi/http/1/system.oauth2/getToken'
token_params = {
'grant_type': 'refresh_token',
'need_refresh_token': 'true',
'client_id': self.app_key,
'client_secret': self.app_secret,
'refresh_token': self.refresh_token
}
response = requests.post(token_url, data=token_params)
if response.status_code == 200:
token_data = response.json()
self.access_token = token_data.get('access_token')
self.refresh_token = token_data.get('refresh_token')
self.token_expire_time = int(time.time()) + token_data.get('expires_in', 0)
return token_data
else:
raise Exception(f"刷新访问令牌失败: {response.text}")
def check_token_valid(self):
"""检查令牌是否有效"""
return self.access_token and self.token_expire_time > int(time.time()) + 60
def call_api(self, method, api_params=None):
"""调用速卖通API"""
# 检查令牌有效性
if not self.check_token_valid():
if self.refresh_token:
self.refresh_access_token()
else:
raise Exception("访问令牌无效,请重新获取授权")
# 构建公共参数
public_params = {
'method': method,
'app_key': self.app_key,
'timestamp': int(time.time() * 1000),
'format': 'json',
'v': '2.0',
'sign_method': 'hmac-sha1',
'access_token': self.access_token
}
# 合并参数
all_params = {**public_params, **(api_params or {})}
# 生成签名
sign = self.generate_sign(all_params)
all_params['sign'] = sign
# 发送请求
api_url = 'https://gw.api.alibaba.com/openapi/param2/2/aliexpress.open/' + method
try:
response = requests.post(api_url, data=all_params)
if response.status_code == 200:
return response.json()
else:
raise Exception(f"API调用失败: HTTP {response.status_code}, {response.text}")
except Exception as e:
# 记录异常日志
print(f"API调用异常: {str(e)}")
raise
四、商品数据实时获取实现
基于上面的 API 接入类,我们可以实现商品数据的实时获取功能。速卖通提供了多个商品相关的 API,如商品搜索、商品详情查询、商品列表批量获取等。
下面是一个获取商品列表和商品详情的示例:
def get_product_list(api_client, keywords, page=1, page_size=20):
"""获取商品列表"""
method = 'aliexpress.affiliate.product.query'
params = {
'keywords': keywords,
'page_no': page,
'page_size': page_size,
'sort': 'SALE_PRICE_ASC' # 按价格升序排序
}
result = api_client.call_api(method, params)
return result.get('result', {})
def get_product_detail(api_client, product_ids):
"""获取商品详情"""
method = 'aliexpress.affiliate.productdetail.get'
params = {
'product_ids': ','.join(map(str, product_ids))
}
result = api_client.call_api(method, params)
return result.get('result', {})
def main():
# 初始化API客户端
app_key = 'YOUR_APP_KEY'
app_secret = 'YOUR_APP_SECRET'
redirect_uri = 'https://your-website.com/callback'
api_client = AliexpressAPI(app_key, app_secret, redirect_uri)
# 第一步:获取授权URL,引导用户授权
auth_url = api_client.get_authorization_url()
print(f"请访问以下URL进行授权: {auth_url}")
# 第二步:用户授权后,获取授权码(code),并换取访问令牌
auth_code = input("请输入授权码: ")
token_info = api_client.get_access_token(auth_code)
print(f"成功获取访问令牌: {token_info}")
# 第三步:调用商品API获取数据
try:
# 获取商品列表
product_list = get_product_list(api_client, "iphone case", page=1, page_size=10)
print(f"获取到 {len(product_list.get('products', []))} 个商品")
# 提取商品ID列表
product_ids = [item.get('product_id') for item in product_list.get('products', []) if item.get('product_id')]
if product_ids:
# 获取商品详情
product_details = get_product_detail(api_client, product_ids[:5]) # 取前5个商品ID获取详情
print(f"获取到 {len(product_details.get('product_details', []))} 个商品详情")
# 打印商品信息
for detail in product_details.get('product_details', []):
print(f"商品: {detail.get('product_title')}")
print(f"价格: {detail.get('min_sale_price')} - {detail.get('max_sale_price')} {detail.get('currency')}")
print(f"销量: {detail.get('total_sold')}")
print(f"链接: {detail.get('product_url')}")
print("-" * 50)
except Exception as e:
print(f"获取商品数据失败: {str(e)}")
if __name__ == "__main__":
main()
五、数据处理与存储
获取到商品数据后,通常需要进行处理和存储:
- 数据清洗:去除不需要的字段,处理缺失值,转换数据类型
- 数据存储:可以存储到关系型数据库 (如 MySQL)、非关系型数据库 (如 MongoDB) 或数据仓库
- 数据同步:定时同步数据,保持数据的实时性
下面是一个简单的数据处理和存储示例:
import pymysql
from datetime import datetime
def process_and_store_products(products, db_config):
"""处理商品数据并存储到MySQL数据库"""
# 连接数据库
conn = pymysql.connect(
host=db_config['host'],
user=db_config['user'],
password=db_config['password'],
database=db_config['database'],
charset='utf8mb4'
)
try:
with conn.cursor() as cursor:
# 创建商品表(如果不存在)
create_table_sql = """
CREATE TABLE IF NOT EXISTS aliexpress_products (
product_id BIGINT PRIMARY KEY,
title VARCHAR(512) NOT NULL,
min_price DECIMAL(10, 2) NOT NULL,
max_price DECIMAL(10, 2) NOT NULL,
currency VARCHAR(10) NOT NULL,
total_sold INT NOT NULL,
category_id BIGINT,
seller_id VARCHAR(50),
update_time DATETIME NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
"""
cursor.execute(create_table_sql)
# 处理每条商品数据
for product in products:
product_id = product.get('product_id')
if not product_id:
continue
# 插入或更新商品数据
insert_sql = """
INSERT INTO aliexpress_products
(product_id, title, min_price, max_price, currency, total_sold, category_id, seller_id, update_time)
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s)
ON DUPLICATE KEY UPDATE
title = VALUES(title),
min_price = VALUES(min_price),
max_price = VALUES(max_price),
total_sold = VALUES(total_sold),
update_time = VALUES(update_time)
"""
cursor.execute(insert_sql, (
product_id,
product.get('product_title')[:512], # 截断过长的标题
float(product.get('min_sale_price', 0)),
float(product.get('max_sale_price', 0)),
product.get('currency', 'USD'),
int(product.get('total_sold', 0)),
product.get('category_id'),
product.get('seller_id'),
datetime.now()
))
# 提交事务
conn.commit()
print(f"成功存储 {len(products)} 条商品数据")
except Exception as e:
print(f"存储商品数据失败: {str(e)}")
conn.rollback()
finally:
conn.close()
六、性能优化与最佳实践
为了保证 API 调用的稳定性和效率,需要注意以下几点:
- 合理使用缓存:对于不经常变化的数据,如商品类目信息,可以设置缓存
- 控制请求频率:遵守速卖通 API 的限流规则,避免频繁调用导致 IP 被封
- 异常处理与重试机制:添加完善的异常处理和重试逻辑,确保数据获取的稳定性
- 异步处理:对于大量数据的获取,可以采用异步处理方式提高效率
- 数据增量更新:只更新变化的数据,减少不必要的 API 调用
七、总结
通过速卖通平台的 API,我们可以安全、高效地获取商品数据。本文详细介绍了 API 接入的流程、安全机制、商品数据获取方法以及数据处理与存储方案。在实际应用中,还需要根据具体业务需求进行适当调整和优化,确保系统稳定运行并提供准确的商品数据服务。