唯品会的 item_get 接口是用于获取唯品会平台商品详情的核心接口,能够获取商品的完整信息,包括基础属性、价格、库存、规格、促销活动、店铺信息等。该接口对于电商数据分析、竞品监控、多平台商品对比等场景具有重要价值。
一、接口核心特性分析
1. 接口功能与定位
2. 认证机制
3. 核心参数与响应结构
请求参数
响应核心字段
二、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 VipItemAPI:
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.vip.com"
self.access_token = None
self.token_expires_at = 0 # token过期时间戳
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 _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}/oauth2/token"
params = {
"grant_type": "client_credentials",
"client_id": self.appkey,
"client_secret": self.appsecret
}
try:
response = self.session.get(url, params=params, timeout=10)
response.raise_for_status()
result = response.json()
if "access_token" in result:
self.access_token = result["access_token"]
self.token_expires_at = time.time() + result.get("expires_in", 3600)
return self.access_token
else:
logging.error(f"获取access_token失败: {result.get('error_description', '未知错误')}")
return None
except RequestException as e:
logging.error(f"获取access_token请求异常: {str(e)}")
return None
def get_item_details(self, goods_id: str, fields: Optional[str] = None) -> Optional[Dict]:
"""
获取商品详情
:param goods_id: 商品ID
:param fields: 需要返回的字段,多个用逗号分隔
:return: 商品详情数据
"""
# 获取有效的access_token
if not self._get_access_token():
return None
url = f"{self.base_url}/item/get"
# 构建请求参数
params = {
"goods_id": goods_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("code") == 0:
# 格式化商品数据
return self._format_item_data(result.get("data", {}))
else:
logging.error(f"获取商品详情失败: {result.get('message', '未知错误')} (错误码: {result.get('code')})")
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 = {
"goods_id": item_data.get("goods_id"),
"title": item_data.get("title"),
"sub_title": item_data.get("sub_title"),
"brand": {
"brand_id": item_data.get("brand_id"),
"brand_name": item_data.get("brand_name")
},
"main_images": item_data.get("main_images", []),
"detail_images": item_data.get("detail_images", []),
"detail_url": item_data.get("detail_url"),
"category": {
"category_id": item_data.get("category_id"),
"category_name": item_data.get("category_name"),
"parent_category_id": item_data.get("parent_category_id"),
"parent_category_name": item_data.get("parent_category_name")
}
}
# 价格信息
price_info = {
"original_price": float(item_data.get("original_price", 0)),
"vip_price": float(item_data.get("vip_price", 0)),
"discount": float(item_data.get("discount", 0)),
"member_price": float(item_data.get("member_price", 0)) if item_data.get("has_member_price") else None,
"has_member_price": item_data.get("has_member_price", False)
}
# 库存信息
stock_info = {
"total_stock": int(item_data.get("total_stock", 0)),
"sales_count": int(item_data.get("sales_count", 0)),
"is_in_stock": item_data.get("is_in_stock", False),
"limit_buy_count": int(item_data.get("limit_buy_count", 0)) # 限购数量
}
# 规格信息
sku_info = {
"has_sku": item_data.get("has_sku", False),
"sku_list": []
}
# 处理规格数据
if sku_info["has_sku"] and "skus" in item_data:
for sku in item_data["skus"]:
sku_info["sku_list"].append({
"sku_id": sku.get("sku_id"),
"specs": sku.get("specs", []), # 规格组合,如["红色", "XL"]
"price": float(sku.get("price", 0)),
"original_price": float(sku.get("original_price", 0)),
"stock": int(sku.get("stock", 0)),
"image": sku.get("image")
})
# 促销信息
promotion_info = {
"promotions": item_data.get("promotions", []), # 促销活动列表
"start_time": item_data.get("promotion_start_time"),
"end_time": item_data.get("promotion_end_time"),
"is_promotion": item_data.get("is_promotion", False)
}
# 店铺信息
shop_info = {
"shop_id": item_data.get("shop_id"),
"shop_name": item_data.get("shop_name"),
"shop_type": item_data.get("shop_type"),
"score": float(item_data.get("shop_score", 0)),
"sales_volume": item_data.get("shop_sales_volume")
}
# 物流信息
logistics_info = {
"freight": float(item_data.get("freight", 0)),
"freight_free_threshold": float(item_data.get("freight_free_threshold", 0)),
"delivery_place": item_data.get("delivery_place"),
"shipping_methods": item_data.get("shipping_methods", [])
}
return {
"basic_info": basic_info,
"price_info": price_info,
"stock_info": stock_info,
"sku_info": sku_info,
"promotion_info": promotion_info,
"shop_info": shop_info,
"logistics_info": logistics_info,
"raw_data": item_data # 保留原始数据
}
# 示例调用
if __name__ == "__main__":
# 替换为实际的appkey和appsecret(从唯品会开放平台获取)
APPKEY = "your_appkey"
APPSECRET = "your_appsecret"
# 替换为目标商品ID
GOODS_ID = "12345678"
# 初始化API客户端
api = VipItemAPI(APPKEY, APPSECRET)
# 获取商品详情(可以指定需要返回的字段,如:"goods_id,title,vip_price,stock")
item_details = api.get_item_details(GOODS_ID)
if item_details:
print(f"=== 商品详情 ===")
print(f"商品ID: {item_details['basic_info']['goods_id']}")
print(f"商品标题: {item_details['basic_info']['title']}")
print(f"品牌: {item_details['basic_info']['brand']['brand_name']}")
print(f"原价: {item_details['price_info']['original_price']}元")
print(f"唯品会价: {item_details['price_info']['vip_price']}元")
print(f"折扣: {item_details['price_info']['discount']}折")
if item_details['price_info']['has_member_price']:
print(f"会员价: {item_details['price_info']['member_price']}元")
print(f"库存: {item_details['stock_info']['total_stock']}")
print(f"销量: {item_details['stock_info']['sales_count']}")
print(f"店铺: {item_details['shop_info']['shop_name']}")
if item_details['promotion_info']['is_promotion']:
print(f"\n促销活动:")
for promo in item_details['promotion_info']['promotions'][:2]:
print(f"- {promo.get('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}: {','.join(sku['specs'])} - {sku['price']}元 - 库存{sku['stock']}")