以下是Python采集淘宝商品详情数据的干货指南,基于淘宝API接口(JSON返回)的完整实现方案,包含核心步骤、代码示例及优化策略:
1. 准备工作:获取API访问权限
- 注册开放平台账号:关注博主,完成企业/个人实名认证。
- 创建应用 :在"应用管理"中创建API应用,获取
App Key
和App Secret
(密钥需严格保密)。 - 申请API权限 :在"API管理"中搜索
taobao.item.get
接口,提交权限申请(部分接口需审核)。
2. 核心步骤:调用商品详情API
2.1 生成请求签名
淘宝API要求所有请求必须签名,以HMAC-SHA1
或MD5
算法为例:
python
python
import hashlib
import hmac
import time
import urllib.parse
def generate_sign(params, app_secret, method="md5"):
sorted_params = sorted(params.items(), key=lambda x: x[0]) # 参数按ASCII排序
query_string = "".join(f"{k}{v}" for k, v in sorted_params)
sign_str = f"{app_secret}{query_string}{app_secret}"
if method == "md5":
return hashlib.md5(sign_str.encode()).hexdigest().upper()
else: # hmac-sha1
return hmac.new(app_secret.encode(), sign_str.encode(), hashlib.sha1).digest()
2.2 构建请求参数
以taobao.item.get
接口为例,关键参数:
perl
python
params = {
"method": "taobao.item.get",
"app_key": "YOUR_APP_KEY",
"timestamp": time.strftime("%Y-%m-%d %H:%M:%S"),
"format": "json",
"v": "2.0",
"sign_method": "md5",
"num_iid": "123456789", # 商品ID
"fields": "num_iid,title,price,pic_url,skus" # 动态字段选择器
}
params["sign"] = generate_sign(params, "YOUR_APP_SECRET")
2.3 发送请求并解析JSON
使用requests
库发送GET请求,处理JSON响应:
python
python
import requests
def get_item_detail(item_id):
url = "https://eco.taobao.com/router/rest"
response = requests.get(url, params=params)
if response.status_code == 200:
data = response.json()
if "error_response" in data: # 错误处理
raise Exception(f"API错误: {data['error_response']['msg']}")
return data["item_get_response"]["item"]
else:
raise Exception(f"HTTP错误: {response.status_code}")
3. JSON数据解析与存储
3.1 解析商品详情
返回的JSON结构示例:
json
json
{
"item_get_response": {
"item": {
"num_iid": "123456789",
"title": "商品标题",
"price": "99.90",
"pic_url": ["http://img.alicdn.com/..."],
"skus": {
"sku": [
{"properties": "颜色:红色;尺寸:M", "price": "99.90", "quantity": 100}
]
}
}
}
}
解析代码:
css
python
def parse_item(item_data):
return {
"商品ID": item_data["num_iid"],
"标题": item_data["title"],
"价格": float(item_data["price"]),
"主图": item_data["pic_url"][0],
"SKU列表": [
{
"属性": s["properties"],
"价格": float(s["price"]),
"库存": int(s["quantity"])
} for s in item_data["skus"]["sku"]
]
}
3.2 数据存储
使用pandas
或数据库存储(如MySQL):
python
python
import pandas as pd
def save_to_csv(items):
df = pd.DataFrame(items)
df.to_csv("taobao_items.csv", index=False)
4. 优化策略与错误处理
4.1 动态字段选择器
通过fields
参数指定返回字段,减少数据量(如fields=num_iid,title,price
),提升传输效率。
4.2 错误处理与重试
实现指数退避重试机制:
python
python
import time
import random
def retry_api_call(func, max_retries=5):
for i in range(max_retries):
try:
return func()
except Exception as e:
if "RATE_LIMIT" in str(e):
wait_time = min(2**i + random.uniform(0, 1), 30)
time.sleep(wait_time)
else:
raise
raise Exception("Max retries exceeded")
4.3 代理IP与反爬策略
使用scrapy-proxies
或轮询代理池,避免IP封禁:
csharp
python
proxies = [{"http": "http://1.1.1.1:8080"}, {"http": "http://2.2.2.2:8080"}]
proxy_cycle = cycle(proxies)
def get_with_proxy(url, params):
proxy = next(proxy_cycle)
try:
response = requests.get(url, params=params, proxies=proxy, timeout=5)
return response.json()
except:
return get_with_proxy(url, params) # 自动切换代理重试
5. 完整代码示例
python
python
import requests
import hashlib
import time
import pandas as pd
from itertools import cycle
# 配置信息
APP_KEY = "YOUR_APP_KEY"
APP_SECRET = "YOUR_APP_SECRET"
PROXY_POOL = [{"http": "http://1.1.1.1:8080"}, {"http": "http://2.2.2.2:8080"}]
def generate_sign(params, app_secret):
sorted_params = sorted(params.items())
query_string = "".join(f"{k}{v}" for k, v in sorted_params)
sign_str = f"{app_secret}{query_string}{app_secret}"
return hashlib.md5(sign_str.encode()).hexdigest().upper()
def get_item_detail(item_id):
url = "https://eco.taobao.com/router/rest"
params = {
"method": "taobao.item.get",
"app_key": APP_KEY,
"timestamp": time.strftime("%Y-%m-%d %H:%M:%S"),
"format": "json",
"v": "2.0",
"sign_method": "md5",
"num_iid": item_id,
"fields": "num_iid,title,price,pic_url,skus"
}
params["sign"] = generate_sign(params, APP_SECRET)
proxy_cycle = cycle(PROXY_POOL)
for _ in range(3): # 最多尝试3个代理
proxy = next(proxy_cycle)
try:
response = requests.get(url, params=params, proxies=proxy, timeout=10)
if response.status_code == 200:
data = response.json()
if "error_response" not in data:
return data["item_get_response"]["item"]
raise Exception("请求失败")
except:
continue
raise Exception("所有代理均失败")
# 采集多个商品
items = []
for item_id in ["123456789", "987654321"]:
try:
item = get_item_detail(item_id)
items.append(parse_item(item))
except Exception as e:
print(f"采集失败: {str(e)}")
# 保存数据
save_to_csv(items)
6. 关键注意事项
- 频率限制:默认QPS为10,超限需重试或申请提额。
- 数据合规:遵守淘宝数据使用政策,避免敏感信息泄露。
- 版本更新:关注淘宝API文档变动,及时调整代码。
通过以上方案,可高效采集淘宝商品详情数据,并处理JSON返回结果,适用于电商分析、竞品监控等场景。