微店的 item_get
接口是获取商品详情数据的核心接口,能够获取微店平台上商品的基础信息、价格、库存、规格、图片等详细数据。对于电商分析、竞品监控、数据挖掘等场景具有重要价值。
一、接口核心特性分析
- 接口功能与定位
-
** 核心功能 :获取微店商品的详细信息,包括基础信息、价格体系、库存状态、规格参数、图片等
- 数据特点 **:- 包含微店特有营销信息,如分销信息、限时折扣等
- 数据结构贴近微店前端展示形式
- 包含商品的多维度信息,满足不同场景需求
-** 应用场景 **: - 电商竞品分析系统
- 商品价格监控工具
- 多平台商品数据整合
- 市场趋势分析
- 认证机制
微店开放平台采用 appkey + appsecret
进行认证:
- 开发者在微店开放平台注册应用,获取
appkey
和appsecret
- 部分接口可能需要用户授权获取
access_token
- 接口调用需在请求中携带相关认证信息
- 核心参数与响应结构
请求参数
参数名 | 类型 | 是否必填 | 说明 |
---|---|---|---|
item_id |
String | 是 | 商品 ID |
appkey |
String | 是 | 应用密钥 |
timestamp |
Integer | 是 | 时间戳 |
sign |
String | 是 | 签名 |
shop_id |
String | 否 | 店铺 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 = "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" })
python
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"
python
# 初始化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("包含商品视频")
三、接口调用注意事项
- 调用限制与规范
- QPS 限制:微店开放平台对商品详情接口有 QPS 限制,通常为 10-20 次 / 秒
- 数据缓存:建议对获取的商品数据进行缓存,缓存时间建议 30 分钟到 1 小时
- 合法使用:获取的商品数据需遵守微店平台规定,不得用于非法用途
- 参数规范:确保传递正确的商品 ID 和店铺 ID,否则可能返回错误数据
- 常见错误及解决方案
错误码 | 说明 | 解决方案 |
---|---|---|
10001 | 认证失败 | 检查 appkey 和 appsecret 是否正确 |
10002 | 签名错误 | 检查签名生成算法是否正确 |
10003 | 参数错误 | 检查请求参数是否完整和正确 |
10004 | 商品不存在 | 确认 item_id 是否正确有效 |
10005 | 访问频率超限 | 降低调用频率,实现请求限流 |
10006 | 权限不足 | 检查是否有访问该接口的权限 |
- 数据解析要点
- 价格处理:注意区分原价和售价,多规格商品有最低和最高价格
- 库存计算:总库存与各规格库存可能存在差异,需根据实际需求选择
- 规格结构:规格信息可能是多层结构,需要递归解析
- 图片处理:部分图片 URL 可能需要特殊处理才能直接访问
- 时间格式:时间字段可能是时间戳或字符串,需统一转换
四、应用场景与扩展建议
典型应用场景
- 商品监控系统:实时监控商品价格、库存变化
- 竞品分析工具:对比分析同类商品的参数、价格等信息
- 多平台数据整合:将微店商品数据与其他平台数据整合分析
- 智能选品系统:基于商品数据和销售情况辅助选品决策
扩展建议
- 实现商品价格变化追踪:定期获取价格数据,记录价格波动
- 开发库存预警功能:当商品库存低于阈值时发出预警
- 构建商品相似度匹配系统:根据商品属性推荐相似商品
- 实现多店铺商品对比分析:同一商品在不同店铺的价格、销量对比
- 开发商品数据导出功能:支持将商品数据导出为 Excel、CSV 等格式 通过合理使用微店
item_get
接口,开发者可以构建功能丰富的商品分析系统,为电商运营和决策提供有力支持。使用时需遵守微店开放平台的相关规定,确保数据的合法使用。