×

微店关键词搜索 API 实战:分销佣金筛选 + 到手价核算 + 令牌自动续期(Python 合规版)

Ace Ace 发表于2026-06-05 16:19:29 浏览14 评论0

抢沙发发表评论

前言

微店依托个体商户、私域分销生态,关键词搜品是私域选品、分销带货的核心数据源。网上多数教程存在三大短板:要么采用网页爬虫抓搜索页极易封号 IP,要么只做基础关键词查询、缺失微店独有分销佣金、拼团价、优惠券到手价筛选逻辑,access_token 过期无自动刷新机制,无法适配长期生产调用。本文基于微店开放平台官方weidian.item.search接口,落地多条件动态筛选、分销佣金过滤、实付价自动计算、access_token 定时续期、指数退避重试差异化方案,全程依托官方 API 合规开发,满足 CSDN 发文规范。

一、差异化技术亮点(区别全网通用代码)


  1. 微店专属分销筛选引擎:独有最低佣金门槛、拼团商品过滤、自营 / 个体店区分筛选,适配微店分销业务。

  2. 三层价格自动拆解:标价、原价、券后到手价结构化拆分,自动核算优惠幅度。

  3. AccessToken 自动续期:内置令牌有效期检测,临近过期自动刷新,杜绝因 token 失效中断采集。

  4. 会话重试 + 阶梯休眠:429 限流、5xx 异常自动重试,高频调用动态调整休眠时间规避平台风控。

  5. 商品分销潜力打分:依托佣金比例 + 近 7 天销量生成选品分值,快速筛选优质带货货源。


二、接口基础规范


  • 接口标识:weidian.item.search,网关https://api.weidian.com/router,POST 表单提交

  • 签名规则:参数 ASCII 升序拼接,HMAC-SHA256 加密转大写,时间戳固定13 位毫秒级(微店独有规范,区别淘系秒级时间)

  • 令牌规则:access_token 有效期 7 天,refresh_token 有效期 30 天,通过密钥续期令牌

  • QPS 限制:普通开发者≤5 次 / 秒,批量分页单次休眠≥0.6s

点击获取key和secret

三、完整可运行 Python 代码

python

运行

import requests
import hmac
import hashlib
import time
import json
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry

class WeidianSearch:
    def __init__(self, appkey, appsecret):
        self.appkey = appkey
        self.appsecret = appsecret
        self.api_gate = "https://api.weidian.com/router"
        self.token_url = "https://api.weidian.com/oauth/token"
        self.access_token = ""
        self.refresh_token = ""
        self.token_expire = 0
        # 请求重试配置
        self.session = requests.Session()
        retry_cfg = Retry(total=3, backoff_factor=0.3, status_forcelist=[429,500,502])
        self.session.mount("https://", HTTPAdapter(max_retries=retry_cfg))

    def get_sign(self, params):
        """HMAC-SHA256微店标准签名"""
        sorted_kv = sorted(params.items(), key=lambda x:x[0])
        sign_str = "&".join([f"{k}={v}" for k,v in sorted_kv])
        sign = hmac.new(self.appsecret.encode(), sign_str.encode(), hashlib.sha256).hexdigest().upper()
        return sign

    def refresh_access_token(self):
        """令牌自动续期,过期自动刷新"""
        if int(time.time()) < self.token_expire - 3600:
            return True
        req_data = {"grant_type":"refresh_token","appkey":self.appkey,"refresh_token":self.refresh_token}
        res = self.session.post(self.token_url, data=req_data, timeout=8).json()
        if res.get("code")==0:
            self.access_token = res["data"]["access_token"]
            self.refresh_token = res["data"]["refresh_token"]
            self.token_expire = int(time.time()) + int(res["data"]["expires_in"])
            return True
        return False

    def calc_score(self, sale7, comm_rate):
        """分销潜力打分:销量60%+佣金40%"""
        s_score = min(sale7/300*60,60)
        c_score = min(comm_rate*4,40)
        return round(s_score+c_score,2)

    def search_item(self, keyword, page=1, page_size=20, min_price=None,max_price=None,min_comm=0,is_group=0):
        self.refresh_access_token()
        biz_param = {"keyword":keyword,"page":page,"page_size":page_size}
        # 空参数不传入,精简报文
        if min_price:biz_param["price_min"]=min_price
        if max_price:biz_param["price_max"]=max_price
        if min_comm>0:biz_param["commission_min"]=min_comm
        if is_group==1:biz_param["is_group"]=1

        pub_params = {
            "method":"weidian.item.search","appkey":self.appkey,"access_token":self.access_token,
            "timestamp":str(int(time.time()*1000)),"version":"1.0","format":"json",
            "param_json":json.dumps(biz_param,ensure_ascii=False)
        }
        pub_params["sign"] = self.get_sign(pub_params)
        try:
            resp = self.session.post(self.api_gate,data=pub_params,timeout=10)
            ret = resp.json()
            if ret.get("code")!=0:
                return {"code":-1,"msg":ret.get("msg","接口异常")}
            data = ret["data"]
            goods_list = data.get("item_list",[])
            res_data = []
            for item in goods_list:
                comm = float(item.get("commission_rate",0))
                sale = int(item.get("sale_7d",0))
                res_data.append({
                    "item_id":item["item_id"],"title":item["title"],"ori_price":item["market_price"],
                    "sell_price":item["sell_price"],"real_price":item["coupon_price"],
                    "commission_rate":comm,"seven_sale":sale,"is_group":item.get("is_group",0),
                    "shop_name":item["shop_name"],"score":self.calc_score(sale,comm)
                })
            time.sleep(0.6)
            return {"code":200,"total":data["total"],"data":res_data}
        except Exception as e:
            return {"code":-2,"msg":str(e)}

# 调用示例
if __name__ == "__main__":
    ak = "替换你的AppKey"
    as_sec = "替换你的AppSecret"
    api = WeidianSearch(ak,as_sec)
    # 筛选:护肤、29-199元、佣金≥8%、拼团商品
    print(json.dumps(api.search_item("护肤",min_price=29,max_price=199,min_comm=8,is_group=1),ensure_ascii=False,indent=2))

四、实战原创避坑要点


  1. timestamp 必须 13 位毫秒,传秒级时间直接签名失败,是微店高频踩坑点。

  2. 业务参数统一封装进param_json,不可拆分至外层公共参数。

  3. refresh_token 留存用于自动续期,令牌提前 1 小时刷新,避免中途失效。

  4. commission_min为微店独有分销筛选字段,非通用电商接口参数。

  5. 单页请求强制休眠 0.6s,连续高频调用易触发 QPS 限流。

群贤毕至

访客