在电商应用开发、数据分析等场景中,获取淘宝商品详情是常见需求。淘宝开放平台提供了标准化 API 接口,通过合法途径调用可高效获取商品信息。本文将详细介绍调用淘宝 API 获取商品详情的开发流程,并提供完整代码示例。
一、淘宝 API 准备工作
1. 注册开发者账号
访问注册账号并完成实名认证。创建应用时,选择 "服务型应用" 类型。
2. 获取 API 权限
在应用管理页面,申请 "商品基础信息查询" 相关权限。部分接口需要审核,审核通过后方可调用。
3. 获取关键参数
创建应用后,获取以下参数:
Api Key:应用标识Api Secret:应用密钥(用于签名生成)Session Key:如果需要获取用户私有数据,需用户授权后获取
4. 接口文档参考
核心接口:taobao.item.get(获取单个商品详情)
- 请求 URL:
- 请求方式:
GET或POST - 返回格式:JSON 或 XML(推荐 JSON)
二、API 调用核心流程
1. 签名生成规则
淘宝 API 要求所有请求必须包含签名参数,签名生成步骤:
- 将所有请求参数(除
sign外)按参数名 ASCII 码升序排序 - 将排序后的参数键值对拼接成字符串(格式:
key1value1key2value2...) - 在拼接字符串前后各加上
Api Secret - 对拼接后的字符串进行 MD5 加密,转换为大写
2. 公共请求参数
所有 API 请求都需要包含以下参数:
method:API 接口名称(如taobao.item.get)api_key:应用标识timestamp:请求时间戳(格式:yyyy-MM-dd HH:mm:ss)format:返回格式(可选json或xml)v:API 版本(固定为2.0)sign:签名参数
三、代码实现
下面提供 Python、PHP、Java 三种语言的实现示例。
Python 实现
import requests
import hashlib
import time
# 配置信息
APP_KEY = "你的App Key"
APP_SECRET = "你的App Secret"
API_URL = "https://eco.taobao.com/router/rest"
def generate_sign(params):
"""生成API签名"""
# 1. 按参数名ASCII码升序排序
sorted_params = sorted(params.items(), key=lambda x: x[0])
# 2. 拼接参数
sign_str = APP_SECRET
for k, v in sorted_params:
sign_str += f"{k}{v}"
sign_str += APP_SECRET
# 3. MD5加密并转换为大写
return hashlib.md5(sign_str.encode()).hexdigest().upper()
def get_item_detail(item_id):
"""获取商品详情"""
# 构造请求参数
params = {
"method": "taobao.item.get",
"app_key": APP_KEY,
"timestamp": time.strftime("%Y-%m-%d %H:%M:%S"),
"format": "json",
"v": "2.0",
"fields": "num_iid,title,price,pic_url,detail_url,item_imgs,props_name,brand",
"num_iid": item_id
}
# 生成签名
params["sign"] = generate_sign(params)
# 发送请求
try:
response = requests.get(API_URL, params=params)
result = response.json()
# 处理错误
if "error_response" in result:
error = result["error_response"]
print(f"API调用失败: {error['code']} - {error['msg']}")
return None
# 返回商品详情
return result["item_get_response"]["item"]
except Exception as e:
print(f"请求异常: {e}")
return None
# 示例调用
if __name__ == "__main__":
item_id = "1234567890" # 替换为实际商品ID
item = get_item_detail(item_id)
if item:
print(f"商品ID: {item['num_iid']}")
print(f"商品标题: {item['title']}")
print(f"商品价格: {item['price']}")
print(f"主图URL: {item['pic_url']}")
print(f"商品详情页: {item['detail_url']}")
# 打印更多字段...
PHP 实现
<?php
// 配置信息
$appKey = "你的App Key";
$appSecret = "你的App Secret";
$apiUrl = "https://eco.taobao.com/router/rest";
/**
* 生成API签名
* @param array $params 请求参数
* @return string 签名结果
*/
function generateSign($params) {
global $appSecret;
// 1. 按参数名ASCII码升序排序
ksort($params);
// 2. 拼接参数
$signStr = $appSecret;
foreach ($params as $key => $value) {
$signStr .= $key . $value;
}
$signStr .= $appSecret;
// 3. MD5加密并转换为大写
return strtoupper(md5($signStr));
}
/**
* 获取商品详情
* @param string $itemId 商品ID
* @return array|false 商品详情数组,失败时返回false
*/
function getItemDetail($itemId) {
global $appKey, $appSecret, $apiUrl;
// 构造请求参数
$params = [
"method" => "taobao.item.get",
"app_key" => $appKey,
"timestamp" => date("Y-m-d H:i:s"),
"format" => "json",
"v" => "2.0",
"fields" => "num_iid,title,price,pic_url,detail_url,item_imgs,props_name,brand",
"num_iid" => $itemId
];
// 生成签名
$params["sign"] = generateSign($params);
// 发送请求
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $apiUrl . "?" . http_build_query($params));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
$response = curl_exec($ch);
$error = curl_error($ch);
curl_close($ch);
if ($error) {
echo "请求异常: $error";
return false;
}
// 解析响应
$result = json_decode($response, true);
// 处理错误
if (isset($result["error_response"])) {
$error = $result["error_response"];
echo "API调用失败: {$error['code']} - {$error['msg']}";
return false;
}
// 返回商品详情
return $result["item_get_response"]["item"];
}
// 示例调用
$itemId = "1234567890"; // 替换为实际商品ID
$item = getItemDetail($itemId);
if ($item) {
echo "商品ID: {$item['num_iid']}\n";
echo "商品标题: {$item['title']}\n";
echo "商品价格: {$item['price']}\n";
echo "主图URL: {$item['pic_url']}\n";
echo "商品详情页: {$item['detail_url']}\n";
// 打印更多字段...
}
?>
Java 实现
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.*;
public class TaobaoApiClient {
// 配置信息
private static final String APP_KEY = "你的App Key";
private static final String APP_SECRET = "你的App Secret";
private static final String API_URL = "https://eco.taobao.com/router/rest";
/**
* 生成API签名
* @param params 请求参数
* @return 签名结果
*/
public static String generateSign(Map<String, String> params) {
// 1. 按参数名ASCII码升序排序
List<String> keys = new ArrayList<>(params.keySet());
Collections.sort(keys);
// 2. 拼接参数
StringBuilder signStr = new StringBuilder(APP_SECRET);
for (String key : keys) {
signStr.append(key).append(params.get(key));
}
signStr.append(APP_SECRET);
// 3. MD5加密并转换为大写
try {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] digest = md.digest(signStr.toString().getBytes());
StringBuilder hexStr = new StringBuilder();
for (byte b : digest) {
String hex = Integer.toHexString(b & 0xFF);
if (hex.length() == 1) {
hexStr.append('0');
}
hexStr.append(hex);
}
return hexStr.toString().toUpperCase();
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("MD5加密失败", e);
}
}
/**
* 获取商品详情
* @param itemId 商品ID
* @return 商品详情JSON字符串
*/
public static String getItemDetail(String itemId) {
// 构造请求参数
Map<String, String> params = new HashMap<>();
params.put("method", "taobao.item.get");
params.put("app_key", APP_KEY);
params.put("timestamp", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
params.put("format", "json");
params.put("v", "2.0");
params.put("fields", "num_iid,title,price,pic_url,detail_url,item_imgs,props_name,brand");
params.put("num_iid", itemId);
// 生成签名
params.put("sign", generateSign(params));
// 拼接请求URL
StringBuilder urlBuilder = new StringBuilder(API_URL);
urlBuilder.append("?");
for (Map.Entry<String, String> entry : params.entrySet()) {
urlBuilder.append(entry.getKey())
.append("=")
.append(entry.getValue())
.append("&");
}
String requestUrl = urlBuilder.deleteCharAt(urlBuilder.length() - 1).toString();
// 发送HTTP请求
try {
URL url = new URL(requestUrl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(5000);
connection.setReadTimeout(5000);
int responseCode = connection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
StringBuilder response = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
response.append(line);
}
reader.close();
return response.toString();
} else {
throw new IOException("HTTP请求失败,状态码: " + responseCode);
}
} catch (Exception e) {
System.err.println("请求异常: " + e.getMessage());
return null;
}
}
public static void main(String[] args) {
String itemId = "1234567890"; // 替换为实际商品ID
String response = getItemDetail(itemId);
if (response != null) {
System.out.println("API响应: " + response);
// 解析JSON响应...
}
}
}
四、关键参数说明
1. 公共参数
| 参数名 | 描述 | 是否必填 |
|---|---|---|
method | API 接口名称 | 是 |
api_key | 应用标识 | 是 |
timestamp | 请求时间戳 | 是 |
format | 返回格式 | 否 |
v | API 版本 | 是 |
sign | 签名 | 是 |
2. 接口特定参数
| 参数名 | 描述 | 是否必填 |
|---|---|---|
fields | 需要返回的字段列表 | 是 |
num_iid | 商品 ID | 是 |
五、常见问题及解决方案
1. 签名错误
- 检查参数排序是否正确(按 ASCII 码升序)
- 确认拼接字符串时是否包含
sign参数(不应包含) - 检查
Api Secret是否正确,前后是否都添加
2. 接口权限不足
- 确认已申请相应接口权限
- 检查权限是否已审核通过
3. 调用频率限制
- 淘宝 API 对不同接口有调用频率限制(如 QPS 限制)
- 可通过缓存机制减少重复请求
- 合理控制请求频率,避免触发限流
六、扩展与优化
1. 批量获取商品
可通过循环调用接口实现多商品数据获取,但需注意:
- 控制请求频率,避免触发反爬机制
- 考虑使用异步请求提高效率
2. 数据缓存
对于高频访问的商品数据,可使用 Redis 等缓存工具:
import redis
# 连接Redis
r = redis.Redis(host='localhost', port=6379, db=0)
def get_cached_item_detail(item_id):
# 先从缓存获取
cached_data = r.get(f"taobao_item:{item_id}")
if cached_data:
return json.loads(cached_data)
# 缓存未命中,调用API
item_data = get_item_detail(item_id)
if item_data:
# 缓存1小时
r.setex(f"taobao_item:{item_id}", 3600, json.dumps(item_data))
return item_data
3. 异常处理增强
完善的异常处理可提高程序稳定性:
def safe_get_item_detail(item_id, max_retries=3):
"""带重试机制的商品详情获取"""
for i in range(max_retries):
try:
return get_item_detail(item_id)
except Exception as e:
print(f"尝试 {i+1}/{max_retries} 失败: {e}")
time.sleep(2 ** i) # 指数退避
return None
七、合规声明
使用淘宝 API 需遵守淘宝服务协议:
- 数据仅限自身应用使用,禁止转售或提供给第三方
- 控制爬取频率,避免对平台造成压力
- 敏感数据(如用户隐私)需妥善保护
通过本文提供的代码和方法,你可以合法、高效地获取淘宝商品详情数据,为电商应用开发、数据分析等场景提供支持。


被折叠的 条评论
为什么被折叠?



