微店的item_search
接口是用于根据关键词搜索商品列表的核心接口,能够根据用户输入的关键词,返回相关的商品列表信息。该接口对于电商平台的商品检索索功能、竞品竞品分析、市场调研调研等场景具有重要意义。
接口功能与定位
-
核心功能:通过关键词用户输入的关键词,在微店平台上检索索并返回相关的商品列表,并返回商品的基本信息、价格、销量等数据。
-
应用场景:
- 电商平台的商品检索功能,帮助用户快速找到所需商品。
- 竞品分析,通过关键词搜索了解竞争对手的商品情况。
- 市场调研,分析特定关键词下的商品分布、价格区间等信息。 认证机制 微店开放平台采用
appkey + access_token
的认证方式,具体流程如下:
- 开发者在微店开放平台注册应用,获取
appkey
和appsecret
。 - 使用
appkey
和appsecret
获取access_token
,该令牌有一定的有效期。 - 每次调用接口时,在请求参数中携带
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 ,确保appkey 和appsecret 正确 |
429 | 调用频率超限 | 降低接口调用频率,实现请求限流机制,如添加延迟时间 |
500 | 服务器内部错误 | 稍后重试,若问题持续,联系微店开放平台技术支持 |
数据解析要点
- 价格字段可能为字符串类型,需要转换为浮点型进行数值计算和比较。
- 商品图片 URL 可能需要拼接域名才能直接访问,需注意处理。
- 部分商品可能缺少某些字段(如原价),解析时需进行容错处理,避免程序报错。
应用场景与扩展建议
典型应用场景
- 电商导购平台,根据用户输入的关键词为用户推荐相关商品。
- 竞品分析工具,通过关键词搜索了解竞争对手的商品定价、销量等情况。
- 市场调研系统,分析特定行业或品类下的商品分布、价格趋势等信息。
扩展建议
- 实现商品筛选功能,如根据价格区间、销量范围等进一步筛选商品。
- 添加商品详情获取功能,结合
item_get
接口,为用户提供更详细的商品信息。 - 开发数据可视化功能,将搜索结果以图表形式展示,如价格分布直方图、销量排行榜等。
- 实现搜索历史记录功能,方便用户查看之前的搜索内容。
通过合理使用微店item_search
接口,开发者可以快速实现商品搜索功能,为用户提供便捷的商品查找服务,同时也能为企业的市场分析和竞品监控提供有力支持。在使用过程中,需遵守微店开放平台的相关规定,确保接口调用的合法性和合规性。