在电商开发场景中,调用淘宝 API 获取商品信息是常见需求,但直接编写原生请求代码易出现冗余、维护难等问题。本文将通过 Python 语言,实战演示如何封装一个可复用的商品信息获取类,实现参数统一管理、请求异常处理、数据格式标准化,让 API 调用更优雅、更高效。
一、前期准备:淘宝 API 接入基础
在封装类之前,需完成淘宝 API 的接入准备,确保调用权限和参数正确。
1. 核心前置条件
- 申请 API 权限:获取
ApiKey和ApiSecret。 - 了解接口规范:明确目标接口的请求方式(如 GET/POST)、必填参数(如商品 ID
num_iid)、返回格式(通常为 JSON),参考淘宝开放平台官方接口文档。 - 安装依赖库:使用
requests库发送 HTTP 请求,pycryptodome库处理 API 签名(淘宝 API 需签名验证),执行以下命令安装:
pip install requests pycryptodome
二、核心思路:可复用类的设计原则
为确保类的复用性和可维护性,设计时遵循以下 3 个原则:
- 参数分离:将固定配置(如
App Key、接口地址)与动态参数(如商品 ID)分离,通过初始化方法传入固定配置,查询方法传入动态参数。 - 异常统一处理:捕获网络错误、参数缺失、API 返回错误等常见异常,返回标准化的结果(成功 / 失败标识 + 数据 / 错误信息),避免上层调用崩溃。
- 单一职责:类仅负责 “淘宝商品信息获取” 相关逻辑,不掺杂数据存储、业务计算等其他功能,便于后续扩展(如新增库存查询方法)。
三、代码实战:封装淘宝商品信息获取类
1. 完整代码实现
import requests
import time
import hashlib
from urllib.parse import urlencode
from typing import Dict, Optional, Tuple
class TaobaoProductApi:
"""淘宝商品信息获取工具类,支持获取商品详情、价格等信息"""
def __init__(self, app_key: str, app_secret: str):
"""
初始化淘宝API配置
:param app_key: 淘宝开放平台申请的App Key
:param app_secret: 淘宝开放平台申请的App Secret
"""
# 固定配置:接口基础地址、请求超时时间
self.app_key = app_key
self.app_secret = app_secret
self.base_url = "https://eco.taobao.com/router/rest" # 淘宝API公共网关
self.timeout = 10 # 请求超时时间(秒)
def _generate_sign(self, params: Dict) -> str:
"""
生成淘宝API所需的签名(签名规则:参数按key排序→拼接→加secret→MD5加密→转大写)
:param params: 待签名的请求参数
:return: 签名字符串
"""
# 1. 按参数key的ASCII码升序排序
sorted_params = sorted(params.items(), key=lambda x: x[0])
# 2. 拼接为"key=value&key=value"格式
param_str = urlencode(sorted_params)
# 3. 拼接App Secret,生成签名
sign_str = self.app_secret + param_str + self.app_secret
# 4. MD5加密并转为大写
sign = hashlib.md5(sign_str.encode("utf-8")).hexdigest().upper()
return sign
def _create_common_params(self, method: str) -> Dict:
"""
创建淘宝API的公共请求参数(所有接口均需携带)
:param method: 接口名称(如"taobao.item.get"表示获取商品详情)
:return: 公共参数字典
"""
return {
"app_key": self.app_key,
"method": method,
"format": "json", # 返回格式
"v": "2.0", # API版本
"timestamp": time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()), # 当前时间
"sign_method": "md5" # 签名方式
}
def get_product_detail(self, num_iid: str) -> Tuple[bool, Optional[Dict]]:
"""
获取商品详情信息(调用taobao.item.get接口)
:param num_iid: 商品ID(淘宝商品的唯一标识)
:return: (是否成功, 数据/错误信息):成功时返回(True, 商品详情字典),失败时返回(False, 错误描述)
"""
try:
# 1. 检查必填参数
if not num_iid.strip():
return False, "商品ID(num_iid)不能为空"
# 2. 构建请求参数(公共参数+接口私有参数)
method = "taobao.item.get"
common_params = self._create_common_params(method)
private_params = {
"num_iid": num_iid,
"fields": "num_iid,title,price,pic_url,detail_url,stock" # 需要返回的字段
}
all_params = {**common_params, **private_params}
# 3. 生成签名并添加到参数中
all_params["sign"] = self._generate_sign(all_params)
# 4. 发送GET请求
response = requests.get(
url=self.base_url,
params=all_params,
timeout=self.timeout
)
response.raise_for_status() # 若状态码非200,抛出HTTPError
# 5. 解析返回结果
result = response.json()
# 淘宝API成功时返回"item_get_response",失败时返回"error_response"
if "error_response" in result:
error_msg = result["error_response"]["msg"]
return False, f"API返回错误:{error_msg}"
product_data = result["item_get_response"]["item"]
return True, product_data
except requests.exceptions.RequestException as e:
# 捕获网络异常(超时、连接失败等)
return False, f"网络请求错误:{str(e)}"
except Exception as e:
# 捕获其他未知异常
return False, f"未知错误:{str(e)}"
# ------------------- 类的使用示例 -------------------
if __name__ == "__main__":
# 1. 替换为自己的App Key和App Secret
APP_KEY = "你的淘宝App Key"
APP_SECRET = "你的淘宝App Secret"
# 2. 初始化API工具类
taobao_api = TaobaoProductApi(app_key=APP_KEY, app_secret=APP_SECRET)
# 3. 获取指定商品详情(示例商品ID:自行替换为真实有效ID)
product_id = "612345678901" # 注意:需使用有权限访问的商品ID
success, data = taobao_api.get_product_detail(num_iid=product_id)
# 4. 处理结果
if success:
print("商品详情获取成功:")
print(f"商品标题:{data['title']}")
print(f"商品价格:{data['price']}元")
print(f"商品图片:{data['pic_url']}")
print(f"商品库存:{data['stock']}件")
else:
print(f"商品详情获取失败:{data}")
2. 代码核心模块解析
(1)签名生成方法_generate_sign
淘宝 API 要求所有请求参数需经过签名验证,防止参数被篡改。该方法按以下步骤生成签名:
- 对请求参数按
key的 ASCII 码升序排序; - 拼接为
key=value&key=value格式; - 在拼接字符串前后添加
App Secret; - 通过 MD5 加密并转为大写,得到最终签名。
(2)公共参数方法_create_common_params
所有淘宝 API 接口均需携带公共参数(如app_key、timestamp),该方法统一生成这些参数,避免重复编写。
(3)商品详情查询方法get_product_detail
该方法是类的核心业务方法,流程如下:
- 校验必填参数(商品 ID);
- 合并公共参数与接口私有参数;
- 生成签名并发送请求;
- 捕获异常并解析返回结果,返回标准化的成功 / 失败信息。
四、类的扩展与优化建议
- 新增接口方法:若需获取商品价格、销量等其他信息,可参考
get_product_detail方法,新增get_product_price、get_product_sales等方法,只需修改method(接口名称)和private_params(私有参数)。 - 添加请求重试机制:在网络不稳定场景下,可引入
tenacity库,为请求添加重试逻辑(如重试 3 次,每次间隔 2 秒)。 - 参数缓存:对高频查询的商品 ID,可添加本地缓存(如使用
lru_cache装饰器),减少重复 API 调用,降低接口费用。 - 日志记录:引入
logging库,将请求日志、错误日志记录到文件,便于问题排查。
五、注意事项
- API 权限与配额:淘宝开放平台对 API 调用有配额限制(如免费应用每日调用次数有限),需合理规划调用频率,避免超限。
- 参数安全:
App Secret属于敏感信息,请勿硬编码到代码中,建议通过环境变量或配置文件读取。 - 接口版本:本文使用淘宝 API 2.0 版本,若后续接口版本更新,需同步调整
v参数和返回结果解析逻辑。