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

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

接口功能与定位

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

  • 应用场景

    • 电商平台的商品检索功能,帮助用户快速找到所需商品。
    • 竞品分析,通过关键词搜索了解竞争对手的商品情况。
    • 市场调研,分析特定关键词下的商品分布、价格区间等信息。 认证机制 微店开放平台采用appkey + access_token的认证方式,具体流程如下:
  1. 开发者在微店开放平台注册应用,获取appkeyappsecret
  2. 使用appkeyappsecret获取access_token,该令牌有一定的有效期。
  3. 每次调用接口时,在请求参数中携带access_token以完成身份验证。

核心参数与响应结构

请求参数

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

响应核心字段

  • 分页信息:总页数、当前页码、总商品数等。
  • 商品列表:每个商品包含商品 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 = "api.vdian.com" self.access_token = None self.token_expires_at = 0 # token过期时间戳 self.session = requests.Session()

python 复制代码
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 = "手机"

python 复制代码
# 初始化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接口,开发者可以快速实现商品搜索功能,为用户提供便捷的商品查找服务,同时也能为企业的市场分析和竞品监控提供有力支持。在使用过程中,需遵守微店开放平台的相关规定,确保接口调用的合法性和合规性

相关推荐
围巾哥萧尘13 小时前
用 SOLO 模式 30 分钟搞定 智能点名系统 | 围巾哥萧尘🧣
trae
兵临天下api14 小时前
微店 item_get 接口深度分析及 Python 实现
trae
围巾哥萧尘14 小时前
生成一个应用创意众筹的网站🧣
trae
围巾哥萧尘15 小时前
用AI做了款英语学习软件的一个案例🧣
trae
用户40993225021216 小时前
测试覆盖率不够高?这些技巧让你的FastAPI测试无懈可击!
后端·ai编程·trae
IAM四十二1 天前
用Trae做一个浏览器插件
llm·ai编程·trae
VUE1 天前
分享一些常用的mcp服务(附带场景演示)
mcp·trae
前端卧龙人1 天前
Trae 帮我搞定九大行星围绕太阳转的 Three.js 项目
trae
前端的日常1 天前
俄罗斯方块,到底有多“上头”?(Trae实现版)
trae