一、天猫 API 接入准备
1.1 申请账号
首先需要注册****账号****。
1.2 创建应用并获取密钥
登录选择所需的 API 权限,主要包括商品信息查询、价格监控等权限。创建成功后,获取 ApiKey 和 ApiSecret,这是调用 API 的身份凭证。
1.3 开发环境配置
推荐使用 Python 作为开发语言,因为其具有丰富的网络请求和数据处理库。需要安装以下 Python 库:
import requests # HTTP请求
import hashlib # 加密算法
import time # 时间处理
import json # JSON数据处理
import base64 # Base64编码
二、API 认证与签名机制
2.1 签名算法实现
天猫 API 采用 MD5 加密签名机制,需要按照特定规则生成签名:
def generate_sign(params, app_secret):
"""生成API请求签名"""
# 1. 参数排序
sorted_params = sorted(params.items(), key=lambda x: x[0])
# 2. 拼接参数
string_to_sign = app_secret
for k, v in sorted_params:
string_to_sign += f"{k}{v}"
string_to_sign += app_secret
# 3. MD5加密
sign = hashlib.md5(string_to_sign.encode()).hexdigest().upper()
return sign
2.2 公共请求参数
每次 API 请求都需要包含以下公共参数:
def get_common_params(app_key, method):
"""获取公共请求参数"""
return {
"app_key": app_key,
"method": method,
"format": "json",
"v": "2.0",
"sign_method": "md5",
"timestamp": time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
}
三、实时商品信息采集核心代码
3.1 商品详情 API 调用
以下是调用天猫商品详情 API 的核心代码:
def get_item_detail(app_key, app_secret, item_id):
"""获取天猫商品详情"""
# 设置请求参数
method = "taobao.tbk.item.info.get"
params = get_common_params(app_key, method)
# 添加业务参数
params["num_iids"] = item_id
params["platform"] = 1 # 1:PC, 2:无线
# 生成签名
sign = generate_sign(params, app_secret)
params["sign"] = sign
# 发送请求
url = "https://eco.taobao.com/router/rest"
response = requests.get(url, params=params)
# 解析响应
result = response.json()
if "error_response" in result:
print(f"API调用失败: {result['error_response']['sub_msg']}")
return None
return result["tbk_item_info_get_response"]["results"]["n_tbk_item"][0]
3.2 批量采集商品信息
为了提高效率,可以批量采集多个商品信息:
def batch_get_items(app_key, app_secret, item_ids, batch_size=20):
"""批量获取商品信息"""
all_items = []
for i in range(0, len(item_ids), batch_size):
batch_ids = item_ids[i:i+batch_size]
item_id_str = ",".join(map(str, batch_ids))
item_data = get_item_detail(app_key, app_secret, item_id_str)
if item_data:
all_items.extend(item_data)
# 控制请求频率,避免限流
time.sleep(1)
return all_items
四、数据解析与持久化
4.1 商品数据解析
获取到的商品数据包含丰富的信息,需要提取关键字段:
def parse_item_data(item):
"""解析商品数据"""
return {
"item_id": item.get("num_iid"),
"title": item.get("title"),
"price": float(item.get("zk_final_price")),
"original_price": float(item.get("reserve_price")),
"sales_volume": int(item.get("volume", 0)),
"shop_title": item.get("nick"),
"category_id": item.get("cat_id"),
"pic_url": item.get("pict_url"),
"coupon_amount": float(item.get("coupon_amount", 0)),
"commission_rate": float(item.get("commission_rate", 0)) / 100,
"update_time": int(time.time())
}
4.2 数据存储到 MongoDB
将采集到的数据存储到 MongoDB 数据库:
from pymongo import MongoClient
def save_to_mongodb(items, collection_name="tmall_items"):
"""将商品数据保存到MongoDB"""
client = MongoClient("mongodb://localhost:27017/")
db = client["tmall_data"]
collection = db[collection_name]
# 批量插入数据
if items:
collection.insert_many(items)
print(f"成功保存 {len(items)} 条商品数据")
client.close()
五、定时采集与监控
5.1 定时任务实现
使用 APScheduler 库实现定时采集:
from apscheduler.schedulers.blocking import BlockingScheduler
def scheduled_crawler(app_key, app_secret, item_ids_file):
"""定时采集任务"""
# 读取商品ID列表
with open(item_ids_file, "r") as f:
item_ids = [line.strip() for line in f.readlines() if line.strip()]
# 采集数据
items = batch_get_items(app_key, app_secret, item_ids)
# 解析数据
parsed_items = [parse_item_data(item) for item in items if item]
# 保存数据
save_to_mongodb(parsed_items)
print(f"定时采集完成,共获取 {len(parsed_items)} 条有效数据")
# 设置定时任务(每天上午10点和下午4点各执行一次)
scheduler = BlockingScheduler()
scheduler.add_job(scheduled_crawler, 'cron', hour='10,16',
args=[APP_KEY, APP_SECRET, "item_ids.txt"])
scheduler.start()
5.2 异常处理与监控
添加完善的异常处理和监控机制:
import logging
# 配置日志
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s',
filename='crawler.log'
)
def safe_crawler(func):
"""安全执行装饰器"""
def wrapper(*args, **kwargs):
try:
return func(*args, **kwargs)
except Exception as e:
logging.error(f"采集过程发生错误: {str(e)}", exc_info=True)
# 可以添加告警机制,如发送邮件或短信
return wrapper
六、反爬虫策略与应对
6.1 控制请求频率
在代码中已经通过time.sleep()
控制请求频率,建议:
- 普通应用:控制在 20-30 次 / 分钟
- 高级应用:根据 API 权限调整,但不要超过限制
6.2 代理 IP 池
使用代理 IP 池避免 IP 被封:
import random
PROXY_POOL = [
"http://101.101.101.1:8080",
"http://102.102.102.2:8080",
# 添加更多代理IP
]
def get_random_proxy():
"""获取随机代理IP"""
return random.choice(PROXY_POOL)
# 在请求中使用代理
response = requests.get(url, params=params, proxies={"http": get_random_proxy()})
6.3 User-Agent 池
使用不同的 User-Agent 模拟不同浏览器:
USER_AGENTS = [
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36",
# 添加更多User-Agent
]
# 在请求中设置随机User-Agent
headers = {"User-Agent": random.choice(USER_AGENTS)}
response = requests.get(url, params=params, headers=headers)
七、API 调用示例与结果展示
7.1 完整调用示例
以下是一个完整的调用示例:
if __name__ == "__main__":
# 配置信息
APP_KEY = "你的AppKey"
APP_SECRET = "你的AppSecret"
# 获取单个商品详情
item_id = "5678901234" # 示例商品ID
item = get_item_detail(APP_KEY, APP_SECRET, item_id)
if item:
parsed_item = parse_item_data(item)
print(f"商品标题: {parsed_item['title']}")
print(f"当前价格: {parsed_item['price']}元")
print(f"原价: {parsed_item['original_price']}元")
print(f"月销量: {parsed_item['sales_volume']}")
print(f"店铺名称: {parsed_item['shop_title']}")
else:
print("获取商品信息失败")
7.2 示例输出
商品标题: 【官方正品】2025夏季新款运动鞋男透气网面减震防滑跑步鞋
当前价格: 349.0元
原价: 499.0元
月销量: 23456
店铺名称: 某品牌官方旗舰店
八、注意事项与合规建议
- 遵守 API 调用限制:不要超出 API 的调用频率和量级限制,否则可能导致账号被封禁。
- 数据使用合规:采集到的数据仅用于合法用途,不得用于恶意竞争或侵犯用户隐私。
- 异常处理:完善的异常处理机制是保证爬虫稳定运行的关键。
- 定期维护:天猫 API 可能会更新,需要定期检查代码是否正常工作。
- 权限管理:妥善保管 AppKey 和 AppSecret,不要泄露到公开渠道。
通过以上步骤和代码实现,你可以构建一个稳定、高效的天猫商品信息实时采集系统,为电商数据分析、价格监控等应用提供有力支持。