×

微店item_search - 根据关键词取商品列表深度分析及 Python 实现

万邦科技Lex 万邦科技Lex 发表于2025-09-02 11:52:39 浏览261 评论0

抢沙发发表评论

      注册账号免费测试微店API数据接口

微店的item_search接口是用于根据关键词搜索商品列表的核心接口,能够根据用户输入的关键词,返回相关的商品列表信息。该接口对于电商平台的商品检索索功能、竞品竞品分析、市场调研调研等场景具有重要意义。

接口功能与定位

  • 核心功能:通过关键词用户输入的关键词,在微店平台上检索索并返回相关的商品列表,并返回商品的基本信息、价格、销量等数据。

  • 应用场景

    • 电商平台的商品检索功能,帮助用户快速找到所需商品。

    • 竞品分析,通过关键词搜索了解竞争对手的商品情况。

    • 市场调研,分析特定关键词下的商品分布、价格区间等信息。

认证机制

微店开放平台采用appkey + access_token的认证方式,具体流程如下:


  1. 开发者在微店开放平台注册应用,获取appkeyappsecret

  2. 使用appkeyappsecret获取access_token,该令牌有一定的有效期。

  3. 每次调用接口时,在请求参数中携带access_token以完成身份验证。

核心参数与响应结构

请求参数

参数名类型是否必填说明
keywordString搜索关键词
pageInteger页码,默认值为 1
page_sizeInteger每页显示的商品数量,默认值为 20,最大值通常为 100
sortString排序方式,如price_asc(价格升序)、price_desc(价格降序)、sales_desc(销量降序)等
access_tokenString访问令牌

响应核心字段

  • 分页信息:总页数、当前页码、总商品数等。

  • 商品列表:每个商品包含商品 ID、标题、主图、价格、销量、店铺信息等。

Python 脚本实现

以下是调用微店item_search接口的 Python 实现,包含获取访问令牌、接口调用、数据解析等功能:
import requests
import time
import json
import logging
from typing import Dict, Optional, List
from requests.exceptions import RequestException

# 配置日志
logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s - %(levelname)s - %(message)s"
)

class WeidianItemSearchAPI:
    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.access_token = None
        self.token_expires_at = 0  # token过期时间戳
        self.session = requests.Session()

    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}/token"

        params = {
            "grant_type": "client_credentials",
            "appkey": self.appkey,
            "appsecret": self.appsecret
        }

        try:
            response = self.session.get(url, params=params, timeout=10)
            response.raise_for_status()
            result = response.json()

            if result.get("status") == 0:
                self.access_token = result.get("result", {}).get("access_token")
                expires_in = result.get("result", {}).get("expires_in", 3600)
                self.token_expires_at = time.time() + expires_in
                return self.access_token
            else:
                logging.error(f"获取access_token失败: {result.get('msg')}")
                return None

        except RequestException as e:
            logging.error(f"获取access_token请求异常: {str(e)}")
            return None

    def search_items(self, keyword: str, page: int = 1, page_size: int = 20, sort: Optional[str] = None) -> Optional[Dict]:
        """
        根据关键词搜索商品
        :param keyword: 搜索关键词
        :param page: 页码
        :param page_size: 每页商品数量
        :param sort: 排序方式
        :return: 商品搜索结果
        """
        # 获取有效的access_token
        if not self._get_access_token():
            return None

        url = f"{self.base_url}/item/search"

        # 构建请求参数
        params = {
            "keyword": keyword,
            "page": page,
            "page_size": page_size,
            "access_token": self.access_token
        }

        # 添加排序参数
        if sort:
            params["sort"] = sort

        try:
            response = self.session.get(url, params=params, timeout=15)
            response.raise_for_status()
            result = response.json()

            if result.get("status") == 0:
                # 格式化商品数据
                return self._format_search_result(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_search_result(self, result_data: Dict) -> Dict:
        """格式化搜索结果数据"""
        # 分页信息
        pagination = {
            "total_items": int(result_data.get("total", 0)),
            "total_pages": (int(result_data.get("total", 0)) + int(result_data.get("page_size", 20)) - 1) // int(result_data.get("page_size", 20)),
            "current_page": int(result_data.get("page", 1)),
            "page_size": int(result_data.get("page_size", 20))
        }

        # 商品列表
        items = []
        for item in result_data.get("items", {}).get("item", []):
            items.append({
                "item_id": item.get("item_id"),
                "title": item.get("title"),
                "main_img": item.get("main_img"),
                "price": float(item.get("price", 0)),
                "original_price": float(item.get("original_price", 0)),
                "sales": int(item.get("sales", 0)),
                "shop_id": item.get("shop_id"),
                "shop_name": item.get("shop_name"),
                "detail_url": item.get("detail_url")
            })

        return {
            "pagination": pagination,
            "items": items
        }

    def search_all_items(self, keyword: str, max_pages: int = 5) -> List[Dict]:
        """
        搜索所有页的商品
        :param keyword: 搜索关键词
        :param max_pages: 最大页数限制
        :return: 所有商品列表
        """
        all_items = []
        page = 1

        while page <= max_pages:
            logging.info(f"搜索关键词 '{keyword}' 第 {page} 页商品")
            result = self.search_items(keyword, page=page, page_size=100)

            if not result or not result["items"]:
                break

            all_items.extend(result["items"])

            # 检查是否已达最后一页
            if page >= result["pagination"]["total_pages"]:
                break

            page += 1
            # 添加延迟,避免触发频率限制
            time.sleep(1)

        return all_items


# 示例调用
if __name__ == "__main__":
    # 替换为实际的appkey和appsecret(从微店开放平台获取)
    APPKEY = "your_appkey"
    APPSECRET = "your_appsecret"
    # 搜索关键词
    KEYWORD = "手机"

    # 初始化API客户端
    api = WeidianItemSearchAPI(APPKEY, APPSECRET)

    # 方式1:获取指定页的商品
    # search_result = api.search_items(KEYWORD, page=1, page_size=20, sort="sales_desc")

    # 方式2:获取多页商品
    search_result = api.search_all_items(KEYWORD, max_pages=3)

    if isinstance(search_result, dict) and "items" in search_result:
        print(f"关键词 '{KEYWORD}' 搜索结果:")
        print(f"总商品数:{search_result['pagination']['total_items']}")
        print(f"总页数:{search_result['pagination']['total_pages']}")
        print(f"当前页:{search_result['pagination']['current_page']}")
        print("\n前5件商品信息:")
        for i, item in enumerate(search_result["items"][:5], 1):
            print(f"{i}. {item['title']}")
            print(f"   价格:{item['price']}元,原价:{item['original_price']}元")
            print(f"   销量:{item['sales']}件")
            print(f"   店铺:{item['shop_name']}")
            print(f"   链接:{item['detail_url']}")
            print("-" * 80)
    elif isinstance(search_result, list):
        print(f"关键词 '{KEYWORD}' 共获取到 {len(search_result)} 件商品")
        print("\n前5件商品信息:")
        for i, item in enumerate(search_result[:5], 1):
            print(f"{i}. {item['title']}")
            print(f"   价格:{item['price']}元,原价:{item['original_price']}元")
            print(f"   销量:{item['sales']}件")
            print(f"   店铺:{item['shop_name']}")
            print(f"   链接:{item['detail_url']}")
            print("-" * 80)


接口调用注意事项

调用限制与规范

  • QPS 限制:微店开放平台对item_search接口有 QPS 限制,一般为 10 次 / 秒,超过限制会返回错误信息。

  • 分页限制:通常每页最多显示 100 条商品数据,且总页数有一定限制,避免过度请求。

  • 关键词规范:搜索关键词需符合法律法规和平台规定,不得包含违法、违规内容。

  • 数据缓存:对于相同关键词的搜索结果,建议进行缓存处理,减少接口调用次数,提高响应速度。

常见错误及解决方案

错误码说明解决方案
400请求参数错误检查关键词、页码、页大小等参数是否正确,确保参数格式符合要求
401未授权或 token 无效重新获取access_token,确保appkeyappsecret正确
429调用频率超限降低接口调用频率,实现请求限流机制,如添加延迟时间
500服务器内部错误稍后重试,若问题持续,联系微店开放平台技术支持

数据解析要点

  • 价格字段可能为字符串类型,需要转换为浮点型进行数值计算和比较。

  • 商品图片 URL 可能需要拼接域名才能直接访问,需注意处理。

  • 部分商品可能缺少某些字段(如原价),解析时需进行容错处理,避免程序报错。

应用场景与扩展建议

典型应用场景

  • 电商导购平台,根据用户输入的关键词为用户推荐相关商品。

  • 竞品分析工具,通过关键词搜索了解竞争对手的商品定价、销量等情况。

  • 市场调研系统,分析特定行业或品类下的商品分布、价格趋势等信息。

扩展建议

  • 实现商品筛选功能,如根据价格区间、销量范围等进一步筛选商品。

  • 添加商品详情获取功能,结合item_get接口,为用户提供更详细的商品信息。

  • 开发数据可视化功能,将搜索结果以图表形式展示,如价格分布直方图、销量排行榜等。

  • 实现搜索历史记录功能,方便用户查看之前的搜索内容。


通过合理使用微店item_search接口,开发者可以快速实现商品搜索功能,为用户提供便捷的商品查找服务,同时也能为企业的市场分析和竞品监控提供有力支持。在使用过程中,需遵守微店开放平台的相关规定,确保接口调用的合法性和合规性。


群贤毕至

访客