淘宝关键词搜索 API 接入实战:快速开发商品数据采集接口

124 阅读5分钟

一、淘宝 API 接入概述

淘宝平台为开发者提供了丰富的****API 接口****,允许第三方应用获取淘宝商品、订单、用户等多方面的数据。本文将重点介绍如何接入淘宝商品搜索 API,实现根据关键词搜索商品数据的功能。

import requests
import hashlib
import time
import json
import logging

# 配置日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)

class TaobaoAPI:
    def __init__(self, app_key, app_secret, redirect_uri=None):
        """初始化淘宝API客户端"""
        self.app_key = app_key
        self.app_secret = app_secret
        self.redirect_uri = redirect_uri
        self.access_token = None
        self.token_expire_time = 0
        self.api_url = "https://eco.taobao.com/router/rest"  # 淘宝开放平台API网关
    
    def generate_sign(self, params):
        """生成API签名"""
        # 按照参数名的字典序升序排列
        sorted_params = sorted(params.items(), key=lambda x: x[0])
        # 拼接参数名和参数值
        sign_str = self.app_secret
        for k, v in sorted_params:
            sign_str += f"{k}{v}"
        sign_str += self.app_secret
        # MD5加密并转换为大写
        return hashlib.md5(sign_str.encode('utf-8')).hexdigest().upper()
    
    def get_access_token(self, code=None):
        """获取或刷新访问令牌"""
        # 如果已有有效令牌,直接返回
        if self.access_token and time.time() < self.token_expire_time - 60:
            return self.access_token
        
        # 使用授权码换取令牌
        if code:
            params = {
                "grant_type": "authorization_code",
                "client_id": self.app_key,
                "client_secret": self.app_secret,
                "code": code,
                "redirect_uri": self.redirect_uri
            }
        # 刷新令牌
        else:
            params = {
                "grant_type": "refresh_token",
                "client_id": self.app_key,
                "client_secret": self.app_secret,
                "refresh_token": self.refresh_token
            }
        
        try:
            response = requests.post("https://oauth.taobao.com/token", data=params)
            response.raise_for_status()
            token_data = response.json()
            
            if "access_token" in token_data:
                self.access_token = token_data["access_token"]
                self.refresh_token = token_data.get("refresh_token")
                # 设置过期时间(默认15天)
                self.token_expire_time = time.time() + token_data.get("expires_in", 1296000)
                logger.info("获取访问令牌成功")
                return self.access_token
            else:
                logger.error(f"获取令牌失败: {token_data.get('error_description', '未知错误')}")
                return None
                
        except Exception as e:
            logger.error(f"获取令牌异常: {str(e)}")
            return None
    
    def execute(self, method, params, need_auth=False):
        """执行API请求"""
        # 公共参数
        common_params = {
            "app_key": self.app_key,
            "method": method,
            "format": "json",
            "v": "2.0",
            "sign_method": "md5",
            "timestamp": time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
        }
        
        # 需要授权的API添加令牌
        if need_auth:
            if not self.access_token:
                logger.error("执行需要授权的API,但没有有效的访问令牌")
                return None
            common_params["session"] = self.access_token
        
        # 合并参数
        all_params = {**common_params, **params}
        # 生成签名
        all_params["sign"] = self.generate_sign(all_params)
        
        try:
            # 发送请求
            response = requests.get(self.api_url, params=all_params)
            response.raise_for_status()
            result = response.json()
            
            # 检查API返回是否有错误
            error_response = result.get("error_response")
            if error_response:
                error_code = error_response.get("code")
                error_msg = error_response.get("msg")
                sub_code = error_response.get("sub_code")
                sub_msg = error_response.get("sub_msg")
                logger.error(f"API调用失败 - 主错误: {error_code} {error_msg}, 子错误: {sub_code} {sub_msg}")
                return None
                
            return result
            
        except Exception as e:
            logger.error(f"API请求异常: {str(e)}")
            return None
    
    def item_search(self, keyword, page=1, page_size=20):
        """搜索商品接口"""
        method = "taobao.tbk.item.get"  # 示例API,实际应使用有效的淘宝客商品搜索API
        params = {
            "q": keyword,
            "page_no": page,
            "page_size": page_size,
            # 其他必要参数
            "fields": "num_iid,title,pict_url,small_images,reserve_price,zk_final_price,user_type,provcity,item_url,seller_id,volume,nick"
        }
        return self.execute(method, params, need_auth=True)

# 使用示例
if __name__ == "__main__":
    # 从配置文件或环境变量获取密钥
    APP_KEY = "your_app_key"
    APP_SECRET = "your_app_secret"
    REDIRECT_URI = "https://your-redirect-uri.com"
    
    # 初始化API客户端
    api = TaobaoAPI(APP_KEY, APP_SECRET, REDIRECT_URI)
    
    # 如果已有令牌,设置令牌
    # api.access_token = "your_access_token"
    
    # 如果没有令牌,需要先获取授权码并换取令牌
    # 1. 引导用户访问授权页面
    auth_url = f"https://oauth.taobao.com/authorize?response_type=code&client_id={APP_KEY}&redirect_uri={REDIRECT_URI}&state=STATE"
    print(f"请访问以下URL进行授权: {auth_url}")
    # 2. 用户授权后会重定向到REDIRECT_URI,并携带code参数
    # code = input("请输入授权码: ")
    # api.get_access_token(code)
    
    # 搜索商品
    keyword = "手机"
    result = api.item_search(keyword, page=1, page_size=10)
    if result:
        # 处理搜索结果
        items = result.get("tbk_item_get_response", {}).get("results", {}).get("n_tbk_item", [])
        print(f"找到 {len(items)} 个商品")
        for item in items:
            print(f"商品: {item.get('title')}, 价格: {item.get('zk_final_price')}, 销量: {item.get('volume')}")
    else:
        print("搜索失败")    

淘宝 API 接入的基本流程包括:

  1. 注册开发者账号
  2. 获取 ApiKey 和 ApiSecret
  3. 进行 API 权限申请
  4. 实现 OAuth2.0 授权流程
  5. 调用商品搜索 API
  6. 处理返回数据

二、开发环境准备

在开始开发前,需要准备以下工作:

  1. 注册淘宝平台开发者账号
  2. 获取 ApiKey 和 ApiSecret
  3. 申请必要的 API 权限(如商品搜索 API)
  4. 选择开发语言(本文示例使用 Python)
  5. 安装必要的开发工具和依赖库

三、API 接入核心实现

淘宝 API 接入的核心是实现签名算法和 OAuth2.0 授权流程。

1.签名算法实现

淘宝 API 要求对所有请求参数进行签名验证,确保请求的合法性和完整性。签名算法步骤如下:

  • 将所有请求参数按照参数名的字典序排序
  • 拼接参数名和参数值(不包括 sign 参数本身)
  • 在首尾加上 ApiSecret
  • 使用 MD5 加密并转换为大写

2.OAuth2.0 授权流程

淘宝 API 采用 OAuth2.0 进行用户授权,主要流程包括:

  • 引导用户访问授权页面
  • 用户授权后获取授权码
  • 使用授权码换取访问令牌 (Access Token)
  • 使用刷新令牌定期刷新访问令牌

3.商品搜索 API 调用

获取访问令牌后,就可以调用商品搜索 API 获取商品数据了。根据不同的业务需求,可以选择不同的商品搜索 API,如淘宝客商品搜索、天猫商品搜索等。

四、代码实现解析

上面提供的代码实现了一个完整的淘宝 API 客户端,包括以下功能:

  1. 初始化 API 客户端:设置 ApiKey、ApiSecret 等基本信息
  2. 签名生成:实现了淘宝 API 要求的签名算法
  3. 授权管理:处理 OAuth2.0 授权流程,包括获取和刷新访问令牌
  4. API 请求执行:封装了通用的 API 请求方法
  5. 商品搜索:实现了商品搜索的具体方法

在使用时,首先需要创建 API 客户端实例,然后进行授权(如果已有令牌可以直接设置),最后调用商品搜索方法获取数据。

五、注意事项与优化建议

  1. 频率限制:淘宝 API 对调用频率有严格限制,开发时需要注意控制请求频率,避免被封禁
  2. 错误处理:完善的错误处理机制非常重要,特别是网络异常和 API 返回错误
  3. 数据缓存:对于热门关键词的搜索结果,可以考虑适当缓存,减少 API 调用次数
  4. 安全存储:ApiKey 和 ApiSecret 等敏感信息应妥善存储,避免泄露
  5. 异步处理:在高并发场景下,建议使用异步请求方式提高性能

通过以上步骤和代码示例,你可以快速实现淘宝关键词搜索 API 的接入,开发出功能完善的商品数据采集接口。