以下是基于微店商品详情 API 接口的 Python 采集系列实现,涵盖基础详情、规格参数、库存状态、卖家信息等多维度数据采集,并以 JSON 格式返回。代码适配微店公开 API 的请求规则,包含反爬处理和数据结构化逻辑。
一、核心采集类(支持多维度数据获取)
python
运行
import requestsimport jsonimport timeimport randomfrom fake_useragent import UserAgentfrom urllib.parse import urlparse, parse_qsclass WeidianProductAPI:
def __init__(self):
# 初始化请求头(模拟移动端/PC端浏览器)
self.ua = UserAgent()
self.headers = {
'User-Agent': self.ua.random,
'Accept': 'application/json, text/plain, */*',
'Accept-Language': 'zh-CN,zh;q=0.9',
'Referer': 'https://weidian.com/',
'X-Requested-With': 'XMLHttpRequest',
}
# 微店API基础地址(基于公开接口分析)
self.base_api = "https://weidian.com/api"
def _update_headers(self):
"""动态更新请求头(防止UA被识别)"""
self.headers['User-Agent'] = self.ua.random def _get(self, api_path, params):
"""通用GET请求方法(含反爬处理)"""
try:
self._update_headers() # 每次请求更新UA
url = f"{self.base_api}/{api_path}"
# 随机延迟(1-3秒),避免高频请求
time.sleep(random.uniform(1, 3))
response = requests.get(
url=url,
params=params,
headers=self.headers,
timeout=15
)
response.raise_for_status() # 抛出HTTP错误
return response.json()
except Exception as e:
return {'error': f"请求失败:{str(e)}"}
def extract_ids_from_url(self, product_url):
"""从商品URL中提取商品ID和店铺ID"""
parsed = urlparse(product_url)
query = parse_qs(parsed.query)
item_id = query.get('itemID', [None])[0]
# 店铺ID可能在路径中(如/shop/12345 -> 12345)
shop_id = None
if 'shop' in parsed.path:
shop_id = parsed.path.split('/')[-1].strip()
return item_id, shop_id### 二、商品基础详情采集```pythonclass WeidianProductDetail(WeidianProductAPI):
def get_base_info(self, product_id, shop_id=None):
"""
获取商品基础详情(标题、价格、主图等)
:param product_id: 商品ID
:param shop_id: 店铺ID(可选)
:return: 结构化JSON数据
"""
params = {
'itemId': product_id,
'wId': shop_id or '',
'timestamp': int(time.time() * 1000),
'nonce': random.randint(100000, 999999) # 随机数防缓存
}
raw_data = self._get('item/detail', params)
if 'error' in raw_data:
return json.dumps(raw_data, indent=2, ensure_ascii=False)
if raw_data.get('code') != 0:
return json.dumps({
'error': 'API返回错误',
'code': raw_data.get('code'),
'message': raw_data.get('message')
}, indent=2, ensure_ascii=False)
data = raw_data.get('data', {})
# 结构化基础信息
base_info = {
'product_id': product_id,
'shop_id': data.get('shopId'),
'title': data.get('title'),
'price': {
'current': data.get('price'), # 现价(分转元需除以100)
'original': data.get('marketPrice'), # 原价
'unit': data.get('priceUnit', '元')
},
'sales': data.get('saleCount', 0), # 销量
'cover_image': data.get('mainPic'), # 主图URL
'image_list': data.get('pics', []), # 多图列表
'create_time': data.get('createTime'), # 上架时间
'update_time': data.get('updateTime') # 更新时间
}
return json.dumps(base_info, indent=2, ensure_ascii=False)### 三、商品规格与库存采集```pythonclass WeidianProductSpec(WeidianProductAPI):
def get_spec_and_stock(self, product_id, shop_id=None):
"""
获取商品规格(颜色、尺寸)及对应库存
:param product_id: 商品ID
:param shop_id: 店铺ID
:return: 规格与库存JSON数据
"""
params = {
'itemId': product_id,
'wId': shop_id or '',
'needStock': 1, # 强制返回库存
'timestamp': int(time.time() * 1000)
}
raw_data = self._get('item/spec', params)
if 'error' in raw_data:
return json.dumps(raw_data, indent=2, ensure_ascii=False)
if raw_data.get('code') != 0:
return json.dumps({
'error': '规格API错误',
'code': raw_data.get('code'),
'message': raw_data.get('message')
}, indent=2, ensure_ascii=False)
data = raw_data.get('data', {})
# 解析规格组(如颜色组、尺寸组)
spec_groups = []
for group in data.get('specGroups', []):
spec_groups.append({
'group_id': group.get('groupId'),
'group_name': group.get('groupName'),
'specs': [
{
'spec_id': spec.get('specId'),
'spec_name': spec.get('specName'),
'spec_image': spec.get('specPic') # 规格对应的图片(如颜色图)
} for spec in group.get('specs', [])
]
})
# 解析SKU库存(规格组合对应的库存)
sku_stock = []
for sku in data.get('skus', []):
sku_stock.append({
'sku_id': sku.get('skuId'),
'spec_ids': sku.get('specIds'), # 规格ID组合(如颜色ID+尺寸ID)
'price': sku.get('price'), # 该规格的价格
'stock': sku.get('stock'), # 库存数量
'sales': sku.get('saleCount') # 该规格的销量
})
return json.dumps({
'product_id': product_id,
'spec_groups': spec_groups,
'sku_stock': sku_stock,
'total_stock': data.get('totalStock', 0) # 总库存
}, indent=2, ensure_ascii=False)### 四、商品详情与卖家信息采集```pythonclass WeidianProductExtend(WeidianProductAPI):
def get_description(self, product_id, shop_id=None):
"""获取商品详情页描述(HTML格式)"""
params = {
'itemId': product_id,
'wId': shop_id or '',
'timestamp': int(time.time() * 1000)
}
raw_data = self._get('item/desc', params)
if 'error' in raw_data or raw_data.get('code') != 0:
return json.dumps({
'error': '详情API错误',
'message': raw_data.get('message', str(raw_data))
}, indent=2, ensure_ascii=False)
return json.dumps({
'product_id': product_id,
'description_html': raw_data.get('data', {}).get('desc', ''), # 详情HTML
'description_text': raw_data.get('data', {}).get('descText', '') # 纯文本描述
}, indent=2, ensure_ascii=False)
def get_seller_info(self, shop_id):
"""获取卖家(店铺)信息"""
if not shop_id:
return json.dumps({'error': '店铺ID不能为空'}, indent=2)
params = {
'wId': shop_id,
'timestamp': int(time.time() * 1000)
}
raw_data = self._get('shop/base', params)
if 'error' in raw_data or raw_data.get('code') != 0:
return json.dumps({
'error': '店铺API错误',
'message': raw_data.get('message', str(raw_data))
}, indent=2, ensure_ascii=False)
data = raw_data.get('data', {})
return json.dumps({
'shop_id': shop_id,
'shop_name': data.get('shopName'),
'logo': data.get('logo'),
'level': data.get('level', 0), # 店铺等级
'fans_count': data.get('fansCount', 0), # 粉丝数
'好评率': data.get('positiveRate', 0), # 好评率(%)
'open_time': data.get('openTime') # 开店时间
}, indent=2, ensure_ascii=False)### 五、使用示例```pythonif __name__ == "__main__":
# 初始化采集器
detail = WeidianProductDetail()
spec = WeidianProductSpec()
extend = WeidianProductExtend()
# 从商品URL提取ID(示例URL)
product_url = "https://weidian.com/item.html?itemID=1234567890"
product_id, shop_id = detail.extract_ids_from_url(product_url)
print(f"提取到商品ID:{product_id},店铺ID:{shop_id}\n")
if product_id:
# 1. 获取基础详情
print("===== 商品基础详情 =====")
print(detail.get_base_info(product_id, shop_id))
# 2. 获取规格与库存
print("\n===== 商品规格与库存 =====")
print(spec.get_spec_and_stock(product_id, shop_id))
# 3. 获取商品详情描述
print("\n===== 商品详情描述 =====")
print(extend.get_description(product_id, shop_id))
# 4. 获取店铺信息(需店铺ID)
if shop_id:
print("\n===== 店铺信息 =====")
print(extend.get_seller_info(shop_id))关键说明
- 依赖安装:bash
pip install requests fake_useragent
- API 接口说明:
基础详情:
/item/detail→ 标题、价格、销量等核心信息规格库存:
/item/spec→ 颜色 / 尺寸规格及对应 SKU 库存详情描述:
/item/desc→ 商品详情页 HTML / 纯文本店铺信息:
/shop/base→ 卖家店铺等级、粉丝数等- 反爬与稳定性:
动态更新 User-Agent,添加随机请求延迟
自动从 URL 提取商品 ID 和店铺 ID,减少手动输入
完善的错误处理,返回结构化错误信息
- 字段适配:
价格字段可能以 “分” 为单位(需除以 100 转换为元)
详情描述包含 HTML 标签,可根据需求用
BeautifulSoup清洗规格 ID 组合需与 SKU 对应(如颜色 ID + 尺寸 ID 确定唯一 SKU)
- 注意事项:
微店 API 可能随版本更新调整,若字段不符,需打印
raw_data查看最新结构高频调用可能被限制,建议添加代理 IP 池(通过
proxies参数配置)商业使用需遵守微店用户协议,禁止滥用数据
通过以上系列接口,可全面采集微店商品的多维数据,适用于电商分析、竞品监控等场景。如需扩展,可基于此框架添加评论采集(
/item/review接口)等功能。