🚀 别再爬淘宝了!官方TOP API合法获取数据,基础接口有免费额度(附代码)
结论先行:淘宝/天猫商品查询(taobao.item.get)、店铺在售列表(taobao.items.onsale.get)、订单同步(taobao.trades.sold.get)、物流轨迹 均有免费调用额度,只要企业实名应用 + AppKey 调官方网关,合法、稳定、不封IP、不触发风控。爬虫该退休了。
一、为什么放弃爬虫选官方TOP API?
维度 | Selenium/Requests 爬虫 | 淘宝开放平台 TOP API |
|---|---|---|
合法性 | ⚠️ 违反ToS,有法律风险 | ✅ 签约开放平台,合规 |
稳定性 | 页面改版即挂,滑块验证棘手 | 接口版本化管理 |
数据质量 | HTML解析易缺字段 | 结构化JSON,含SKU/价格/库存 |
限流 | IP被封 | 明确免费QPS+日额度(企业可提) |
维护成本 | 高(UA/代理/JS逆向) | 几乎零(签名+调接口) |
二、前置准备(10分钟)
- 登录 淘宝开放平台→ 创建「自用型应用」
- 企业支付宝认证(订单/店铺接口必须;商品公开查询个人可试但额度低)
- 应用详情页获取
App Key+App Secret - 申请接口权限:
taobao.item.get(商品详情)taobao.items.onsale.get(店铺商品列表)taobao.trades.sold.get(订单列表)taobao.trade.fullinfo.get(订单明细)taobao.logistics.trace.get(物流轨迹)- 如需订单/店铺私有数据 → 卖家账号OAuth2授权换取 AccessToken(session参数)
三、Python完整源码 —— TOP API合法获取数据
# top_legal_api.py
"""
淘宝/天猫 TOP API 合法获取数据 Client
支持: 商品详情 / 店铺商品列表 / 订单列表(需session)
签名规则: 参数按key ASCII升序 → 拼 AppSecret+KV+AppSecret → MD5 → 大写
"""
import hashlib
import time
import requests
from typing import Dict, List, Optional
from datetime import datetime, timedelta
# 封装好API供应商demo url=https://console.open.onebound.cn/console/?i=Lex
class TopLegalClient:
"""淘宝TOP API Client(生产用)"""
GATEWAY = "https://gw.api.taobao.com/router/rest"
SANDBOX = "https://gw.api.tbsandbox.com/router/rest"
def __init__(self, app_key: str, app_secret: str, sandbox=False):
self.ak = app_key
self.as_ = app_secret
self.gw = self.SANDBOX if sandbox else self.GATEWAY
# ───────────── 标准TOP MD5签名 ─────────────
def _sign(self, params: Dict) -> str:
filt = sorted((k, v) for k, v in params.items()
if v is not None and str(v).strip() != '' and k != 'sign')
qs = ''.join(f"{k}{v}" for k, v in filt)
return hashlib.md5(f"{self.as_}{qs}{self.as_}".encode()
).hexdigest().upper()
def _call(self, method: str, biz: Dict, session: str = None) -> Dict:
p = {
"method": method,
"app_key": self.ak,
"timestamp": str(int(time.time() * 1000)), # 毫秒!
"format": "json",
"v": "2.0",
"sign_method": "md5"
}
if session:
p["session"] = session
p.update(biz)
p["sign"] = self._sign(p)
r = requests.post(self.gw, data=p, timeout=15)
r.raise_for_status()
d = r.json()
if "error_response" in d:
err = d["error_response"]
raise Exception(
f"TOP [{err.get('code')}]: {err.get('msg')} "
f"sub:{err.get('sub_msg','')}"
)
return d.get(list(d.keys() - {"error_response"})[0], {})
# ──── ① 商品详情(个人/企业均可,公开字段不需session)───
def get_item(self, num_iid: str,
fields: str = None, session: str = None) -> Dict:
fields = fields or (
"num_iid,title,price,org_price,pic_url,item_imgs,"
"skus,props_name,approve_status,num,outer_id,seller_nick,cid"
)
resp = self._call(
"taobao.item.get",
biz={"num_iid": num_iid, "fields": fields},
session=session
)
return resp.get("item", resp)
# ──── ② 店铺在售商品列表(需企业+卖家授权session)───
def list_onsale(self, page_no=1, page_size=100,
session: str = None) -> Dict:
return self._call(
"taobao.items.onsale.get",
biz={
"page_no": page_no,
"page_size": min(page_size, 100),
"fields": "num_iid,title,price,num,outer_id,approve_status"
},
session=session
)
# ──── ③ 增量同步卖家订单(需session)───
def list_sold_orders(self, minutes_back=30, page_no=1,
session: str = None) -> Dict:
now = datetime.now()
start = (now - timedelta(minutes=minutes_back)
).strftime("%Y-%m-%d %H:%M:%S")
end = now.strftime("%Y-%m-%d %H:%M:%S")
return self._call(
"taobao.trades.sold.get",
biz={
"fields": (
"tid,status,payment,modified,buyer_nick,"
"receiver_name,receiver_mobile,orders.num_iid,"
"orders.title,orders.num,orders.price,orders.outer_sku_id"
),
"start_modified": start,
"end_modified": end,
"page_no": page_no,
"page_size": 40
},
session=session
)
# 封装好API供应商demo url=https://console.open.onebound.cn/console/?i=Lex
# =========================================================
# 使用示例
# =========================================================
if __name__ == "__main__":
client = TopLegalClient(
app_key="YOUR_APP_KEY",
app_secret="YOUR_APP_SECRET",
sandbox=False
)
try:
# ★ 商品详情 —— 不需session,个人号也能跑
item = client.get_item("654321098765") # ← 替换真实num_iid
print("✅ 商品标题:", item.get("title"))
print(" 一口价: ¥", item.get("price"))
print(" 主图:", item.get("pic_url"))
skus = item.get("skus") or []
print(f" SKU数:{len(skus)}")
for s in skus[:2]:
print(f" {s.get('properties_name','默认')} "
f"¥{s.get('price')} 库:{s.get('quantity')}")
# ★ 店铺商品 / 订单 —— 需传卖家AccessToken
# goods = client.list_onsale(session="SELLER_ACCESS_TOKEN")
# orders = client.list_sold_orders(session="SELLER_ACCESS_TOKEN")
except Exception as e:
print("❌", e)
print("→ 确认: AppKey/Secret正确、接口权限已申请、num_iid有效")四、免费额度说明(2026版)
接口 | 是否免费 | 典型免费QPS | 日调用上限(企业) |
|---|---|---|---|
taobao.item.get | ✅ 免费 | ≈5/s | 50万~100万 |
taobao.items.onsale.get | ✅ 免费 | ≈5/s | 同上 |
taobao.trades.sold.get | ✅ 免费(基础) | ≈5~10/s | 同上(超量按基础计费¥极低) |
taobao.logistics.trace.get | ✅ 免费 | ≈5/s | — |
增值数据分析API | 💰 增值包 | — | 需购包 |
中小企业做商品同步+订单回写 零API调用费,QPS如不够可买资源包提频。
五、高频避坑
坑 | 现象 | 解决 |
|---|---|---|
skus返回空 | 查别人店铺商品公开数据不含库存 | 自己店铺查须传 seller AccessToken |
403 no permission调订单 | 个人应用或未授权 | 切企业应用 + 卖家OAuth授权 |
Invalid Signature | 时间戳用秒 | 必须 int(time.time()*1000) |
偶发 code=7 | QPS超限 | 令牌桶限速 QPS≤4(免费上限5),退避重试 |
desc为空 | 部分类目详情在独立接口 | 补调 taobao.item.desc.get |
六、面试/方案一句话
淘宝/天猫数据用官方TOP API(taobao.item.get/taobao.trades.sold.get等)合法获取,基础接口有免费额度,MD5签名按参数ASCII升序拼AppSecret+KV+AppSecret转大写;查自己店铺SKU库存/订单须传卖家AccessToken(OAuth2授权),完全替代爬虫规避风控与法律风险。
需要我补 TOP OAuth2授权码→AccessToken完整Python代码 或 订单增量同步APScheduler脚本(带断点续跑) 吗?