×

华为商城关键词搜索商品列表接口实战:分页降噪与数据归一化处理

Ace Ace 发表于2026-10-26 13:47:32 浏览4 评论0

抢沙发发表评论

在电商商品数据同步场景里,华为商城搜索接口有一个很明显的特点:搜索结果混排自营商品、第三方店铺、广告展位,直接拉取原始数据会掺杂大量无效广告数据,这也是很多通用教程没有重点处理的痛点。本文从业务过滤角度封装调用逻辑,优先过滤广告,统一商品基础字段,方便后续入库或者对接详情接口。

接口调用的核心难点不在于签名,而在于请求头指纹、分页终止判断、广告标记识别。原生返回结构嵌套层级深,促销价、划线价、库存状态分散在不同节点,需要做一层归一化,保证输出字段稳定。下面封装可复用的搜索工具类,内置重试、超时、广告过滤。

点击获取key和secret

import requests
import time

class VmallSearch:
    def __init__(self):
        self.session = requests.Session()
        self.headers = {
            "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
            "referer": "https://www.vmall.com/",
            "accept": "application/json, text/plain, */*"
        }
        self.base_url = "https://www.vmall.com/api/search/list"

    def search_goods(self, keyword, page=1, size=20):
        params = {
            "keyword": keyword,
            "page": page,
            "size": size
        }
        try:
            resp = self.session.get(self.base_url, params=params, headers=self.headers, timeout=8)
            resp.raise_for_status()
            res_json = resp.json()
            data_list = []
            items = res_json.get("data", {}).get("goodsList", [])
            for item in items:
                # 过滤广告展位商品
                if item.get("isAd") == 1:
                    continue
                info = {
                    "goods_id": item.get("goodsId"),
                    "goods_name": item.get("goodsName"),
                    "price": item.get("salePrice"),
                    "market_price": item.get("marketPrice"),
                    "img": item.get("picUrl"),
                    "is_self": item.get("isSelfSupport"),
                    "stock_status": item.get("stockStatus")
                }
                data_list.append(info)
            return {"code": res_json.get("code"), "list": data_list, "total": res_json.get("data", {}).get("total")}
        except Exception as e:
            print(f"请求异常:{e}")
            return None

if __name__ == "__main__":
    searcher = VmallSearch()
    result = searcher.search_goods(keyword="手机", page=1, size=20)
    if result:
        for row in result["list"]:
            print(row)

代码逻辑上,使用 session 维持会话减少指纹变化,增加广告字段isAd过滤,输出固定结构字典。分页逻辑不要单纯循环固定页数,业务上推荐根据返回 total 做动态终止,避免无效空请求浪费频次。

线上落地有几个高频踩坑点。第一,UA 和 referer 不能随意省略,缺少后大概率返回空或者 403 拦截;第二,接口有访问频次限制,连续分页建议增加 0.5s 以上间隔;第三,库存状态是实时变动字段,只适合快照采集,不可直接当作实时下单判断依据;第四,自营标识 is_self 可以用来区分华为自营和第三方商家,做数据分类。

在数据流转链路中,该搜索接口拿到 goods_id 后,可以直接传入商品详情接口,形成一套完整的 “搜索列表 - 详情” 数据链路。如果用于长期定时同步,建议增加 redis 去重,以 goods_id 作为唯一主键,避免重复入库。整体方案轻量,适合中小规模商品数据采集同步,兼顾稳定性和数据干净度。

群贤毕至

访客