阅读视图

发现新文章,点击刷新页面。

干货!Python采集淘宝商品详情数据,淘宝API接口系列(json数据返回)

以下是基于淘宝开放平台API的Python商品详情采集深度指南,包含完整技术实现与合规注意事项:

一、前置条件准备

  1. 开放平台入驻

    • 注册平台账号
    • 创建应用获取app_keyapp_secret
    • 申请taobao.item.get接口权限(需企业认证)
  2. 商品ID获取技巧

    python
    # 从商品链接提取num_iid
    import re
    url = "https://detail.tmall.com/item.htm?id=68543210987"
    item_id = re.search(r'id=(\d+)', url).group(1)
    

二、完整API调用实现(增强版)

python
import requests
import hashlib
import time
import json
from urllib.parse import urlparse

class TaobaoAPI:
    def __init__(self, app_key, app_secret, sandbox=False):
        self.app_key = app_key
        self.app_secret = app_secret
        self.sandbox = sandbox
        self.base_url = "https://gw.api.tbsandbox.com/router/rest" if sandbox else "https://eco.taobao.com/router/rest"

    def _generate_sign(self, params):
        """生成符合淘宝规范的MD5签名"""
        param_str = "".join(f"{k}{params[k]}" for k in sorted(params.keys()))
        sign_str = f"{self.app_secret}{param_str}{self.app_secret}"
        return hashlib.md5(sign_str.encode('utf-8')).hexdigest().upper()

    def get_item_detail(self, item_id, fields="num_iid,title,price,pic_url,desc,skus,props_name,quantity"):
        """获取商品详情(含错误重试机制)"""
        params = {
            'method': 'taobao.item.get',
            'app_key': self.app_key,
            'timestamp': time.strftime("%Y-%m-%d %H:%M:%S"),
            'format': 'json',
            'v': '2.0',
            'sign_method': 'md5',
            'num_iid': item_id,
            'fields': fields
        }
        
        # 添加签名
        params['sign'] = self._generate_sign(params)
        
        # 添加公共参数
        params.update(self._get_common_params())
        
        try:
            response = requests.get(self.base_url, params=params, timeout=5)
            response.raise_for_status()
            return response.json()
        except (requests.exceptions.RequestException, KeyError) as e:
            return self._handle_error(e, item_id)

    def _get_common_params(self):
        """获取公共请求参数"""
        return {
            'partner_id': 'open-api-sdk',
            'target_app_key': '12345678',  # 替换为目标APPKEY
            'sdk_version': '2.0',
            'simplify': 'false'
        }

    def _handle_error(self, error, item_id):
        """错误处理与重试逻辑"""
        if isinstance(error, requests.exceptions.Timeout):
            return {"error": "Request timeout"}
        elif 'code' in str(error):
            error_code = json.loads(error).get('error_response', {}).get('code')
            return self._map_error_code(error_code, item_id)
        return {"error": str(error)}

    def _map_error_code(self, code, item_id):
        """错误码映射处理"""
        error_map = {
            11: "API权限不足,请检查应用权限",
            27: f"商品不存在或无权限访问: {item_id}",
            100: "参数错误,请检查请求参数",
            10001: "系统内部错误,请重试"
        }
        return {"error": error_map.get(code, "未知错误")}

# 使用示例
if __name__ == "__main__":
    APP_KEY = "YOUR_APP_KEY"
    APP_SECRET = "YOUR_APP_SECRET"
    ITEM_ID = "68543210987"
    
    taobao = TaobaoAPI(APP_KEY, APP_SECRET)
    result = taobao.get_item_detail(ITEM_ID)
    
    # 解析响应数据
    if 'error' not in result:
        item_data = result['taobao_item_get_response']['item']
        print(f"商品标题: {item_data['title']}")
        print(f"价格: ¥{item_data['price']}")
        print(f"主图: {item_data['pic_url']}")
        
        # 处理SKU数据
        skus = item_data.get('skus', {}).get('sku', [])
        for sku in skus:
            print(f"规格: {sku['properties']} | 价格: {sku['price']} | 库存: {sku['quantity']}")
    else:
        print(f"错误信息: {result['error']}")

三、关键技术细节解析

  1. 签名算法优化

    • 采用参数名排序+值拼接的MD5加密方式
    • 示例签名串:secretkeyapp_key12345fieldsnum_iid,titleformatjsonmethodtaobao.item.getnum_iid123456timestamp2025-10-28 12:00:00v2.0secretkey
  2. 字段选择策略

    • 基础字段:num_iid,title,price,pic_url
    • 扩展字段:desc(详情描述)、props_name(属性名)、quantity(库存)
    • 规格数据:通过skus字段获取多规格商品信息
  3. 错误处理增强

    • 网络请求超时重试机制
    • 错误码映射系统(如11→权限不足,27→商品不存在)
    • 沙箱环境测试支持

四、合规与反爬策略

  1. 频率控制

    python
    # 请求间隔控制示例
    import time
    def safe_request(item_id):
        time.sleep(0.2)  # 5秒内不超过25次请求
        return taobao.get_item_detail(item_id)
    
  2. **User-Agent设置

    python
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
    }
    
  3. IP代理轮换

    • 建议使用代理IP池应对高频访问限制
    • 可集成scrapy-rotating-proxy等中间件

五、数据解析示例

返回JSON典型结构:

json
{
  "taobao_item_get_response": {
    "item": {
      "num_iid": "68543210987",
      "title": "2025春季新款男士休闲裤",
      "price": "129.00",
      "pic_url": "https://img.alicdn.com/example.jpg",
      "desc": "<img src='...' />商品详细描述",
      "skus": {
        "sku": [
          {
            "properties": "颜色:深蓝;尺码:30",
            "price": "129.00",
            "quantity": 200
          },
          {
            "properties": "颜色:黑色;尺码:32",
            "price": "139.00",
            "quantity": 150
          }
        ]
      }
    }
  }
}

六、常见问题解决方案

  1. 权限不足(错误码11)

    • 检查应用权限配置
    • 确认已申请taobao.item.get接口
    • 联系开放平台客服提升权限
  2. 商品不存在(错误码27)

    • 确认商品ID正确性
    • 检查商品是否下架或区域限制
    • 验证应用是否有权访问该商品
  3. 签名验证失败

    • 检查时间戳格式(YYYY-MM-DD HH:MM:SS)
    • 确认参数排序正确
    • 验证app_secret是否泄露

基于浏览器扩展 API Mock 工具开发探索|得物技术

一、前 言

在日常开发过程中,偶尔会遇到后端接口未完成或者某个环境出现问题需要根据接口返回来复现等等场景。刚好最近在学习浏览器插件的相关知识,并在此背景下开发了一款基于浏览器插件的 Mock 工具。该工具专注于 API 请求拦截和数据模拟,旨在帮助开发者提升开发效率,能够解决一些问题。

二、浏览器插件介绍

什么是浏览器插件

浏览器插件(Extensions 或 Add-ons)是一类运行于浏览器进程中的轻量级功能增强模块,其核心价值在于通过标准化接口实现对浏览器内核能力的深度整合与定制。根据 Mozilla 开发者文档定义,插件本质上是“能够修改和增强浏览器能力的应用程序”,Firefox、Chrome 等主流浏览器均采用 WebExtensions API 这一跨浏览器技术构建插件生态。与网页应用(Web App)需依赖浏览器标签页运行、原生应用(Native App)需独立安装的特性不同,插件以轻量化部署为显著特征——无需复杂设置即可直接在浏览器环境内运行,同时具备标签控制、网络请求拦截、本地存储访问等网页应用无法实现的底层能力。

Manifest V3 架构

Manifest V3 对浏览器插件的底层架构进行了颠覆性重构,主要体现在背景执行机制、网络请求控制和代码安全模型三个核心维度。以下从技术实现与设计动机角度进行全面对比:

关键架构变革:V3 采用"静态声明+内核级处理"模式替代 V2 的"动态脚本+插件自主控制"模式,通过浏览器内核直接介入关键流程(如网络拦截),在性能与安全性之间取得平衡。

核心配置差异示例

背景执行模块配置

// V2 持久化背景页配置"
background": {
  "scripts": ["background.js"],  
  "persistent": true             
}


// V3 Service Worker 配置
"background": {
   "service_worker": "background.js",  
   "type": "module"                   
}

网络请求规则配置

V3 需在 Manifest 中声明 DNR 权限及规则文件:

// V3 declarativeNetRequest 配置
"permissions": ["declarativeNetRequest"],
"host_permissions": ["<all_urls>"],
"declarative_net_request": {
   "rule_resources": [
       {"id": "ruleset_1","enabled": true,"path": "rules.json"  }
    ]
}

三、Mock 插件实现的基本原理

请求拦截的核心原理

由于 Manifest V3 移除了webRequest API 的阻塞能力,declarativeNetRequest又无法重定向到自定义数据,于是方案上选择的是在页面上下文中重写原生 API,目前重写了fetch跟XMLHttpRequest。

// injected.js - 在页面环境中重写fetch
const originalFetch = window.fetch;
window.fetch = async function(url, options = {}) {
  // 1. 发送拦截请求到content script
  const response = await sendMockRequest(url, options);


  // 2. 如果有匹配的Mock规则,返回Mock数据
  if (response.shouldMock) {
    return new Response(
      JSON.stringify(response.mockData),
      {
        status: response.status,
        headers: response.headers
      }
    );
  }


  // 3. 否则执行原始请求
  return originalFetch.call(this, url, options);
};

脚本注入

通过多重注入策略 + 动态检测的方式实现, 直接引入会触发 Content Security Policy 阻止内联脚本执行。

// content.js
async function injectScript() {
  // 策略1: 内联脚本注入
  try {
    await injectInlineScript();
    if (await checkScriptActivation()) return;
  } catch (e) {
    console.warn('内联注入失败:', e);
  }


  // 策略2: 外部脚本注入
  try {
    await injectExternalScript();
    if (await checkScriptActivation()) return;
  } catch (e) {
    console.warn('外部注入失败:', e);
  }


  // 策略3: 最简单注入方式
  await attemptSimpleInjection();
}

四、整体实现架构与流程

项目结构设计

chrome-mock/
├── build-script/          # rollup 进行构建
├── static/                # 静态文件引入,如mockjs
├── debug/                 # 本地调试相关的页面
├── manifest.json          # 插件配置
├── background.js          # 核心逻辑处理
├── content.js            # 脚本注入和消息中转
├── injected.js           # 请求拦截实现
├── options.html          # 管理界面
├── options.js            # 管理界面逻辑
├── options.css           # 管理界面样式
├── popup.html            # 弹窗界面
├── popup.js              # 弹窗逻辑
├── popup.css             # 弹窗样式
└── icons/                # 图标资源

相关功能介绍

创建 Mock 规则

创建 Mock 规则提供了多种方式:

  • 如果是快速联调的场景,可以用得物API管理平台导入的方式。
  • 在排查某个环境问题,需要根据服务端接口返回数据复现的时候,可以通过在管理规则页面手动新建。

方法一:快捷操作弹窗配置

  • 打开 Mock 管理页面
    • 点击浏览器工具栏中的 Mock Frog 图标;
    • 选择"管理规则"或直接访问扩展选项页。
  • 添加新规则

方式一:复制粘贴得物API管理平台地址,点击导入,自动生成。这个弹窗比较小适合自动导入的场景,也可以点击上面 popup 的管理规则再进行操作。

如:https:/apiManage.test.com/project/interface?id=3xxxx&projectId=5xxxx

本地调用可能会有代理增加了前缀,系统会自动在路径前添加通配符 *

方式二:复制接口地址到匹配 URL 输入框中自行配置数据,这一步建议到管理规则中才施展的开。

支持根据接口平台的 JSON Schema 生成对应类型的 Mock 数据。

Mock 效果演示:

,时长00:14

方法二:管理规则页配置

由于 popup 界面大小有限,点击其他区域弹窗也会关闭,提供了一个比较详细的管理页可以修改添加规则。

规则列表:

新建 Mock 规则:

页面白名单管理

作用:针对所有页面都进行拦截可能会导致页面卡顿,影响整体性能,于是增加了白名单控制,控制 Mock 功能在哪些场景下才生效。同时也提供了全局生效模式,方便快速操作。

使用方法:

  • 开启白名单功能
    • 进入扩展设置页面
    • 找到"页面白名单"配置
    • 启用"使用页面白名单"
  • 添加白名单域名
支持格式:
- http://localhost:3000        # 完整URL
- *.example.com               # 通配符域名
- dev.company.com             # 具体域名
- http://dev.company.com      # 带协议的域名

请求日志

作用:记录所有 Mock 请求的详细信息,便于调试。

整体流程

五、总结与收获

本次插件开发过程中,探索了浏览器扩展插件的能力,学习了 Manifest V3 的新知识,掌握了浏览器插件开发相关技术点。随之而来带来的思考便是在 AI 的浪潮下,浏览器插件是否能有更多的可能。

另外,本次很多功能点的实现也依赖了 Cursor,探索浏览器插件的同时也深入的学习了Cursor的应用,感受到了Cursor从 0 到 1 搭建过程中的速度和效率。但是在后续需要对功能点进行改造时,使用效率并不是高,如何建立规则和组织话术,让 AI 更加规范、高效地辅助开发是一个值得深思的问题,当然通过 rules 是能够解决大部分问题。

六、未来展望

功能升级:在复杂业务场景中,往往需要Mock的接口都比较多。如果能监听页面所有请求,然后提供通过选中某个历史请求即可Mock接口的方式,就能快速实现接口的Mock。

能力拓展:探索在浏览器插件上结合 AI 能力的应用,基于规则跟用户的要求更快速的生成 Mock 数据。

往期回顾

1. 破解gh-ost变更导致MySQL表膨胀之谜|得物技术

2. MySQL单表为何别超2000万行?揭秘B+树与16KB页的生死博弈|得物技术

3. 0基础带你精通Java对象序列化--以Hessian为例|得物技术

4. 前端日志回捞系统的性能优化实践|得物技术

5. 得物灵犀搜索推荐词分发平台演进3.0

文 /段壹

关注得物技术,每周更新技术干货

要是觉得文章对你有帮助的话,欢迎评论转发点赞~

未经得物技术许可严禁转载,否则依法追究法律责任。

❌