调用淘宝API接口获取商品类目:完整开发指南

admin10小时前淘宝api9

一、概述

淘宝商品类目是电商平台最基础的数据结构之一,它决定了商品在平台上的展示方式、属性规则以及搜索推荐逻辑。淘宝开放平台提供了多个类目相关API接口,开发者可以通过这些接口获取完整的类目体系、类目属性及属性值等信息。本文将详细介绍如何注册开发者账号、申请权限、生成签名并调用类目相关API。

二、准备工作

2.1 注册淘宝开放平台账号

  1. 访问 淘宝开放平台 官网
  2. 点击注册,使用淘宝账号登录并完成实名认证
  3. 进入控制台,创建新应用

2.2 创建应用并获取密钥

在开放平台控制台中:
  1. 进入「应用管理」→「创建应用」
  2. 填写应用名称、描述、图标等信息
  3. 选择应用类型(自用型他用型
  4. 填写使用场景和目的
  5. 提交审核,审核通过后将获得:
    • App Key:应用标识
    • App Secret:应用密钥(用于签名)

2.3 申请API权限

在应用详情页中找到「接口权限」模块,申请以下类目相关接口权限:
  • taobao.itemcats.get — 获取可供发布的类目列表
  • taobao.item.cat.get — 获取单个类目详情
  • taobao.itemprops.get — 获取标准商品类目属性
  • taobao.itempropvalues.get — 获取标准类目属性值
  • taobao.itemcats.authorize.get — 查询商家被授权的品牌和类目
⚠️ 注意:淘宝开放平台会根据应用情况、资质及安全策略进行审核,部分接口可能需要商家授权才能调用。

三、核心API接口详解

3.1 接口概览

表格
接口名称功能描述是否需要授权
taobao.itemcats.get获取可供发布的标准类目列表
taobao.item.cat.get获取单个类目详细信息
taobao.itemprops.get获取类目的属性列表
taobao.itempropvalues.get获取类目的属性值列表
taobao.itemcats.authorize.get查询商家被授权的品牌和类目

四、签名生成机制

淘宝API采用 HMAC-MD5 签名算法,所有请求参数必须经过签名验证。签名步骤如下:

4.1 签名规则

  1. 排序:将所有参数(除 sign 外)按参数名 ASCII 码升序排列
  2. 拼接:将排序后的参数按 key+value 格式拼接成字符串,首尾各加一次 App Secret
  3. 加密:使用 HMAC-MD5 算法加密,结果转大写

4.2 Python签名示例

Python
import hmacimport hashlibimport urllib.parsedef generate_sign(params: dict, app_secret: str) -> str:
    """
    生成淘宝API请求签名(HMAC-MD5)
    
    :param params: 请求参数(不含sign)
    :param app_secret: 应用密钥
    :return: 签名字符串(大写)
    """
    # 1. 过滤空值参数,按key排序
    sorted_params = sorted(
        [(k, v) for k, v in params.items() if v is not None and k != 'sign'],
        key=lambda x: x[0]
    )
    
    # 2. 拼接字符串:secret + key1value1 + key2value2 + ... + secret
    sign_content = app_secret    for key, value in sorted_params:
        sign_content += f"{key}{value}"
    sign_content += app_secret    
    # 3. HMAC-MD5加密
    sign = hmac.new(
        app_secret.encode('utf-8'),
        sign_content.encode('utf-8'),
        hashlib.md5    ).hexdigest().upper()
    
    return sign

五、完整调用示例

5.1 获取一级类目列表(taobao.itemcats.get)

该接口用于获取可供发布的标准类目,通过递归调用可获取完整的类目树。
Python
import requestsimport timeimport json# ========== 配置信息 ==========APP_KEY = 'your_app_key'          # 替换为你的App KeyAPP_SECRET = 'your_app_secret'    # 替换为你的App SecretAPI_URL = 'https://eco.taobao.com/router/rest'# ========== 签名生成函数 ==========def generate_sign(params, app_secret):
    sorted_params = sorted(
        [(k, v) for k, v in params.items() if v is not None and k != 'sign'],
        key=lambda x: x[0]
    )
    sign_content = app_secret    for key, value in sorted_params:
        sign_content += f"{key}{value}"
    sign_content += app_secret    
    import hmac, hashlib
    sign = hmac.new(
        app_secret.encode('utf-8'),
        sign_content.encode('utf-8'),
        hashlib.md5    ).hexdigest().upper()
    return sign# ========== 获取类目列表 ==========def get_itemcats(parent_cid=0, fields=None):
    """
    调用 taobao.itemcats.get 获取类目列表
    
    :param parent_cid: 父类目ID,0表示获取一级类目
    :param fields: 返回字段,默认获取常用字段
    :return: 类目列表
    """
    if fields is None:
        fields = "cid,parent_cid,name,is_parent,status,sort_order"
    
    params = {
        'app_key': APP_KEY,
        'method': 'taobao.itemcats.get',
        'timestamp': time.strftime('%Y-%m-%d %H:%M:%S'),
        'format': 'json',
        'v': '2.0',
        'sign_method': 'hmac-md5',
        'fields': fields,
        'parent_cid': parent_cid    }
    
    # 生成签名
    params['sign'] = generate_sign(params, APP_SECRET)
    
    # 发送请求
    response = requests.post(API_URL, data=params, timeout=30)
    result = response.json()
    
    # 解析结果
    if 'itemcats_get_response' in result:
        itemcats = result['itemcats_get_response'].get('item_cats', {}).get('item_cat', [])
        return itemcats    else:
        error = result.get('error_response', {})
        print(f"调用失败: {error.get('msg', '未知错误')}")
        return None# ========== 递归获取完整类目树 ==========def build_category_tree(parent_cid=0, max_depth=3, current_depth=0):
    """
    递归构建类目树
    
    :param parent_cid: 父类目ID
    :param max_depth: 最大递归深度
    :param current_depth: 当前深度
    :return: 类目树结构
    """
    if current_depth >= max_depth:
        return []
    
    categories = get_itemcats(parent_cid)
    if not categories:
        return []
    
    tree = []
    for cat in categories:
        node = {
            'cid': cat.get('cid'),
            'name': cat.get('name'),
            'parent_cid': cat.get('parent_cid'),
            'is_parent': cat.get('is_parent'),
            'status': cat.get('status'),
            'sort_order': cat.get('sort_order'),
            'children': []
        }
        
        # 如果是父类目,递归获取子类目
        if cat.get('is_parent') and current_depth < max_depth - 1:
            # 添加延时避免触发限流(个人开发者通常1QPS)
            time.sleep(1.2)
            node['children'] = build_category_tree(
                cat.get('cid'), max_depth, current_depth + 1
            )
        
        tree.append(node)
    
    return tree# ========== 主程序 ==========if __name__ == '__main__':
    print("=" * 50)
    print("淘宝商品类目获取工具")
    print("=" * 50)
    
    # 获取一级类目
    print("\n【一级类目列表】")
    top_categories = get_itemcats(parent_cid=0)
    for cat in top_categories[:5]:  # 只展示前5个
        print(f"  📁 [{cat['cid']}] {cat['name']} "
              f"{'(有子类目)' if cat.get('is_parent') else '(叶子类目)'}")
    
    # 获取某个一级类目下的二级类目(以女装为例:cid=50008163)
    print("\n【女装类目下的二级类目】")
    sub_categories = get_itemcats(parent_cid=50008163)
    if sub_categories:
        for cat in sub_categories[:5]:
            print(f"  📂 [{cat['cid']}] {cat['name']}")
    
    # 构建完整类目树(示例:只递归2层)
    print("\n【构建类目树(深度2)】")
    # tree = build_category_tree(parent_cid=0, max_depth=2)
    # print(json.dumps(tree, ensure_ascii=False, indent=2))

5.2 获取单个类目详情(taobao.item.cat.get)

Python
def get_item_cat_detail(cid):
    """
    获取单个类目的详细信息
    
    :param cid: 类目ID
    :return: 类目详情
    """
    params = {
        'app_key': APP_KEY,
        'method': 'taobao.item.cat.get',
        'timestamp': time.strftime('%Y-%m-%d %H:%M:%S'),
        'format': 'json',
        'v': '2.0',
        'sign_method': 'hmac-md5',
        'cid': cid    }
    
    params['sign'] = generate_sign(params, APP_SECRET)
    
    response = requests.post(API_URL, data=params, timeout=30)
    result = response.json()
    
    if 'item_cat_get_response' in result:
        return result['item_cat_get_response'].get('item_cat', {})
    else:
        error = result.get('error_response', {})
        print(f"获取失败: {error.get('msg', '未知错误')}")
        return None# 示例:获取女装类目详情cat_detail = get_item_cat_detail(50008163)if cat_detail:
    print(f"类目名称: {cat_detail.get('name')}")
    print(f"父类目ID: {cat_detail.get('parent_cid')}")
    print(f"是否为父类目: {cat_detail.get('is_parent')}")

5.3 获取类目属性(taobao.itemprops.get)

Python
def get_item_props(cid, fields=None):
    """
    获取类目的属性列表
    
    :param cid: 类目ID
    :param fields: 返回字段
    :return: 属性列表
    """
    if fields is None:
        fields = "pid,name,must,multi,prop_values,is_key_prop,is_sale_prop"
    
    params = {
        'app_key': APP_KEY,
        'method': 'taobao.itemprops.get',
        'timestamp': time.strftime('%Y-%m-%d %H:%M:%S'),
        'format': 'json',
        'v': '2.0',
        'sign_method': 'hmac-md5',
        'fields': fields,
        'cid': cid    }
    
    params['sign'] = generate_sign(params, APP_SECRET)
    
    response = requests.post(API_URL, data=params, timeout=30)
    result = response.json()
    
    if 'itemprops_get_response' in result:
        return result['itemprops_get_response'].get('item_props', {}).get('item_prop', [])
    else:
        error = result.get('error_response', {})
        print(f"获取失败: {error.get('msg', '未知错误')}")
        return None# 示例:获取手机类目(cid=1512)的属性print("\n【手机类目属性列表】")props = get_item_props(1512)if props:
    for prop in props[:5]:
        print(f"  🔧 [{prop['pid']}] {prop['name']} "
              f"{'(必填)' if prop.get('must') else '(选填)'} "
              f"{'(多选)' if prop.get('multi') else '(单选)'}")

5.4 获取类目属性值(taobao.itempropvalues.get)点击测试获取测试key

Python
def get_item_prop_values(cid, pvs, fields=None):
    """
    获取类目的属性值列表
    
    :param cid: 类目ID
    :param pvs: 属性ID,多个用逗号分隔,如 "139248429"
    :param fields: 返回字段
    :return: 属性值列表
    """
    if fields is None:
        fields = "cid,pid,prop_name,vid,name,name_alias,status,sort_order"
    
    params = {
        'app_key': APP_KEY,
        'method': 'taobao.itempropvalues.get',
        'timestamp': time.strftime('%Y-%m-%d %H:%M:%S'),
        'format': 'json',
        'v': '2.0',
        'sign_method': 'hmac-md5',
        'fields': fields,
        'cid': cid,
        'pvs': pvs    }
    
    params['sign'] = generate_sign(params, APP_SECRET)
    
    response = requests.post(API_URL, data=params, timeout=30)
    result = response.json()
    
    if 'itempropvalues_get_response' in result:
        return result['itempropvalues_get_response'].get('prop_values', {}).get('prop_value', [])
    else:
        error = result.get('error_response', {})
        print(f"获取失败: {error.get('msg', '未知错误')}")
        return None

六、返回字段说明

6.1 taobao.itemcats.get 返回字段

表格
字段名类型说明
cidNumber类目ID
parent_cidNumber父类目ID
nameString类目名称
is_parentBoolean是否为父类目(true表示有子类目)
statusString类目状态(normal/normal)
sort_orderNumber排序值

6.2 类目属性字段

表格
字段名类型说明
pidNumber属性ID
nameString属性名称
mustBoolean是否必填
multiBoolean是否多选
is_key_propBoolean是否关键属性(如品牌、型号)
is_sale_propBoolean是否销售属性(影响SKU)

七、关键注意事项

7.1 调用频率限制

淘宝开放平台对接口调用有 QPS(每秒查询率)限制,个人开发者通常限制为 1 QPS。建议在代码中加入延时控制:
Python
import time# 每次调用间隔至少1.2秒time.sleep(1.2)

7.2 叶子类目

商品必须发布在叶子类目is_parent = false)下。获取叶子类目的方法是通过递归调用 taobao.itemcats.get,直到 is_parentfalse

7.3 管控类目

部分类目(如食品、酒类、书籍、保健品、农药、医疗等)需要卖家提供相关资质才能发布,调用 taobao.itemcats.authorize.get 可查询商家是否有权限发布。

7.4 错误处理

常见错误码及处理方式:
表格
错误码说明解决方案
isv.invalid-parameter参数错误检查参数格式和必填项
isv.permission-ip-limitIP受限在开放平台配置服务器IP白名单
isv.permission-api-forbiddenAPI权限不足申请对应接口权限
isv.trade-not-exist交易不存在检查传入的参数值

八、Java调用示例

java
import java.util.*;import javax.crypto.Mac;import javax.crypto.spec.SecretKeySpec;import org.apache.commons.codec.binary.Hex;import java.net.URLEncoder;public class TaobaoCategoryApi {
    
    private static final String APP_KEY = "your_app_key";
    private static final String APP_SECRET = "your_app_secret";
    private static final String API_URL = "https://eco.taobao.com/router/rest";
    
    /**
     * 生成HMAC-MD5签名
     */
    public static String generateSign(Map<String, String> params, String appSecret) throws Exception {
        List<String> keys = new ArrayList<>(params.keySet());
        Collections.sort(keys);
        
        StringBuilder sb = new StringBuilder();
        sb.append(appSecret);
        for (String key : keys) {
            String value = params.get(key);
            if (value != null && !value.isEmpty()) {
                sb.append(key).append(value);
            }
        }
        sb.append(appSecret);
        
        Mac mac = Mac.getInstance("HmacMD5");
        SecretKeySpec secretKey = new SecretKeySpec(appSecret.getBytes("UTF-8"), "HmacMD5");
        mac.init(secretKey);
        byte[] bytes = mac.doFinal(sb.toString().getBytes("UTF-8"));
        return Hex.encodeHexString(bytes).toUpperCase();
    }
    
    /**
     * 获取类目列表
     */
    public static String getItemCats(long parentCid) throws Exception {
        Map<String, String> params = new HashMap<>();
        params.put("app_key", APP_KEY);
        params.put("method", "taobao.itemcats.get");
        params.put("timestamp", new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        params.put("format", "json");
        params.put("v", "2.0");
        params.put("sign_method", "hmac-md5");
        params.put("fields", "cid,parent_cid,name,is_parent,status,sort_order");
        params.put("parent_cid", String.valueOf(parentCid));
        
        String sign = generateSign(params, APP_SECRET);
        params.put("sign", sign);
        
        // 构造请求URL
        StringBuilder urlBuilder = new StringBuilder(API_URL + "?");
        for (Map.Entry<String, String> entry : params.entrySet()) {
            urlBuilder.append(entry.getKey())
                     .append("=")
                     .append(URLEncoder.encode(entry.getValue(), "UTF-8"))
                     .append("&");
        }
        
        // 发送HTTP请求(此处使用HttpClient或URLConnection)
        // ...
        return urlBuilder.toString();
    }
    
    public static void main(String[] args) throws Exception {
        System.out.println(getItemCats(0));
    }}

九、总结

表格
步骤内容
1. 注册在淘宝开放平台注册开发者账号并完成实名认证
2. 创建应用创建应用并获取 App Key 和 App Secret
3. 申请权限申请类目相关API接口权限
4. 生成签名使用 HMAC-MD5 算法生成请求签名
5. 调用接口通过 HTTP POST/GET 发送请求到 https://eco.taobao.com/router/rest
6. 解析数据解析JSON响应,构建类目树结构


相关文章

API接口如何实现高并发:技术方案与优化策略

在现代互联网应用中,API接口的高并发处理能力是确保系统稳定性和用户体验的关键。高并发场景下,API接口需要能够快速响应大量同时请求,同时保持系统的稳定性和数据的准确性。本文将从多个方面探讨如何实现A...

淘宝 API 接口获取教程

淘宝开放平台提供了丰富的 API 接口,帮助开发者获取淘宝平台的数据。以下是详细的获取方法和使用流程:一、注册与认证注册账号:访问淘宝开放平台官网,完成个人或企业开发者账号注册。实名认证:注册成功后,...

淘宝 item_cat_get 接口详解:获取淘宝商品类目

一、接口概述item_cat_get 是淘宝开放平台提供的核心类目查询接口,用于获取淘宝/天猫平台的商品类目信息。该接口支持通过类目 ID 查询单个类目的详细信息,包括类目名称、层级、父类目、属性规则...

实战代码解析淘宝视频接口

下面给出一份「Java 版」可落地的淘宝商品视频接口实战代码,覆盖「Token 获取 → 签名 → 调用 → 解析 → 下载」完整链路。示例基于 2025 年仍稳定的 taobao.item.vide...

用“爬虫”思路做淘宝 API 接口测试:从申请 Key 到 Python 自动化脚本

关键词:淘宝开放平台、API 测试、接口签名、Python 爬虫、数据驱动测试一、背景与合规说明淘宝在 2024 年升级了“反爬+合规”双策略:网页端 cookie 加密粒度更细,直接破解易触发 22...

淘宝券后价详情API接口完全指南

一、接口体系概览淘宝券后价并非单一字段,而是通过优惠叠加计算得出的最终价格。官方提供以下核心接口 :表格接口类型核心接口数据覆盖适用场景权限要求淘宝联盟-商品详情taobao.tbk.item.inf...

发表评论    

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。