API 还是 HTML?速卖通抓取的核心取舍
做速卖通(AliExpress)选品工具或代发货数据平台,你迟早会面对一个关键决策:直接爬桌面版 HTML,还是走移动端 API 拿 JSON?
桌面版 HTML 看似门槛低——打开浏览器 DevTools 就能分析 DOM。但速卖通桌面页大量内容靠 JavaScript 动态渲染,CSS class 名随机生成(如 _1n5kl2m),每次发版都可能变。你维护选择器的成本远超想象。
移动端 API 则返回结构化 JSON,字段稳定、数据更丰富(含内层 SKU 映射、运费模板、卖家评分明细),且请求体积更小、速度更快。如果你的目标是构建产品研究数据管道,API 优先几乎总是正确选择。
本文将从实战角度,带你走完速卖通数据抓取的完整链路:页面结构分析 → 防爬体系拆解 → 移动端 API 端点 → Python 代码实现 → 变体/运费/信誉处理 → 数据新鲜度策略。
速卖通的页面结构与数据分布
速卖通的数据散布在四种主要页面类型中,每种承载不同的选品价值:
搜索结果页
URL 模式:https://www.aliexpress.com/w/wholesale-{keyword}.html
搜索页是选品的起点——告诉你某个细分市场有多少卖家、头部商品的价格区间、销量分布。关键数据点:
- 商品标题与主图:标题堆砌关键词严重,需要 NLP 清洗
- 价格区间:展示最低 SKU 价格,不代表成交价
- 订单数:
xxx sold字段,反映历史销量而非实时 - 评分:聚合评分,不含维度明细
CSS 选择器示例(桌面版,随时可能失效):
/* 商品卡片容器 */
.search-product-card .product-container
/* 标题 */
.search-product-card .product-title a
/* 价格 */
.search-product-card .product-price .price-current
/* 销量 */
.search-product-card .product-sales .sale-value商品详情页
URL 模式:https://www.aliexpress.com/item/{itemId}.html
这是数据密度最高的页面,包含变体 SKU 矩阵、运费估算、卖家信息、评价摘要。但也是反爬最严格的页面——后面详述。
店铺页
URL 模式:https://www.aliexpress.com/store/{storeId}
店铺页可用于评估卖家规模、类目分布和上新频率。关键字段:店铺评分三大维度(物流、沟通、商品如实描述)、粉丝数、近 6 个月销量。
热销榜单与推荐流
速卖通提供多个「Top」页面:
https://www.aliexpress.com/popular/{category}.html— 类目热销榜https://www.aliexpress.com/featured/{topic}.html— 主题推荐- 「New User Zone」和「Super Deals」板块
这些页面是发现趋势品的重要入口,但 HTML 结构更不稳定,强烈建议走 API 路线。
阿里巴巴集团的防爬体系
速卖通背后的防爬不是单一方案,而是一整套多层体系:
| 层级 | 技术 | 触发条件 | 表现 |
|---|---|---|---|
| L1 — 速率限制 | IP 维度 QPS 限制 | 同 IP >2-3 req/s 持续 10s+ | HTTP 429 或 503 |
| L2 — 指纹检测 | JA3/JA4 TLS 指纹 + HTTP/2 指纹 | 非浏览器 TLS 握手特征 | 连接重置或空响应 |
| L3 — JS Challenge | ae-beacon JS 脚本 | 首次访问 / Cookie 缺失 | 521 响应 + JS 渲染 |
| L4 — 行为分析 | 鼠标轨迹 / 滚动模式 / 请求序列 | 非人类浏览模式 | 逐步降权至 CAPTCHA |
| L5 — CAPTCHA | 滑块验证(阿里验证码 2.0) | 累积异常行为阈值 | 弹出滑块,不通过则封 IP |
实战观察:
- 数据中心 IP 几乎必触发 L3(521),住宅 IP 通过率显著更高
- 移动端 API 端点对 TLS 指纹要求稍低,但仍需住宅代理配合
- 单 IP 持续请求超过约 50-80 次/小时后,被标记概率急剧上升
- 带合法 Cookie 和
Referer的请求通过率提高 3-5 倍
这就是为什么住宅代理 + 移动端 API 是当前最稳定的组合——住宅 IP 信誉度高,移动端 API 不触发 JS Challenge。
移动端 API:比桌面 HTML 更丰富的 JSON 数据源
速卖通移动端(m.aliexpress.com)和 App 使用一套独立的 API,返回结构化 JSON,数据量远超桌面 HTML 渲染后的内容。
核心端点模式
以下是经过社区验证的端点模式(具体路径可能随版本更新调整):
# 搜索商品
GET https://m.aliexpress.com/api/search/items.json?keyword={kw}&page=1
# 商品详情(核心端点)
GET https://m.aliexpress.com/api/item/{itemId}.json
# 店铺商品列表
GET https://m.aliexpress.com/api/store/{storeId}/items.json?page=1
# 类目热销
GET https://m.aliexpress.com/api/popular/{categoryId}.json关键请求头:
X-Client-Device: android
X-Client-Version: 8.15.0
X-Client-Id: {随机设备ID}
X-App-Lang: en
User-Agent: AliExpress/8.15.0 (Android; SDK 31)
Accept: application/json搜索 API 返回的 JSON 示例(截断):
{
"data": {
"resultList": [
{
"itemId": "1005006234123456",
"title": "Wireless Earbuds TWS Bluetooth 5.3...",
"price": {"minPrice": "8.99", "maxPrice": "15.99", "currency": "USD"},
"sales": {"orderCount": 2340},
"store": {"storeId": "9123456", "storeName": "TechZone Official"},
"ratings": {"averageStar": "4.7", "starCount": "521"},
"imageUrls": ["https://ae01.alicdn.com/kf/..."]
}
],
"totalResults": 48200
}
}注意几个关键优势:
- 价格是结构化对象,不再是 HTML 里的拼接字符串
- 销量字段直接给出数字,无需正则提取
- 店铺信息内嵌,减少二次请求
- 分页信息完整,
totalResults让你决定抓取深度
实战:用 Python + 住宅代理抓取速卖通爆款数据
以下是一个完整的选品数据采集脚本,使用 ProxyHat 住宅代理轮换 IP,从移动端 API 获取趋势商品:
import requests
import time
import json
import random
from datetime import datetime
PROXY_USER = "your_username"
PROXY_PASS = "your_password"
PROXY_HOST = "gate.proxyhat.com"
PROXY_PORT = 8080
def get_proxy_url(country="US", session_id=None):
"""构建 ProxyHat 住宅代理 URL,支持国家定向和会话保持"""
username = f"{PROXY_USER}-country-{country}"
if session_id:
username += f"-session-{session_id}"
return f"http://{username}:{PROXY_PASS}@{PROXY_HOST}:{PROXY_PORT}"
def fetch_aliexpress_search(keyword, page=1, country="US"):
"""通过移动端 API 搜索速卖通商品"""
session_id = f"ae_{random.randint(100000,999999)}"
proxies = {
"http": get_proxy_url(country, session_id),
"https": get_proxy_url(country, session_id),
}
headers = {
"X-Client-Device": "android",
"X-Client-Version": "8.15.0",
"X-Client-Id": f"device_{random.randint(10**15, 10**16-1)}",
"X-App-Lang": "en",
"User-Agent": "AliExpress/8.15.0 (Android; SDK 31)",
"Accept": "application/json",
"Referer": "https://m.aliexpress.com/",
}
params = {
"keyword": keyword,
"page": page,
"sortType": "BEST_MATCH",
}
url = "https://m.aliexpress.com/api/search/items.json"
try:
resp = requests.get(url, headers=headers, params=params,
proxies=proxies, timeout=15)
resp.raise_for_status()
return resp.json()
except requests.exceptions.HTTPError as e:
if resp.status_code == 429:
print(f"[429] 速率限制触发,等待后重试...")
time.sleep(random.uniform(5, 10))
return fetch_aliexpress_search(keyword, page, country)
raise
def fetch_product_detail(item_id, country="US"):
"""获取商品详情,含 SKU 变体和运费信息"""
session_id = f"ae_detail_{random.randint(100000,999999)}"
proxies = {
"http": get_proxy_url(country, session_id),
"https": get_proxy_url(country, session_id),
}
headers = {
"X-Client-Device": "android",
"X-Client-Version": "8.15.0",
"X-Client-Id": f"device_{random.randint(10**15, 10**16-1)}",
"X-App-Lang": "en",
"User-Agent": "AliExpress/8.15.0 (Android; SDK 31)",
"Accept": "application/json",
}
url = f"https://m.aliexpress.com/api/item/{item_id}.json"
resp = requests.get(url, headers=headers, proxies=proxies, timeout=15)
resp.raise_for_status()
return resp.json()
def discover_trending_products(keywords, max_pages=3):
"""批量发现趋势商品,去重并按销量排序"""
seen_ids = set()
products = []
for kw in keywords:
for page in range(1, max_pages + 1):
data = fetch_aliexpress_search(kw, page)
items = data.get("data", {}).get("resultList", [])
for item in items:
iid = item["itemId"]
if iid in seen_ids:
continue
seen_ids.add(iid)
products.append({
"item_id": iid,
"title": item["title"],
"min_price": float(item["price"]["minPrice"]),
"max_price": float(item["price"]["maxPrice"]),
"orders": item["sales"]["orderCount"],
"rating": float(item["ratings"]["averageStar"]),
"store_id": item["store"]["storeId"],
"store_name": item["store"]["storeName"],
"discovered_at": datetime.utcnow().isoformat(),
})
time.sleep(random.uniform(2, 4)) # 礼貌延迟
products.sort(key=lambda x: x["orders"], reverse=True)
return products
# 运行示例
if __name__ == "__main__":
keywords = ["wireless earbuds", "phone holder car", "led strip lights"]
trending = discover_trending_products(keywords, max_pages=2)
print(json.dumps(trending[:10], indent=2, ensure_ascii=False))脚本要点:
- 每次搜索请求使用不同的 session ID,ProxyHat 会分配新的住宅 IP
- 请求间随机延迟 2-4 秒,避免触发 L1 速率限制
- 遇到 429 自动退避重试,指数级增加等待时间
- 国家定向参数确保看到目标市场的价格和运费
如果你的选品工具需要长期运行,建议参考 代理轮换最佳实践 来设计更稳健的 IP 管理策略。
变体 SKU、运费估算与卖家信誉
速卖通商品的核心复杂性在于变体(variant)和运费——这两者直接影响选品决策的准确性。
变体 SKU 矩阵
一个「无线耳机」商品可能有 20+ 个 SKU(颜色 × 版本组合)。移动端 API 的商品详情返回结构化的 SKU 数据:
{
"skuList": [
{
"skuId": "12000034567890",
"propPath": "14:193#Color:Blue;200000617:133#Version:Pro",
"skuAttr": "Color:Blue;Version:Pro",
"price": {"salePrice": {"cent": "1299", "currency": "USD"}},
"stock": 156,
"imageUrl": "https://ae01.alicdn.com/kf/..."
},
{
"skuId": "12000034567891",
"propPath": "14:193#Color:Black;200000617:133#Version:Pro",
"skuAttr": "Color:Black;Version:Pro",
"price": {"salePrice": {"cent": "1199", "currency": "USD"}},
"stock": 89,
"imageUrl": "https://ae01.alicdn.com/kf/..."
}
]
}选品分析建议:
- 只关注有库存的 SKU:
stock > 0过滤掉断码 - 取最低价 SKU 作为竞品基准,但记录中位数更真实
- 分析 SKU 分布:如果某颜色占 80% 库存,说明是主推款
- 价格单位是「分」:
cent: "1299"= $12.99,别忘除以 100
运费估算(按目的地)
速卖通的运费取决于 发货地 + 目的地 + 商品重量/体积 + 物流渠道。移动端 API 通常在详情中返回运费模板:
def estimate_shipping(item_id, dest_country="US"):
"""获取商品到指定国家的运费估算"""
detail = fetch_product_detail(item_id, country=dest_country)
shipping_options = detail.get("data", {}).get("shipping", [])
results = []
for opt in shipping_options:
results.append({
"carrier": opt.get("company", ""),
"estimated_days": f"{opt.get('minDays', '?')}-{opt.get('maxDays', '?')}",
"freight": float(opt.get("freight", {}).get("cent", "0")) / 100,
"tracking": opt.get("tracking", False),
})
return results注意:运费结果与你请求时指定的国家参数强相关。使用住宅代理时,通过 -country-US 参数让 ProxyHat 分配美国 IP,API 会返回美国目的地的运费。这比在代码里硬编码目的地参数更可靠。
卖家信誉评估
速卖通卖家评分体系包含多个维度,移动端 API 通常返回:
- 沟通评分(Communication):卖家回复速度和质量
- 物流评分(Shipping Speed):实际发货时效
- 商品如实描述(Item as Described):实物与描述匹配度
选品工具应关注的阈值:
- 三大维度评分 < 4.5 → 高风险卖家,建议排除
- 店铺粉丝数 < 100 → 新店,供应链稳定性存疑
- 近 6 个月销量 < 50 → 非主力店铺,断货风险高
实战建议:将卖家信誉作为选品过滤的硬门槛,而不是排序因子。一个 4.9 分卖家的 $12 商品,比 4.2 分卖家的 $8 商品更适合代发货——差评和纠纷的隐性成本远超 $4 差价。
数据新鲜度:价格与库存变动规律
速卖通的数据更新频率取决于数据类型:
| 数据类型 | 变动频率 | 建议抓取节奏 |
|---|---|---|
| 价格 | 随时变动(促销/闪购可能每小时变化) | 每 4-6 小时(核心品)/ 每日(长尾品) |
| 库存 | 每日变动,大促期间更快 | 每 12-24 小时 |
| 销量累计数 | 每日更新 | 每日一次,用于趋势追踪 |
| 评价 | 持续新增 | 每 24-48 小时 |
| 运费 | 相对稳定,大促前可能调整 | 每周一次 / 下单前实时 |
| 卖家信息 | 低频变动 | 每周一次 |
关键洞察:如果你做的是价格监控(比价工具),价格数据的时效性要求最高。速卖通大促期间(328、618、双 11、黑五),价格可能每 2-4 小时变动一次,需要加密抓取频率。
反之,如果你做的是选品发现(找爆款),销量趋势比实时价格更重要。每日抓取一次,配合 7 日滑动平均,就能识别出上升趋势。
推荐抓取架构:
- 发现层:每日全量搜索关键词,发现新上榜商品
- 监控层:对已入选商品,每 4-6 小时刷新价格和库存
- 详情层:每周刷新卖家信息、运费模板
这种分层策略将 API 调用量降低 60-70%,同时保证关键数据的时效性。配合 ProxyHat 的住宅代理轮换(查看代理套餐),单日可稳定处理数万次请求。
桌面 HTML vs 移动端 API vs 官方 API:如何选择?
| 维度 | 桌面 HTML 爬取 | 移动端 API | 官方联盟 API |
|---|---|---|---|
| 数据丰富度 | 中等(需解析渲染后 DOM) | 高(结构化 JSON + SKU 明细) | 中高(部分字段受限) |
| 稳定性 | 低(DOM 频繁变动) | 中(端点偶尔调整) | 高(版本化接口) |
| 反爬难度 | 高(521 + JS Challenge) | 中(需住宅代理 + 正确头) | 无(官方授权) |
| 成本 | 代理费用 | 代理费用 | 联盟佣金分成 |
| 数据延迟 | 实时 | 实时 | 可能有数小时延迟 |
| 合规风险 | 高 | 中 | 低(官方授权) |
务实建议:如果你只是做竞品研究、价格监控、选品发现,移动端 API + 住宅代理是性价比最高的方案。如果你需要将速卖通数据嵌入面向终端用户的产品(如代发货插件),建议同时申请官方联盟 API 作为合规兜底。
关于代理选型,网页抓取用例页面有更详细的住宅 vs 数据中心代理对比。简单来说:速卖通抓取必须用住宅代理,数据中心 IP 在 L3 就会被拦截。
关键要点
- API 优先:移动端 JSON 接口数据更丰富、结构更稳定,远优于解析桌面版 HTML
- 住宅代理必备:速卖通 L2-L5 防爬层会拦截数据中心 IP,ProxyHat 住宅代理(
gate.proxyhat.com:8080)是稳定通行的基础 - 国家定向获取准确运费:用
-country-US参数指定 IP 出口国家,确保看到目标市场的价格和运费 - SKU 级别分析:不要只看商品最低价,解析完整 SKU 矩阵才能做准确选品判断
- 分层抓取节奏:发现层每日、监控层每 4-6 小时、详情层每周,降低 60%+ API 调用量
- 卖家信誉做硬门槛:三大维度 < 4.5 的卖家直接排除,代发货的隐性成本远超表面差价
开始构建你的速卖通选品数据管道——选择 ProxyHat 代理套餐,从住宅代理获取稳定的速卖通数据入口。需要覆盖特定国家市场?查看 全球代理节点分布。






