Shopee 的 item_search_shop 接口是获取指定店铺所有商品信息的核心接口,能够返回店铺内的商品列表、基本信息、价格、库存、销量等关键数据。对于店铺运营分析、竞品监控、市场调研等场景具有重要价值,尤其在跨境电商环境中,能帮助卖家了解竞争对手的商品布局和定价策略。
一、接口核心特性分析
1. 接口功能与定位
2. 认证机制
3. 核心参数与响应结构
请求参数
响应核心字段
二、Python 脚本实现
import requests
import time
import json
import logging
import hashlib
import hmac
import os
import re
from typing import Dict, Optional, List, Tuple
from requests.exceptions import RequestException
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from collections import defaultdict
# 配置日志
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s - %(levelname)s - %(message)s"
)
class ShopeeItemSearchShopAPI:
def __init__(self, partner_id: int, partner_key: str, region: str = "sg"):
"""
初始化Shopee店铺商品接口客户端
:param partner_id: 合作伙伴ID
:param partner_key: 合作伙伴密钥
:param region: 地区代码,如sg(新加坡), my(马来西亚), th(泰国), tw(台湾)
"""
self.partner_id = partner_id
self.partner_key = partner_key.encode('utf-8') # 用于签名的密钥
self.region = region
self.base_url = self._get_base_url()
self.access_token = None
self.session = requests.Session()
self.session.headers.update({
"Content-Type": "application/json",
"Accept": "application/json",
"User-Agent": "ShopeeAPI/1.0.0 (Python)"
})
def _get_base_url(self) -> str:
"""根据地区获取基础URL"""
region_map = {
"sg": "https://partner.shopeemobile.com", # 新加坡
"my": "https://partner.shopeemobile.com", # 马来西亚
"th": "https://partner.shopeemobile.com", # 泰国
"tw": "https://partner.shopee.tw", # 台湾
"id": "https://partner.shopeemobile.com", # 印度尼西亚
"vn": "https://partner.shopeemobile.com", # 越南
"ph": "https://partner.shopeemobile.com" # 菲律宾
}
return region_map.get(self.region, region_map["sg"])
def _generate_signature(self, path: str, timestamp: int, access_token: str = "") -> str:
"""生成请求签名"""
# 构建待签名字符串
base_string = f"{self.partner_id}{path}{timestamp}"
if access_token:
base_string += access_token
# 使用HMAC-SHA256计算签名
signature = hmac.new(
self.partner_key,
base_string.encode('utf-8'),
hashlib.sha256
).hexdigest()
return signature
def set_access_token(self, access_token: str) -> None:
"""设置访问令牌"""
self.access_token = access_token
def search_shop_items(self,
shopid: int,
page: int = 1,
page_size: int = 20,
category_id: Optional[int] = None,
sort_by: str = "ctime",
order_by: str = "desc",
price_min: Optional[float] = None,
price_max: Optional[float] = None) -> Optional[Dict]:
"""
获取店铺商品列表
:param shopid: 店铺ID
:param page: 页码
:param page_size: 每页条数
:param category_id: 店铺内分类ID
:param sort_by: 排序方式:ctime(上架时间)、price(价格)、sales(销量)
:param order_by: 排序顺序:asc(升序)、desc(降序)
:param price_min: 最低价格筛选
:param price_max: 最高价格筛选
:return: 商品列表数据
"""
# 验证参数
if page_size < 1 or page_size > 100:
logging.error(f"每页条数必须在1-100之间,当前为: {page_size}")
return None
valid_sort_by = ["ctime", "price", "sales"]
if sort_by not in valid_sort_by:
logging.error(f"无效的排序方式: {sort_by},支持: {valid_sort_by}")
return None
valid_order_by = ["asc", "desc"]
if order_by not in valid_order_by:
logging.error(f"无效的排序顺序: {order_by},支持: {valid_order_by}")
return None
# 检查access_token
if not self.access_token:
logging.error("请先设置access_token")
return None
# 构建请求路径和参数
path = "/api/v2/item/search_shop"
timestamp = int(time.time() * 1000) # 毫秒时间戳
signature = self._generate_signature(path, timestamp, self.access_token)
params = {
"partner_id": self.partner_id,
"shopid": shopid,
"page": page,
"page_size": page_size,
"sort_by": sort_by,
"order_by": order_by,
"timestamp": timestamp,
"access_token": self.access_token,
"sign": signature
}
# 添加可选参数
if category_id is not None:
params["category_id"] = category_id
if price_min is not None:
params["price_min"] = price_min
if price_max is not None:
params["price_max"] = price_max
try:
url = f"{self.base_url}{path}"
response = self.session.get(url, params=params, timeout=15)
response.raise_for_status()
result = response.json()
# 检查响应状态
if result.get("error") != 0:
logging.error(f"获取店铺商品失败: {result.get('message', '未知错误')} (错误码: {result.get('error')})")
return None
# 格式化商品数据
return self._format_item_data(result, shopid)
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, shopid: int) -> Dict:
"""格式化商品数据"""
# 分页信息
pagination = {
"total_items": item_data.get("data", {}).get("total_count", 0),
"total_pages": (item_data.get("data", {}).get("total_count", 0) +
item_data.get("data", {}).get("page_size", 20) - 1) //
item_data.get("data", {}).get("page_size", 20),
"current_page": item_data.get("data", {}).get("page", 1),
"page_size": item_data.get("data", {}).get("page_size", 20)
}
# 店铺信息
shop_info = {
"shopid": shopid,
"shop_name": item_data.get("data", {}).get("shop_name", ""),
"rating": item_data.get("data", {}).get("shop_rating", 0),
"follower_count": item_data.get("data", {}).get("follower_count", 0),
"item_count": item_data.get("data", {}).get("total_count", 0)
}
# 店铺分类信息
categories = []
for cat in item_data.get("data", {}).get("categories", []):
categories.append({
"category_id": cat.get("category_id"),
"name": cat.get("name"),
"item_count": cat.get("item_count", 0)
})
# 格式化商品列表
items = []
for item in item_data.get("data", {}).get("items", []):
# 处理价格信息(Shopee返回的价格单位为分,需转换为元)
price = item.get("price", 0) / 100000
original_price = item.get("original_price", 0) / 100000
discount = 0
if original_price > 0 and price < original_price:
discount = round((1 - price / original_price) * 100, 1)
# 处理库存和销量
stock = item.get("stock", 0)
sold = item.get("sold", 0)
# 处理变体信息
variants = []
if item.get("variants"):
for variant in item.get("variants"):
variants.append({
"variant_id": variant.get("variant_id"),
"attributes": [{"name": attr.get("name"), "value": attr.get("value")}
for attr in variant.get("attributes", [])],
"price": variant.get("price", 0) / 100000,
"stock": variant.get("stock", 0),
"image_url": variant.get("image_url", "")
})
# 处理分类信息
category_info = {
"category_id": item.get("category_id"),
"category_name": self._get_category_name(categories, item.get("category_id"))
}
items.append({
"item_id": item.get("item_id"),
"shopid": shopid,
"name": item.get("name", ""),
"description": item.get("description", "")[:200], # 截取部分描述
"image_url": item.get("image", ""),
"images": item.get("images", []),
"price": price,
"original_price": original_price,
"discount": discount,
"currency": item.get("currency", "SGD"),
"stock": stock,
"sold": sold,
"rating": item.get("item_rating", {}).get("rating_star", 0),
"rating_count": item.get("item_rating", {}).get("rating_count", 0),
"categories": category_info,
"variants": variants,
"is_on_sale": item.get("is_on_sale", False),
"is_promotion": item.get("is_promotion", False),
"created_time": item.get("ctime", 0),
"updated_time": item.get("mtime", 0),
"url": f"https://shopee.{self.region}/product/{shopid}/{item.get('item_id')}"
})
return {
"pagination": pagination,
"shop_info": shop_info,
"categories": categories,
"items": items,
"raw_data": item_data # 保留原始数据
}
def _get_category_name(self, categories: List[Dict], category_id: int) -> str:
"""根据分类ID获取分类名称"""
for cat in categories:
if cat["category_id"] == category_id:
return cat["name"]
return ""
def get_all_shop_items(self, shopid: int, max_pages: int = 20, **kwargs) -> Dict:
"""
获取店铺的所有商品
:param shopid: 店铺ID
:param max_pages: 最大页数限制
:return: 包含所有商品的完整数据
"""
all_items = []
page = 1
shop_info = None
categories = None
while page <= max_pages:
logging.info(f"获取店铺商品第 {page} 页")
result = self.search_shop_items(
shopid=shopid,
page=page,
page_size=100, # 使用最大页大小
**kwargs
)
if not result or not result["items"]:
break
# 保存店铺信息和分类信息
if not shop_info:
shop_info = result["shop_info"]
if not categories:
categories = result["categories"]
all_items.extend(result["items"])
# 检查是否已到最后一页
if page >= result["pagination"]["total_pages"]:
break
page += 1
# 控制请求频率,遵守Shopee API的QPS限制
time.sleep(0.1)
logging.info(f"共获取到 {len(all_items)} 件商品")
return {
"shop_info": shop_info,
"categories": categories,
"total_items": len(all_items),
"items": all_items
}
def analyze_shop_items(self, shop_data: Dict) -> Dict:
"""分析店铺商品数据"""
if not shop_data or not shop_data["items"]:
return {}
items = shop_data["items"]
total = len(items)
# 价格分析
price_analysis = self._analyze_prices(items)
# 分类分析
category_analysis = self._analyze_categories(items, shop_data["categories"])
# 销售分析
sales_analysis = self._analyze_sales(items)
# 变体分析
variant_analysis = self._analyze_variants(items)
# 折扣分析
discount_analysis = self._analyze_discounts(items)
# 评分分析
rating_analysis = self._analyze_ratings(items)
# 识别热门商品
top_items = self._identify_top_items(items)
return {
"shop_summary": shop_data["shop_info"],
"total_items": total,
"price_analysis": price_analysis,
"category_analysis": category_analysis,
"sales_analysis": sales_analysis,
"variant_analysis": variant_analysis,
"discount_analysis": discount_analysis,
"rating_analysis": rating_analysis,
"top_items": top_items
}
def _analyze_prices(self, items: List[Dict]) -> Dict:
"""分析商品价格分布"""
prices = [item["price"] for item in items]
if not prices:
return {}
min_price = min(prices)
max_price = max(prices)
avg_price = round(sum(prices) / len(prices), 2)
median_price = self._calculate_median(prices)
# 价格区间分布
price_ranges = self._get_price_ranges(min_price, max_price)
range_counts = defaultdict(int)
for price in prices:
for r in price_ranges:
if r[0] <= price < r[1]:
range_counts[f"{r[0]}-{r[1]}"] += 1
break
else:
range_counts[f"{price_ranges[-1][1]}+"] += 1
# 价格与销量相关性
price_sales_correlation = self._calculate_correlation(
[item["price"] for item in items],
[item["sold"] for item in items]
)
return {
"min_price": min_price,
"max_price": max_price,
"avg_price": avg_price,
"median_price": median_price,
"range_distribution": dict(range_counts),
"price_sales_correlation": round(price_sales_correlation, 4)
}
def _analyze_categories(self, items: List[Dict], categories: List[Dict]) -> Dict:
"""分析商品分类分布"""
category_counts = defaultdict(int)
category_sales = defaultdict(int)
category_avg_price = defaultdict(list)
for item in items:
cat_id = item["categories"]["category_id"]
cat_name = item["categories"]["category_name"] or f"分类{cat_id}"
category_counts[cat_name] += 1
category_sales[cat_name] += item["sold"]
category_avg_price[cat_name].append(item["price"])
# 计算每个分类的平均价格
category_avg_price = {k: round(sum(v)/len(v), 2) for k, v in category_avg_price.items()}
# 计算每个分类的商品占比
total = len(items)
category_ratio = {k: round(v/total*100, 1) for k, v in category_counts.items()}
# 按商品数量排序
sorted_categories = sorted(category_counts.items(), key=lambda x: x[1], reverse=True)
return {
"total_categories": len(category_counts),
"distribution": dict(category_counts),
"ratio": category_ratio,
"sales_by_category": dict(category_sales),
"avg_price_by_category": category_avg_price,
"top_categories": sorted_categories[:5]
}
def _analyze_sales(self, items: List[Dict]) -> Dict:
"""分析商品销售情况"""
total_sold = sum(item["sold"] for item in items)
avg_sold = round(total_sold / len(items), 1) if items else 0
# 销量分布
sold_ranges = [(0, 0), (1, 10), (11, 50), (51, 100), (101, 500), (501, float('inf'))]
sold_distribution = defaultdict(int)
for item in items:
sold = item["sold"]
for r in sold_ranges:
if r[0] <= sold <= r[1]:
sold_distribution[f"{r[0]}-{r[1] if r[1] != float('inf') else '+'}"] += 1
break
# 计算有销量的商品比例
has_sales_ratio = round(sum(1 for item in items if item["sold"] > 0) / len(items) * 100, 1)
return {
"total_sold": total_sold,
"avg_sold_per_item": avg_sold,
"distribution": dict(sold_distribution),
"has_sales_ratio": has_sales_ratio
}
def _analyze_variants(self, items: List[Dict]) -> Dict:
"""分析商品变体情况"""
variant_counts = [len(item["variants"]) for item in items]
total_variants = sum(variant_counts)
# 变体数量分布
variant_distribution = defaultdict(int)
for count in variant_counts:
if count == 0:
variant_distribution["无变体"] += 1
elif count == 1:
variant_distribution["1个变体"] += 1
elif count <= 5:
variant_distribution["2-5个变体"] += 1
elif count <= 10:
variant_distribution["6-10个变体"] += 1
else:
variant_distribution["10+个变体"] += 1
# 有变体的商品比例
has_variant_ratio = round(sum(1 for item in items if item["variants"]) / len(items) * 100, 1)
return {
"total_variants": total_variants,
"avg_variants_per_item": round(total_variants / len(items), 1) if items else 0,
"distribution": dict(variant_distribution),
"has_variant_ratio": has_variant_ratio
}
def _analyze_discounts(self, items: List[Dict]) -> Dict:
"""分析商品折扣情况"""
discounted_items = [item for item in items if item["discount"] > 0]
discounted_ratio = round(len(discounted_items) / len(items) * 100, 1) if items else 0
# 折扣力度分布
discount_distribution = defaultdict(int)
for item in discounted_items:
discount = item["discount"]
if discount <= 10:
discount_distribution["0-10%"] += 1
elif discount <= 20:
discount_distribution["11-20%"] += 1
elif discount <= 30:
discount_distribution["21-30%"] += 1
elif discount <= 50:
discount_distribution["31-50%"] += 1
else:
discount_distribution["50%+"] += 1
# 平均折扣力度
avg_discount = round(sum(item["discount"] for item in discounted_items) / len(discounted_items), 1) if discounted_items else 0
# 促销商品比例
promotion_ratio = round(sum(1 for item in items if item["is_promotion"]) / len(items) * 100, 1) if items else 0
return {
"discounted_ratio": discounted_ratio,
"avg_discount": avg_discount,
"discount_distribution": dict(discount_distribution),
"promotion_ratio": promotion_ratio
}
def _analyze_ratings(self, items: List[Dict]) -> Dict:
"""分析商品评分情况"""
rated_items = [item for item in items if item["rating_count"] > 0]
rated_ratio = round(len(rated_items) / len(items) * 100, 1) if items else 0
# 评分分布
rating_distribution = defaultdict(int)
for item in rated_items:
rating = round(item["rating"])
rating_distribution[f"{rating}星"] += 1
# 平均评分
avg_rating = round(sum(item["rating"] for item in rated_items) / len(rated_items), 1) if rated_items else 0
# 评分与销量相关性
rating_sales_correlation = 0
if len(rated_items) >= 2:
rating_sales_correlation = self._calculate_correlation(
[item["rating"] for item in rated_items],
[item["sold"] for item in rated_items]
)
return {
"rated_ratio": rated_ratio,
"avg_rating": avg_rating,
"distribution": dict(rating_distribution),
"rating_sales_correlation": round(rating_sales_correlation, 4)
}
def _identify_top_items(self, items: List[Dict]) -> Dict:
"""识别各类热门商品"""
# 按销量排序
top_sales = sorted(items, key=lambda x: x["sold"], reverse=True)[:10]
# 按评分排序(至少有10条评价)
rated_items = [item for item in items if item["rating_count"] >= 10]
top_rated = sorted(rated_items, key=lambda x: x["rating"], reverse=True)[:10]
# 按折扣力度排序
discounted_items = [item for item in items if item["discount"] > 0]
top_discounts = sorted(discounted_items, key=lambda x: x["discount"], reverse=True)[:10]
# 最新上架
top_newest = sorted(items, key=lambda x: x["created_time"], reverse=True)[:10]
return {
"top_sales": top_sales,
"top_rated": top_rated,
"top_discounts": top_discounts,
"top_newest": top_newest
}
# 工具方法
def _get_price_ranges(self, min_price: float, max_price: float) -> List[Tuple[float, float]]:
"""生成合理的价格区间"""
if min_price >= max_price:
return [(min_price - 1, max_price + 1)]
# 计算区间数量,最多8个区间
range_count = min(8, int(max_price - min_price) // 10 + 1)
step = (max_price - min_price) / range_count
ranges = []
for i in range(range_count):
start = min_price + i * step
end = min_price + (i + 1) * step
ranges.append((round(start, 1), round(end, 1)))
return ranges
def _calculate_median(self, data: List[float]) -> float:
"""计算中位数"""
sorted_data = sorted(data)
n = len(sorted_data)
if n % 2 == 1:
return round(sorted_data[n//2], 2)
else:
return round((sorted_data[n//2 - 1] + sorted_data[n//2]) / 2, 2)
def _calculate_correlation(self, x: List[float], y: List[float]) -> float:
"""计算皮尔逊相关系数"""
if len(x) != len(y) or len(x) < 2:
return 0.0
n = len(x)
sum_x = sum(x)
sum_y = sum(y)
sum_xy = sum(xi * yi for xi, yi in zip(x, y))
sum_x2 = sum(xi **2 for xi in x)
sum_y2 = sum(yi** 2 for yi in y)
numerator = n * sum_xy - sum_x * sum_y
denominator = ((n * sum_x2 - sum_x **2) * (n * sum_y2 - sum_y** 2)) **0.5
return numerator / denominator if denominator != 0 else 0.0
def visualize_analysis(self, analysis: Dict, output_dir: str = "shop_analysis") -> None:
"""可视化分析结果"""
# 创建输出目录
if not os.path.exists(output_dir):
os.makedirs(output_dir)
# 设置中文显示
plt.rcParams["font.family"] = ["SimHei", "WenQuanYi Micro Hei", "Heiti TC"]
plt.rcParams["axes.unicode_minus"] = False
# 1. 价格分布直方图
plt.figure(figsize=(10, 6))
if analysis["price_analysis"]["range_distribution"]:
ranges = list(analysis["price_analysis"]["range_distribution"].keys())
counts = list(analysis["price_analysis"]["range_distribution"].values())
plt.bar(ranges, counts, color='skyblue')
plt.title(f"商品价格区间分布 (平均价格: {analysis['price_analysis']['avg_price']}{analysis['shop_summary'].get('currency', 'SGD')})")
plt.xlabel(f"价格区间 ({analysis['shop_summary'].get('currency', 'SGD')})")
plt.ylabel("商品数量")
plt.xticks(rotation=45)
plt.tight_layout()
plt.savefig(f"{output_dir}/price_distribution.png")
plt.close()
# 2. 分类分布饼图
plt.figure(figsize=(10, 6))
top_cats = analysis["category_analysis"]["top_categories"]
if top_cats:
labels = [cat[0] for cat in top_cats]
sizes = [cat[1] for cat in top_cats]
# 其他分类合并
if len(analysis["category_analysis"]["distribution"]) > 5:
other_count = sum(analysis["category_analysis"]["distribution"].values()) - sum(sizes)
labels.append("其他")
sizes.append(other_count)
plt.pie(sizes, labels=labels, autopct='%1.1f%%', startangle=90)
plt.title("商品分类分布")
plt.axis('equal')
plt.tight_layout()
plt.savefig(f"{output_dir}/category_distribution.png")
plt.close()
# 3. 销量分布条形图
plt.figure(figsize=(10, 6))
sales_dist = analysis["sales_analysis"]["distribution"]
if sales_dist:
labels = list(sales_dist.keys())
counts = list(sales_dist.values())
plt.bar(labels, counts, color='#4CAF50')
plt.title("商品销量区间分布")
plt.xlabel("销量区间")
plt.ylabel("商品数量")
plt.xticks(rotation=45)
plt.tight_layout()
plt.savefig(f"{output_dir}/sales_distribution.png")
plt.close()
# 4. 折扣分布条形图
plt.figure(figsize=(10, 6))
discount_dist = analysis["discount_analysis"]["discount_distribution"]
if discount_dist:
labels = list(discount_dist.keys())
counts = list(discount_dist.values())
plt.bar(labels, counts, color='#FF9800')
plt.title("商品折扣力度分布")
plt.xlabel("折扣区间")
plt.ylabel("商品数量")
plt.xticks(rotation=45)
plt.tight_layout()
plt.savefig(f"{output_dir}/discount_distribution.png")
plt.close()
# 5. 评分分布条形图
plt.figure(figsize=(10, 6))
rating_dist = analysis["rating_analysis"]["distribution"]
if rating_dist:
# 确保按星级排序
sorted_labels = sorted(rating_dist.keys(), key=lambda x: int(x[0]))
sorted_counts = [rating_dist[label] for label in sorted_labels]
plt.bar(sorted_labels, sorted_counts, color='#2196F3')
plt.title(f"商品评分分布 (平均评分: {analysis['rating_analysis']['avg_rating']})")
plt.xlabel("评分星级")
plt.ylabel("商品数量")
plt.tight_layout()
plt.savefig(f"{output_dir}/rating_distribution.png")
plt.close()
logging.info(f"分析图表已保存至 {output_dir} 目录")
def export_to_excel(self, shop_data: Dict, output_file: str = "shop_items_analysis.xlsx") -> None:
"""将店铺商品数据导出到Excel"""
if not shop_data or not shop_data["items"]:
logging.warning("没有可导出的商品数据")
return
# 准备数据
items_data = []
for item in shop_data["items"]:
items_data.append({
"商品ID": item["item_id"],
"商品名称": item["name"],
"分类": item["categories"]["category_name"],
"价格": item["price"],
"原价": item["original_price"],
"折扣(%)": item["discount"],
"销量": item["sold"],
"库存": item["stock"],
"评分": item["rating"],
"评价数": item["rating_count"],
"变体数量": len(item["variants"]),
"是否促销": "是" if item["is_promotion"] else "否",
"商品链接": item["url"]
})
# 创建DataFrame
df = pd.DataFrame(items_data)
# 创建Excel写入器
with pd.ExcelWriter(output_file, engine='openpyxl') as writer:
# 商品列表
df.to_excel(writer, sheet_name='商品列表', index=False)
# 分类统计
category_stats = []
for cat_name, count in shop_data.get("category_analysis", {}).get("distribution", {}).items():
category_stats.append({
"分类名称": cat_name,
"商品数量": count,
"占比(%)": shop_data.get("category_analysis", {}).get("ratio", {}).get(cat_name, 0),
"总销量": shop_data.get("category_analysis", {}).get("sales_by_category", {}).get(cat_name, 0),
"平均价格": shop_data.get("category_analysis", {}).get("avg_price_by_category", {}).get(cat_name, 0)
})
pd.DataFrame(category_stats).to_excel(writer, sheet_name='分类统计', index=False)
# 热门商品
top_sales = []
for i, item in enumerate(shop_data.get("top_items", {}).get("top_sales", [])[:10], 1):
top_sales.append({
"排名": i,
"商品名称": item["name"],
"销量": item["sold"],
"价格": item["price"],
"评分": item["rating"]
})
pd.DataFrame(top_sales).to_excel(writer, sheet_name='热销商品', index=False)
logging.info(f"商品数据已导出至 {output_file}")
# 示例调用
if __name__ == "__main__":
# 替换为实际的参数(从Shopee开放平台获取)
PARTNER_ID = 123456 # 合作伙伴ID
PARTNER_KEY = "your_partner_key" # 合作伙伴密钥
ACCESS_TOKEN = "your_access_token" # 访问令牌
SHOPID = 987654 # 目标店铺ID
REGION = "sg" # 地区代码
# 初始化API客户端
api = ShopeeItemSearchShopAPI(PARTNER_ID, PARTNER_KEY, region=REGION)
api.set_access_token(ACCESS_TOKEN)
# 获取店铺所有商品
shop_data = api.get_all_shop_items(
shopid=SHOPID,
max_pages=5, # 最多获取5页
# category_id=123, # 可选:指定分类ID
# sort_by="sales", # 按销量排序
# order_by="desc"
)
if shop_data and shop_data["items"]:
# 分析店铺商品数据
analysis = api.analyze_shop_items(shop_data)
print(f"=== Shopee店铺商品分析报告 (店铺ID: {SHOPID}) ===")
print(f"店铺名称: {analysis['shop_summary']['shop_name']}")
print(f"店铺评分: {analysis['shop_summary']['rating']}星")
print(f"粉丝数量: {analysis['shop_summary']['follower_count']}")
print(f"商品总数: {analysis['total_items']}件")
# 价格分析
print("\n价格分析:")
print(f" 价格范围: {analysis['price_analysis']['min_price']}-{analysis['price_analysis']['max_price']}{analysis['shop_summary'].get('currency', 'SGD')}")
print(f" 平均价格: {analysis['price_analysis']['avg_price']}{analysis['shop_summary'].get('currency', 'SGD')}")
print(f" 价格与销量相关性: {analysis['price_analysis']['price_sales_correlation']}")
# 分类分析
print("\n分类分析:")
print(f" 分类数量: {analysis['category_analysis']['total_categories']}个")
print(" 商品最多的3个分类:")
for i, (cat, count) in enumerate(analysis['category_analysis']['top_categories'][:3], 1):
ratio = analysis['category_analysis']['ratio'].get(cat, 0)
print(f" {i}. {cat}: {count}件 ({ratio}%)")
# 销售分析
print("\n销售分析:")
print(f" 总销量: {analysis['sales_analysis']['total_sold']}件")
print(f" 平均每件商品销量: {analysis['sales_analysis']['avg_sold_per_item']}件")
print(f" 有销量的商品占比: {analysis['sales_analysis']['has_sales_ratio']}%")
# 折扣分析
print("\n折扣分析:")
print(f" 有折扣的商品占比: {analysis['discount_analysis']['discounted_ratio']}%")
print(f" 平均折扣力度: {analysis['discount_analysis']['avg_discount']}%")
print(f" 促销商品占比: {analysis['discount_analysis']['promotion_ratio']}%")
# 评分分析
print("\n评分分析:")
print(f" 有评价的商品占比: {analysis['rating_analysis']['rated_ratio']}%")
print(f" 平均评分: {analysis['rating_analysis']['avg_rating']}星")
# 变体分析
print("\n变体分析:")
print(f" 有变体的商品占比: {analysis['variant_analysis']['has_variant_ratio']}%")
print(f" 平均每件商品变体数: {analysis['variant_analysis']['avg_variants_per_item']}个")
# 热门商品
print("\n热销商品TOP3:")
for i, item in enumerate(analysis['top_items']['top_sales'][:3], 1):
print(f" {i}. {item['name'][:30]}...")
print(f" 价格: {item['price']}{analysis['shop_summary'].get('currency', 'SGD')}")
print(f" 销量: {item['sold']}件")
print(f" 评分: {item['rating']}星")
# 生成可视化图表
api.visualize_analysis(analysis)
# 导出数据到Excel
api.export_to_excel(analysis)