京东关键词搜索 item_search_pro API 接口获取数据——代码逐行解析

说明:item_search_pro 并非京东官方文档里的接口名,而是第三方/服务商对「关键词搜索商品」能力的统一封装,内部实际调用的是京东联盟开放平台的 jd.union.open.goods.search(联盟版)或 routerjson 下的 item_search(自营版)。下文以「联盟版」为例,给出一份可直接落地的 Python 实现,并逐行拆解关键代码,方便你二次封装或排查签名、分页、字段裁剪等常见坑点。


一、接口基本信息

要点取值
请求地址https://api.jd.com/routerjson
方法名jd.union.open.goods.search
请求方式POST / x-www-form-urlencoded
数据格式JSON
签名算法参数名 ASCII 升序 + 首尾拼 app_secret 再 MD5 转大写
返回核心字段skuId、skuName、price、promotionPrice、commissionShare、shopName、mainImageUrl
分页上限50 页(≈ 1000 条)

二、完整源码(可直接跑)

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import time, json, hashlib, requests, os

class JdItemSearchPro:
    """
    京东关键词搜索 item_search_pro 联盟版实现
    官方文档:https://union.jd.com/openplatform/api/10421
    """
    def __init__(self, app_key: str, app_secret: str):
        self.app_key = app_key
        self.app_secret = app_secret
        self.base_url = "https://api.jd.com/routerjson"

    # —— ① 生成京东签名 —— #
    def _sign(self, params: dict) -> str:
        """
        1. 过滤空值
        2. 按 key 升序排列
        3. 首尾拼 app_secret 后 MD5→大写
        """
        params = {k: v for k, v in params.items() if v not in ("", None)}
        src = self.app_secret
        for k, v in sorted(params.items()):
            src += f"{k}{v}"
        src += self.app_secret
        return hashlib.md5(src.encode("utf-8")).hexdigest().upper()

    # —— ② 业务方法:关键词搜索 —— #
    def search(self, keyword: str,
               page: int = 1,
               page_size: int = 20,
               price_min: int = None,
               price_max: int = None,
               sort: str = "sale_desc") -> dict:
        """
        :param keyword:   搜索关键词,如“笔记本电脑”
        :param page:      页码,1 开始
        :param page_size: 每页条数,最大 50
        :param price_min: 最低价(元)
        :param price_max: 最高价(元)
        :param sort:      sale_desc | price_asc | price_desc | hot_desc
        :return:          {"total":100,"items":[{},{},...]}
        """
        # 1)业务参数
        biz = {
            "keyword": keyword,
            "pageIndex": page,
            "pageSize": page_size,
            "sortName": sort
        }
        if price_min is not None:
            biz["priceMin"] = price_min
        if price_max is not None:
            biz["priceMax"] = price_max

        # 2)公共参数
        params = {
            "method": "jd.union.open.goods.search",
            "app_key": self.app_key,
            "timestamp": time.strftime("%Y-%m-%d %H:%M:%S"),
            "format": "json",
            "v": "1.0",
            "param_json": json.dumps(biz, ensure_ascii=False)
        }

        # 3)生成签名并追加
        params["sign"] = self._sign(params)

        # 4)发请求
        rsp = requests.post(self.base_url,
                            data=params,
                            headers={"Content-Type": "application/x-www-form-urlencoded"},
                            timeout=15)
        rsp.raise_for_status()
        root = rsp.json()

        # 5)错误处理
        if "error_response" in root:
            err = root["error_response"]
            raise RuntimeError(f'{err["code"]} {err.get("zh_desc") or err.get("en_desc")}')

        # 6)提取商品列表
        data_json = json.loads(root["jd_union_open_goods_search_response"]["result"])
        if data_json["code"] != 200:
            raise RuntimeError(data_json["message"])
        return {
            "total": data_json["totalCount"],
            "page": page,
            "page_size": page_size,
            "items": data_json["data"]["goodsList"]
        }

# —— ③ 快速体验 —— #
if __name__ == "__main__":
    # 换成你的联盟 APP 凭证
    api = JdItemSearchPro(app_key=os.getenv("JD_APPKEY"),
                          app_secret=os.getenv("JD_SECRET"))
    ret = api.search("手机", page=1, page_size=10, price_min=1000, price_max=5000)
    print(f'共 {ret["total"]} 件商品,本页返回 {len(ret["items"])} 条')
    for i, g in enumerate(ret["items"], 1):
        print(i, g["skuId"], g["skuName"], "¥", g["price"])

三、逐行代码拆解

行号区间关键知识点说明
① _sign签名算法京东全系接口统一规则:过滤空值→ASCII 升序→首尾拼 app_secret→MD5 大写;任何多余空格或大小写错误都会报 40005 。
② biz 参数业务参数keyword/pageIndex/pageSize 为必传;价格区间、排序、类目 ID、品牌 ID 等均为可选。
③ param_json嵌套 JSON京东要求把业务参数整体当字符串放进 param_json,并不再二次排序;否则同样 40005 。
④ timestamp时间格式必须 YYYY-MM-DD HH:MM:SS,不带毫秒;Linux 可直接 time.strftime 生成。
⑤ 返回解析三层嵌套routerjson→jd_union_open_goods_search_response→result 才是业务 JSON,官方用了字符串再包一层,记得 json.loads 。
⑥ 分页陷阱50 页上限深度翻页会被截断;想拉全量请按“价格段+销量段”多次拆分再合并。
⑦ 字段裁剪fields联盟支持 fields 参数,只返回需要的列,节省 30 % 流量;示例未开启,可自行追加。

四、常见报错速查

错误码中文描述排查思路
40005签名验证失败1. 空值未过滤 2. 时间戳格式错 3. param_json 被二次排序
40006应用不存在AppKey 写错或应用未上线
40010无权限未在联盟后台申请“商品搜索” API 包
50001关键词为空前端未做非空校验

五、进阶玩法

  1. 组合关键词:空格代表“且”,+ 代表“或”,- 代表排除,例:笔记本 +游戏本 -二手

  2. 类目锁定:先调 category.search 拿三级类目 ID,再拼 categoryId 可把范围缩小 70 % 以上

  3. 佣金+券双重筛选:选品库场景同时加 hasCoupon=1 + commissionShare 区间,快速找“低价高佣”爆品

  4. 排序权重:sale_desc 走量;price_asc 找低价货源;hot_desc 结合京东热度算法,适合发现潜力新品

  5. 缓存与限流:单 IP 建议 QPS≤10,失败重试 3 次后休眠 5 s;价格数据可落地 Redis 并设置 10 min 过期,避免重复拉取


六、小结

item_search_pro 的核心难点只有两点:

  1. 把签名算对;

  2. 把业务参数拼细(类目、价格、排序、优惠券)。

跑通上面的最小代码后,再叠加自己的 SKU 池、缓存策略与业务字段映射,就能在比价、选品、返利、数据分析等场景中快速上线。祝你“搜”得开心,单量长虹!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值