×

python采集微店商品详情API接口系列,json数据返回

知名用户18007905473 知名用户18007905473 发表于2025-10-30 15:16:26 浏览28 评论0

抢沙发发表评论

以下是基于微店商品详情 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))

关键说明

  1. 依赖安装
    bash
    pip install requests fake_useragent
  2. API 接口说明
    • 基础详情:/item/detail → 标题、价格、销量等核心信息

    • 规格库存:/item/spec → 颜色 / 尺寸规格及对应 SKU 库存

    • 详情描述:/item/desc → 商品详情页 HTML / 纯文本

    • 店铺信息:/shop/base → 卖家店铺等级、粉丝数等

  3. 反爬与稳定性
    • 动态更新 User-Agent,添加随机请求延迟

    • 自动从 URL 提取商品 ID 和店铺 ID,减少手动输入

    • 完善的错误处理,返回结构化错误信息

  4. 字段适配
    • 价格字段可能以 “分” 为单位(需除以 100 转换为元)

    • 详情描述包含 HTML 标签,可根据需求用BeautifulSoup清洗

    • 规格 ID 组合需与 SKU 对应(如颜色 ID + 尺寸 ID 确定唯一 SKU)

  5. 注意事项
    • 微店 API 可能随版本更新调整,若字段不符,需打印raw_data查看最新结构

    • 高频调用可能被限制,建议添加代理 IP 池(通过proxies参数配置)

    • 商业使用需遵守微店用户协议,禁止滥用数据

通过以上系列接口,可全面采集微店商品的多维数据,适用于电商分析、竞品监控等场景。如需扩展,可基于此框架添加评论采集(/item/review接口)等功能。


群贤毕至

访客