×

微店 item_get 接口深度深度分析及 Python 实现

万邦科技Lex 万邦科技Lex 发表于2025-09-09 15:46:54 浏览268 评论0

抢沙发发表评论

      注册账号免费测试微店API数据接口

微店的 item_get 接口是获取商品详情数据的核心接口,能够获取微店平台上商品的基础信息、价格、库存、规格、图片等详细数据。对于电商分析、竞品监控、数据挖掘等场景具有重要价值。

一、接口核心特性分析

1. 接口功能与定位

  • ** 核心功能 :获取微店商品的详细信息,包括基础信息、价格体系、库存状态、规格参数、图片等
    -
     数据特点 **:

    • 包含微店特有营销信息,如分销信息、限时折扣等

    • 数据结构贴近微店前端展示形式

    • 包含商品的多维度信息,满足不同场景需求
      -** 应用场景 **:

    • 电商竞品分析系统

    • 商品价格监控工具

    • 多平台商品数据整合

    • 市场趋势分析

2. 认证机制

微店开放平台采用 appkey + appsecret 进行认证:


  • 开发者在微店开放平台注册应用,获取 appkey 和 appsecret

  • 部分接口可能需要用户授权获取 access_token

  • 接口调用需在请求中携带相关认证信息

3. 核心参数与响应结构

请求参数

参数名类型是否必填说明
item_idString商品 ID
appkeyString应用密钥
timestampInteger时间戳
signString签名
shop_idString店铺 ID

响应核心字段

  • 商品基础信息:商品 ID、名称、描述、分类等

  • 价格信息:原价、售价、折扣信息等

  • 库存信息:总库存、规格库存等

  • 规格参数:商品规格、属性等

  • 多媒体信息:商品主图、详情图等

  • 营销信息:是否参与活动、活动类型等

二、Python 脚本实现

以下是调用微店 item_get 接口的完整 Python 实现:
import requests
import time
import json
import logging
import hashlib
import re
from typing import Dict, Optional, List
from requests.exceptions import RequestException

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

class WeidianItemGetAPI:
    def __init__(self, appkey: str, appsecret: str):
        """
        初始化微店商品详情API客户端
        :param appkey: 微店开放平台appkey
        :param appsecret: 微店开放平台appsecret
        """
        self.appkey = appkey
        self.appsecret = appsecret
        self.base_url = "https://api.vdian.com"
        self.session = requests.Session()
        self.session.headers.update({
            "Content-Type": "application/json",
            "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"
        })

    def _generate_sign(self, params: Dict) -> str:
        """生成签名"""
        # 按参数名排序
        sorted_params = sorted(params.items(), key=lambda x: x[0])
        # 拼接参数
        sign_str = self.appsecret
        for k, v in sorted_params:
            sign_str += f"{k}{v}"
        sign_str += self.appsecret
        # MD5加密
        return hashlib.md5(sign_str.encode()).hexdigest().upper()

    def get_item_details(self, item_id: str, shop_id: Optional[str] = None) -> Optional[Dict]:
        """
        获取商品详情
        :param item_id: 商品ID
        :param shop_id: 店铺ID(可选)
        :return: 商品详情数据
        """
        # 构建基础参数
        timestamp = int(time.time())
        params = {
            "method": "item.get",
            "appkey": self.appkey,
            "timestamp": timestamp,
            "item_id": item_id
        }
        
        # 添加可选参数
        if shop_id:
            params["shop_id"] = shop_id
            
        # 生成签名
        params["sign"] = self._generate_sign(params)
        
        try:
            response = self.session.get(f"{self.base_url}/api", params=params, timeout=15)
            response.raise_for_status()
            result = response.json()
            
            # 检查响应状态
            if result.get("status", 0) == 0:
                # 格式化商品数据
                return self._format_item_data(result.get("result", {}))
            else:
                logging.error(f"获取商品详情失败: {result.get('msg', '未知错误')} (错误码: {result.get('status')})")
                return None
                
        except RequestException as e:
            logging.error(f"获取商品详情请求异常: {str(e)}")
            return None
        except json.JSONDecodeError:
            logging.error(f"商品详情响应解析失败: {response.text[:200]}...")
            return None

    def _format_item_data(self, item_data: Dict) -> Dict:
        """格式化商品数据"""
        # 基础信息提取
        base_info = {
            "item_id": item_data.get("item_id"),
            "title": item_data.get("title"),
            "sub_title": item_data.get("sub_title"),
            "shop_id": item_data.get("shop_id"),
            "shop_name": item_data.get("shop_name"),
            "category": {
                "cid": item_data.get("cid"),
                "cname": item_data.get("cname")
            },
            "create_time": item_data.get("create_time"),
            "update_time": item_data.get("update_time"),
            "sales_count": self._safe_int(item_data.get("sales_count")),  # 销量
            "comment_count": self._safe_int(item_data.get("comment_count"))  # 评论数
        }
        
        # 价格信息提取
        price_info = {
            "original_price": self._safe_float(item_data.get("original_price")),  # 原价
            "price": self._safe_float(item_data.get("price")),  # 售价
            "discount": self._safe_float(item_data.get("discount")),  # 折扣
            "min_price": self._safe_float(item_data.get("min_price")),  # 最低价格(多规格时)
            "max_price": self._safe_float(item_data.get("max_price"))   # 最高价格(多规格时)
        }
        
        # 库存与规格信息提取
        sku_info = {
            "total_stock": self._safe_int(item_data.get("stock")),  # 总库存
            "skus": self._format_skus(item_data.get("skus", [])),
            "specs": self._format_specs(item_data.get("specs", []))
        }
        
        # 多媒体信息提取
        media_info = {
            "main_images": item_data.get("main_images", []),  # 主图
            "detail_images": item_data.get("detail_images", []),  # 详情图
            "video_url": item_data.get("video_url")  # 视频地址
        }
        
        # 商品描述
        description = {
            "detail": self._clean_html(item_data.get("detail", "")),
            "short_description": item_data.get("short_description")
        }
        
        # 营销信息
        marketing_info = {
            "is_promotion": item_data.get("is_promotion", False),  # 是否促销
            "promotion_type": item_data.get("promotion_type"),  # 促销类型
            "promotion_end_time": item_data.get("promotion_end_time"),  # 促销结束时间
            "is_distribution": item_data.get("is_distribution", False),  # 是否支持分销
            "distribution_commission": self._safe_float(item_data.get("distribution_commission"))  # 分销佣金
        }
        
        return {
            "base_info": base_info,
            "price_info": price_info,
            "sku_info": sku_info,
            "media_info": media_info,
            "description": description,
            "marketing_info": marketing_info,
            "raw_data": item_data  # 保留原始数据
        }
    
    def _safe_float(self, value) -> float:
        """安全转换为float"""
        try:
            return float(value) if value is not None else 0.0
        except (ValueError, TypeError):
            return 0.0
    
    def _safe_int(self, value) -> int:
        """安全转换为int"""
        try:
            return int(value) if value is not None else 0
        except (ValueError, TypeError):
            return 0
    
    def _format_skus(self, skus: List[Dict]) -> List[Dict]:
        """格式化SKU列表"""
        formatted = []
        for sku in skus:
            formatted.append({
                "sku_id": sku.get("sku_id"),
                "specs": sku.get("specs", []),  # 规格组合
                "price": self._safe_float(sku.get("price")),
                "original_price": self._safe_float(sku.get("original_price")),
                "stock": self._safe_int(sku.get("stock")),
                "sales_count": self._safe_int(sku.get("sales_count")),
                "image_url": sku.get("image_url")
            })
        return formatted
    
    def _format_specs(self, specs: List[Dict]) -> List[Dict]:
        """格式化规格参数列表"""
        formatted = []
        for spec in specs:
            formatted.append({
                "name": spec.get("name"),
                "values": [
                    {
                        "name": val.get("name"),
                        "image_url": val.get("image_url"),
                        "spec_id": val.get("spec_id")
                    } for val in spec.get("values", [])
                ]
            })
        return formatted
    
    def _clean_html(self, html: str) -> str:
        """清理HTML内容,提取纯文本"""
        if not html:
            return ""
        # 去除HTML标签
        clean = re.sub(r'<.*?>', ' ', html)
        # 去除多余空格和换行
        clean = re.sub(r'\s+', ' ', clean).strip()
        return clean


# 示例调用
if __name__ == "__main__":
    # 替换为实际的appkey和appsecret(从微店开放平台获取)
    APPKEY = "your_appkey"
    APPSECRET = "your_appsecret"
    # 替换为目标商品ID
    ITEM_ID = "123456789"
    # 可选:替换为店铺ID
    SHOP_ID = "987654321"
    
    # 初始化API客户端
    api = WeidianItemGetAPI(APPKEY, APPSECRET)
    
    # 获取商品详情
    item_data = api.get_item_details(
        item_id=ITEM_ID,
        shop_id=SHOP_ID  # 可选参数
    )
    
    if item_data:
        print(f"=== 微店商品详情 (item_id: {ITEM_ID}) ===")
        print(f"商品名称: {item_data['base_info']['title']}")
        print(f"店铺名称: {item_data['base_info']['shop_name']}")
        print(f"类目: {item_data['base_info']['category']['cname']}")
        print(f"销量: {item_data['base_info']['sales_count']}件")
        print(f"评论数: {item_data['base_info']['comment_count']}")
        
        # 价格信息
        print("\n价格信息:")
        print(f"  原价: {item_data['price_info']['original_price']}元")
        print(f"  售价: {item_data['price_info']['price']}元")
        if item_data['price_info']['discount'] < 10:
            print(f"  折扣: {item_data['price_info']['discount']}折")
        
        # 库存信息
        print(f"\n库存: {item_data['sku_info']['total_stock']}件")
        
        # 规格信息
        if item_data['sku_info']['skus']:
            print("\n规格信息:")
            for i, sku in enumerate(item_data['sku_info']['skus'][:3], 1):
                specs = ", ".join([f"{s['name']}:{s['value']}" for s in sku['specs']]) if sku['specs'] else "标准"
                print(f"  {i}. {specs}: {sku['price']}元, 库存{sku['stock']}件")
        
        # 营销信息
        print("\n营销信息:")
        print(f"  促销状态: {'正在促销' if item_data['marketing_info']['is_promotion'] else '未促销'}")
        if item_data['marketing_info']['is_promotion']:
            print(f"  促销类型: {item_data['marketing_info']['promotion_type']}")
        print(f"  支持分销: {'是' if item_data['marketing_info']['is_distribution'] else '否'}")
        if item_data['marketing_info']['is_distribution']:
            print(f"  分销佣金: {item_data['marketing_info']['distribution_commission']}%")
        
        # 媒体信息
        print(f"\n主图数量: {len(item_data['media_info']['main_images'])}")
        print(f"详情图数量: {len(item_data['media_info']['detail_images'])}")
        if item_data['media_info']['video_url']:
            print("包含商品视频")

三、接口调用注意事项

1. 调用限制与规范

  • QPS 限制:微店开放平台对商品详情接口有 QPS 限制,通常为 10-20 次 / 秒

  • 数据缓存:建议对获取的商品数据进行缓存,缓存时间建议 30 分钟到 1 小时

  • 合法使用:获取的商品数据需遵守微店平台规定,不得用于非法用途

  • 参数规范:确保传递正确的商品 ID 和店铺 ID,否则可能返回错误数据

2. 常见错误及解决方案

错误码说明解决方案
10001认证失败检查 appkey 和 appsecret 是否正确
10002签名错误检查签名生成算法是否正确
10003参数错误检查请求参数是否完整和正确
10004商品不存在确认 item_id 是否正确有效
10005访问频率超限降低调用频率,实现请求限流
10006权限不足检查是否有访问该接口的权限

3. 数据解析要点

  • 价格处理:注意区分原价和售价,多规格商品有最低和最高价格

  • 库存计算:总库存与各规格库存可能存在差异,需根据实际需求选择

  • 规格结构:规格信息可能是多层结构,需要递归解析

  • 图片处理:部分图片 URL 可能需要特殊处理才能直接访问

  • 时间格式:时间字段可能是时间戳或字符串,需统一转换

四、应用场景与扩展建议

典型应用场景

  • 商品监控系统:实时监控商品价格、库存变化

  • 竞品分析工具:对比分析同类商品的参数、价格等信息

  • 多平台数据整合:将微店商品数据与其他平台数据整合分析

  • 智能选品系统:基于商品数据和销售情况辅助选品决策

扩展建议

  • 实现商品价格变化追踪:定期获取价格数据,记录价格波动

  • 开发库存预警功能:当商品库存低于阈值时发出预警

  • 构建商品相似度匹配系统:根据商品属性推荐相似商品

  • 实现多店铺商品对比分析:同一商品在不同店铺的价格、销量对比

  • 开发商品数据导出功能:支持将商品数据导出为 Excel、CSV 等格式


通过合理使用微店 item_get 接口,开发者可以构建功能丰富的商品分析系统,为电商运营和决策提供有力支持。使用时需遵守微店开放平台的相关规定,确保数据的合法使用。


群贤毕至

访客