×

小米有品关键词商品搜索接口实战:结构化分页与数据归一化方案

Ace Ace 发表于2026-10-21 16:57:28 浏览16 评论0

抢沙发发表评论

前言

小米有品搜索接口和普通电商平台有明显区别,除基础关键词、分页参数外,额外携带渠道标识、排序类型等公共参数,返回字段嵌套层级多,直接拿到的原始数据很难投入下游统计、比价系统。本文不侧重逆向破解,而是从业务接入角度封装调用类,统一异常捕获、分页循环、字段清洗逻辑,适合做商品监控、价格采集场景的轻量化对接。

环境准备

依赖 requests 库,请求头需要模拟移动端 UA,接口采用 GET 方式提交参数;需要注意该接口存在频率限制,短时间高频请求会触发风控返回空数据。

点击获取key和secret

完整调用代码

import requests
import time

class YouPinSearch:
    def __init__(self):
        self.base_url = "https://m.xiaomiyoupin.com/api/search/goods"
        self.headers = {
            "User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 16 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16 Mobile/15E148 Safari/604.1",
            "Referer": "https://m.xiaomiyoupin.com/search"
        }
        self.session = requests.Session()

    def search_goods(self, keyword, page=1, page_size=20, sort=0):
        """
        sort:0综合,1销量,2价格升序,3价格降序
        """
        params = {
            "keyword": keyword,
            "page": page,
            "limit": page_size,
            "sort": sort
        }
        try:
            resp = self.session.get(self.base_url, headers=self.headers, params=params, timeout=8)
            resp.raise_for_status()
            res_json = resp.json()
            if res_json.get("code") != 0:
                return []
            raw_list = res_json.get("data", {}).get("list", [])
            result = []
            for item in raw_list:
                result.append({
                    "item_id": item.get("itemId"),
                    "title": item.get("title"),
                    "price": item.get("price"),
                    "sale": item.get("saleNum"),
                    "pic": item.get("picUrl"),
                    "shop_name": item.get("shopName")
                })
            return result
        except Exception as e:
            print(f"请求异常:{e}")
            return []

    def loop_search(self, keyword, max_page=3):
        all_data = []
        for p in range(1, max_page + 1):
            page_data = self.search_goods(keyword, page=p)
            if not page_data:
                break
            all_data.extend(page_data)
            time.sleep(1.2)
        return all_data

if __name__ == "__main__":
    sp = YouPinSearch()
    data = sp.loop_search("保温杯", max_page=2)
    for row in data:
        print(row)

核心逻辑解析

代码封装两层函数,search_goods负责单页请求与字段扁平化,剔除广告位、活动冗余字段,只保留业务核心字段;loop_search实现自动分页,内置休眠间隔降低风控风险。小米有品搜索接口广告商品和正常商品混排,在实际业务中可以增加过滤判断,通过标识位跳过广告条目。价格字段是原始数值,没有自动区分券后价、划线价,需要额外解析优惠节点。

线上踩坑总结

  1. UA 固定 PC 端极易返回数据为空,优先使用移动端 UA;

  2. 分页不是无限拉取,超过平台返回最大页码后不会报错,直接返回空列表;

  3. 同一 IP 短时间连续请求,会触发临时限流,表现为 code=0 但 list 为空;

  4. 关键词带特殊符号、生僻字时,需要 urllib 编码,部分版本接口不自动编码。

群贤毕至

访客