微店的 item_get 接口是获取商品详情数据的核心接口,能够获取微店平台上商品的基础信息、价格、库存、规格、图片等详细数据。对于电商分析、竞品监控、数据挖掘等场景具有重要价值。
一、接口核心特性分析
1. 接口功能与定位
2. 认证机制
3. 核心参数与响应结构
请求参数
响应核心字段
二、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("包含商品视频")