×

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

万邦科技Lex 万邦科技Lex 发表于2025-09-02 10:12:20 浏览236 评论0

抢沙发发表评论

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

微店的 item_get 接口是用于获取微店商品详情的核心接口,能够可以获取商品的基本信息、价格、库存、规格、详情描述等全方位数据。该接口对于电商数据分析、竞品监控、多平台商品同步等场景具有重要价值。

一、接口核心特性分析

1. 接口功能与定位

  • 核心功能:获取微店平台上指定商品的完整详情数据

  • 数据范围:涵盖商品基础信息、价格体系、库存状态、规格参数、图文详情、销售数据等

  • 应用场景

    • 电商数据分析工具

    • 多平台商品同步系统

    • 竞品价格与策略监控

    • 电商导购与比价应用

2. 认证机制

微店开放平台采用 appkey + access_token 的认证方式:


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

  • 通过 appkey 和 appsecret 获取 access_token(有有效期)

  • 每次请求在 header 中携带 access_token 进行身份验证

3. 核心参数与响应结构

请求参数

参数名类型是否必填说明
item_idString商品 ID,微店商品详情页 URL 中获取
fieldsString需要返回的字段,多个字段用逗号分隔,默认返回所有字段

响应核心字段

  • 商品基础信息:商品 ID、标题、主图、详情页 URL、店铺信息等

  • 价格信息:原价、售价、会员价、是否促销等

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

  • 规格参数:规格名称、规格值、规格对应价格和库存等

  • 详情描述:图文详情、商品属性、售后服务等

  • 销售数据:销量、评价数、收藏数等

二、Python 脚本实现

以下是调用微店 item_get 接口的完整 Python 实现,包含令牌获取、接口调用、数据解析等功能:
import requests
import time
import json
import logging
import hashlib
from typing import Dict, Optional, List
from requests.exceptions import RequestException

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

class WeidianItemAPI:
    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.access_token = None
        self.token_expires_at = 0  # token过期时间戳
        self.session = requests.Session()
        
    def _get_access_token(self) -> Optional[str]:
        """获取访问令牌"""
        # 检查token是否有效
        if self.access_token and self.token_expires_at > time.time() + 60:
            return self.access_token
            
        logging.info("获取新的access_token")
        url = f"{self.base_url}/token"
        
        params = {
            "grant_type": "client_credentials",
            "appkey": self.appkey,
            "appsecret": self.appsecret
        }
        
        try:
            response = self.session.get(url, params=params, timeout=10)
            response.raise_for_status()
            result = response.json()
            
            if result.get("status") == 0:
                self.access_token = result.get("result", {}).get("access_token")
                expires_in = result.get("result", {}).get("expires_in", 3600)
                self.token_expires_at = time.time() + expires_in
                return self.access_token
            else:
                logging.error(f"获取access_token失败: {result.get('msg')}")
                return None
                
        except RequestException as e:
            logging.error(f"获取access_token请求异常: {str(e)}")
            return None
    
    def get_item_details(self, item_id: str, fields: Optional[str] = None) -> Optional[Dict]:
        """
        获取商品详情
        :param item_id: 商品ID
        :param fields: 需要返回的字段,多个用逗号分隔
        :return: 商品详情数据
        """
        # 获取有效的access_token
        if not self._get_access_token():
            return None
            
        url = f"{self.base_url}/item/get"
        
        # 构建请求参数
        params = {
            "item_id": item_id,
            "access_token": self.access_token
        }
        
        # 添加需要返回的字段
        if fields:
            params["fields"] = fields
            
        try:
            response = self.session.get(url, params=params, timeout=15)
            response.raise_for_status()
            result = response.json()
            
            if result.get("status") == 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:
        """格式化商品数据"""
        # 基础信息
        basic_info = {
            "item_id": item_data.get("item_id"),
            "title": item_data.get("title"),
            "desc": item_data.get("desc"),
            "main_img": item_data.get("main_img"),
            "item_imgs": item_data.get("item_imgs", {}).get("item_img", []),
            "detail_url": item_data.get("detail_url"),
            "create_time": item_data.get("create_time"),
            "update_time": item_data.get("update_time")
        }
        
        # 价格信息
        price_info = {
            "price": float(item_data.get("price", 0)),
            "original_price": float(item_data.get("original_price", 0)),
            "min_price": float(item_data.get("min_price", 0)),
            "max_price": float(item_data.get("max_price", 0)),
            "is_promotion": item_data.get("is_promotion", False),
            "promotion_price": float(item_data.get("promotion_price", 0)) if item_data.get("is_promotion") else None,
            "promotion_start_time": item_data.get("promotion_start_time"),
            "promotion_end_time": item_data.get("promotion_end_time")
        }
        
        # 库存信息
        stock_info = {
            "stock": int(item_data.get("stock", 0)),
            "sales": int(item_data.get("sales", 0)),
            "sold_num": int(item_data.get("sold_num", 0)),
            "is_stock": item_data.get("is_stock", True)
        }
        
        # 规格信息
        sku_info = {
            "has_sku": item_data.get("has_sku", False),
            "sku_list": []
        }
        
        # 处理规格数据
        if sku_info["has_sku"] and "skus" in item_data and "sku" in item_data["skus"]:
            for sku in item_data["skus"]["sku"]:
                sku_info["sku_list"].append({
                    "sku_id": sku.get("sku_id"),
                    "sku_name": sku.get("sku_name"),
                    "sku_img": sku.get("sku_img"),
                    "price": float(sku.get("price", 0)),
                    "stock": int(sku.get("stock", 0)),
                    "sales": int(sku.get("sales", 0))
                })
        
        # 店铺信息
        shop_info = {
            "shop_id": item_data.get("shop_id"),
            "shop_name": item_data.get("shop_name"),
            "shop_logo": item_data.get("shop_logo"),
            "shop_url": item_data.get("shop_url")
        }
        
        # 其他信息
        other_info = {
            "category_id": item_data.get("category_id"),
            "category_name": item_data.get("category_name"),
            "comment_count": int(item_data.get("comment_count", 0)),
            "collect_count": int(item_data.get("collect_count", 0)),
            "weight": float(item_data.get("weight", 0)),
            "volume": float(item_data.get("volume", 0)),
            "post_fee": float(item_data.get("post_fee", 0)),
            "is_free_shipping": item_data.get("is_free_shipping", False)
        }
        
        return {
            "basic_info": basic_info,
            "price_info": price_info,
            "stock_info": stock_info,
            "sku_info": sku_info,
            "shop_info": shop_info,
            "other_info": other_info,
            "raw_data": item_data  # 保留原始数据
        }


# 示例调用
if __name__ == "__main__":
    # 替换为实际的appkey和appsecret(从微店开放平台获取)
    APPKEY = "your_appkey"
    APPSECRET = "your_appsecret"
    # 替换为目标商品ID
    ITEM_ID = "123456789"
    
    # 初始化API客户端
    api = WeidianItemAPI(APPKEY, APPSECRET)
    
    # 获取商品详情(可以指定需要返回的字段,如:"item_id,title,price,stock")
    item_details = api.get_item_details(ITEM_ID)
    
    if item_details:
        print(f"=== 商品详情 ===")
        print(f"商品ID: {item_details['basic_info']['item_id']}")
        print(f"商品标题: {item_details['basic_info']['title']}")
        print(f"售价: {item_details['price_info']['price']}元")
        
        if item_details['price_info']['is_promotion']:
            print(f"促销价: {item_details['price_info']['promotion_price']}元")
            print(f"促销时间: {item_details['price_info']['promotion_start_time']} 至 {item_details['price_info']['promotion_end_time']}")
            
        print(f"库存: {item_details['stock_info']['stock']}")
        print(f"销量: {item_details['stock_info']['sales']}")
        print(f"店铺: {item_details['shop_info']['shop_name']}")
        
        if item_details['sku_info']['has_sku']:
            print(f"\n规格数量: {len(item_details['sku_info']['sku_list'])}")
            for i, sku in enumerate(item_details['sku_info']['sku_list'][:3], 1):
                print(f"  规格{i}: {sku['sku_name']} - {sku['price']}元 - 库存{sku['stock']}")


 三、接口调用注意事项


1. 调用限制与规范


-   **QPS 限制**:微店开放平台对 API 调用有 QPS 限制,默认通常为 10 次 / 秒

-   **数据缓存**:建议对商品详情数据进行缓存,减少重复调用

-   **字段筛选**:不需要全部字段时,通过`fields`参数指定需要的字段,提高响应速度

-   **合规使用**:获取的商品数据需遵守微店开放平台的使用规范,不得用于非法用途


 2. 常见错误及解决方案


| 错误码 | 说明            | 解决方案              |

| --- | ------------- | ----------------- |

| 400 | 请求参数错误        | 检查请求参数是否完整、格式是否正确 |

| 401 | 未授权或 token 无效 | 重新获取 access_token |

| 403 | 权限不足          | 检查应用是否已申请相关接口权限   |

| 404 | 商品不存在         | 确认 item_id 是否正确有效 |

| 429 | 调用频率超限        | 降低调用频率,实现请求限流     |

| 500 | 服务器内部错误       | 稍后重试,或联系微店技术支持    |


 3. 数据解析要点

-   价格相关字段可能为字符串类型,需要转换为数值类型

-   图片 URL 可能需要拼接域名才能直接访问

-   规格数据结构较为复杂,需要特殊处理

-   部分字段可能为 null 或不存在,需要做容错处理

四、应用场景与扩展建议

 典型应用场景

-   电商数据分析系统

-   多平台商品管理工具

-   竞品监控与分析平台

-   电商导购与比价应用

扩展建议

-   实现批量获取商品详情功能,支持多线程并发请求

-   添加商品价格变化监控,及时获取价格调整信息

-   结合评论接口,获取商品评价数据进行综合分析

-   开发数据导出功能,支持 CSV、Excel 等格式

-   实现商品详情页面生成功能,用于快速搭建导购平台

通过合理使用微店 `item_get` 接口,开发者可以高效获取微店商品的详细数据,为电商运营和数据分析提供有力支持。使用时需遵守微店开放平台的相关规定,确保数据使用的合法性和合规性。

群贤毕至

访客