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

admin6天前淘宝api22

一、概述

淘宝商品类目是电商平台最基础的数据结构之一,它决定了商品在平台上的展示方式、属性规则以及搜索推荐逻辑。淘宝开放平台提供了多个类目相关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响应,构建类目树结构


相关文章

1688 商品详情接口实战指南

在 B2B 电商领域,1688 作为国内最大的批发采购平台,沉淀了海量的商品与供应商资源。对于采购企业、数据分析机构及开发者来说,精准获取商品详情数据是实现智能选品、供应链优化、市场洞察的核心前提。而...

Python获取淘宝商品详情数据SKU接口

在电商领域,淘宝作为国内领先的电商平台,拥有海量的商品和丰富的店铺数据。对于开发者和数据分析师来说,能够获取淘宝商品的SKU(Stock Keeping Unit,库存进出计量的基本单元)详情数据至关...

淘宝 API 接口获取教程

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

电商平台“图片搜索”接口获取数据全攻略

——淘宝、天猫、1688、京东、拼多多对比与实战一、背景:为什么需要“以图搜款”直播带货、社交电商、比价工具、ERP 选品、供应链爬虫都离不开“看到一张图,就能找到同款/相似款”的能力。各家官方把这项...

从客户需求到 API 落地:淘宝商品详情批量爬取与接口封装实践

一、需求分析:不只是"爬数据"那么简单在电商数据分析场景中,客户的核心需求通常包含三个层次:基础层:批量获取商品标题、价格、销量、评价等公开信息加工层:数据清洗、格式统一、实时更新...

利用 Java 爬虫获取淘宝商品详情 API 接口数据

在电商领域,淘宝作为国内领先的电商平台,拥有海量的商品数据。对于开发者和数据分析师来说,获取淘宝商品详情数据对于市场分析、价格监控、用户体验优化等场景具有重要意义。本文将详细介绍如何使用 Java 编...

发表评论    

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