0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

京东工业平台商品详情接口开发指南:工业级数据解析与实战实现

邓林 来源:jf_63013664 作者:jf_63013664 2025-08-25 10:50 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

在工业供应链数字化转型过程中,京东工业平台作为专注于工业用品采购的 B2B 电商平台,其商品详情数据包含丰富的技术参数、合规认证和供应链信息,对企业采购系统、供应链管理工具的开发具有重要价值。本文将详细介绍京东工业平台商品详情接口的调用流程,包括 OAuth2.0 认证机制、签名生成、工业特性数据解析及完整代码实现,帮助开发者快速构建稳定高效的工业商品数据对接功能。

一、京东工业商品详情接口基础信息

京东工业开放平台提供的jd.industry.product.detail.get接口是获取商品完整信息的核心接口,专为工业场景设计,相比消费类商品接口增加了大量专业维度的数据。

接口特点

采用 OAuth2.0 + 签名双重认证机制,安全性更高

支持获取工业商品特有的技术参数、规格型号、认证资质等信息

包含详细的包装、物流、售后服务等供应链关键数据

提供多维度价格体系(零售、批发、企业集采等)

接口端点:https://api.jd.com/routerjson

二、认证机制与核心参数解析

1. 完整认证流程

京东工业 API 采用业界标准的 OAuth2.0 认证框架,结合签名机制确保接口安全:

获取 Access Token:通过 client_id 和 client_secret 获取访问令牌(有效期 24 小时)

生成签名:对请求参数按规则进行签名计算

接口调用:在请求中携带 Access Token 和签名信息

2. 签名生成规则

收集所有请求参数(包括公共参数和业务参数)

按参数名 ASCII 码升序排序

拼接为 "key=value" 形式的字符串,用 & 连接

拼接上 Access Token 和 app_secret,形成待签名字符串

使用 MD5 算法对字符串进行加密,得到 32 位大写签名

3. 核心参数说明

公共参数

method:接口名称,固定为jd.industry.product.detail.get

app_key:应用唯一标识

access_token:访问令牌

timestamp:时间戳(毫秒级)

format:响应格式,固定为 json

v:API 版本,固定为 1.0

sign:签名值

业务参数

productId:商品 ID(必填,可从搜索接口获取)

needTechParam:是否需要技术参数(true/false,默认 false)

needCert:是否需要认证信息(true/false,默认 false)

needInventory:是否需要库存信息(true/false,默认 false)

wKgZO2irzvmAOCpfABz3JDYSlpI340.png

三、完整代码实现

以下是 Python 实现的京东工业商品详情接口调用功能,包含完整的认证流程、签名生成和工业数据解析:

import requests
import time
import hashlib
import json
from typing import Dict, List, Optional, Any

class JDIndustryProductAPI:
    def __init__(self, app_key: str, app_secret: str, redirect_uri: str):
        """
        初始化京东工业商品API客户端
        
        :param app_key: 应用的App Key
        :param app_secret: 应用的App Secret
        :param redirect_uri: 授权回调地址
        """
        self.app_key = app_key
        self.app_secret = app_secret
        self.redirect_uri = redirect_uri
        self.base_url = "https://api.jd.com/routerjson"
        self.token_url = "https://oauth.jd.com/token"
        self.access_token = None
        self.token_expiry = 0  # 令牌过期时间戳(秒)
    
    def get_auth_url(self) -> str:
        """生成授权URL,用于获取code(首次授权时使用)"""
        params = {
            "response_type": "code",
            "client_id": self.app_key,
            "redirect_uri": self.redirect_uri,
            "state": "JD_INDUSTRY_STATE"
        }
        return f"https://oauth.jd.com/authorize?{requests.compat.urlencode(params)}"
    
    def get_access_token(self, code: Optional[str] = None, refresh_token: Optional[str] = None) -> bool:
        """
        获取或刷新访问令牌
        
        :param code: 授权码(首次获取时需要)
        :param refresh_token: 刷新令牌(令牌过期时使用)
        :return: 是否成功
        """
        params = {
            "client_id": self.app_key,
            "client_secret": self.app_secret,
            "grant_type": "authorization_code" if code else "refresh_token"
        }
        
        if code:
            params["code"] = code
            params["redirect_uri"] = self.redirect_uri
        elif refresh_token:
            params["refresh_token"] = refresh_token
        else:
            return False
        
        try:
            response = requests.post(self.token_url, data=params, timeout=10)
            result = response.json()
            
            if "access_token" in result:
                self.access_token = result["access_token"]
                expires_in = result.get("expires_in", 86400)
                self.token_expiry = time.time() + expires_in
                self.refresh_token = result.get("refresh_token")
                return True
            else:
                print(f"获取令牌失败: {result.get('error_description')}")
                return False
                
        except Exception as e:
            print(f"令牌请求异常: {str(e)}")
            return False
    
    def _generate_sign(self, params: Dict[str, str]) -> str:
        """生成API请求签名"""
        # 按参数名ASCII升序排序
        sorted_params = sorted(params.items(), key=lambda x: x[0])
        
        # 拼接参数
        query_string = "&".join([f"{k}={v}" for k, v in sorted_params])
        
        # 拼接access_token和app_secret
        sign_str = f"{query_string}&access_token={self.access_token}{self.app_secret}"
        
        # 计算MD5签名并转为大写
        return hashlib.md5(sign_str.encode('utf-8')).hexdigest().upper()
    
    def get_product_detail(self,
                         product_id: str,
                         need_tech_param: bool = True,
                         need_cert: bool = True,
                         need_inventory: bool = True) -> Dict[str, Any]:
        """
        获取京东工业商品详情
        
        :param product_id: 商品ID
        :param need_tech_param: 是否需要技术参数
        :param need_cert: 是否需要认证信息
        :param need_inventory: 是否需要库存信息
        :return: 商品详情数据
        """
        # 检查令牌有效性
        if not self.access_token or time.time() >= self.token_expiry:
            if not self.refresh_token or not self.get_access_token(refresh_token=self.refresh_token):
                return {"success": False, "error_msg": "访问令牌无效或已过期"}
        
        # 业务参数
        biz_params = {
            "productId": product_id,
            "needTechParam": str(need_tech_param).lower(),
            "needCert": str(need_cert).lower(),
            "needInventory": str(need_inventory).lower()
        }
        
        # 公共参数
        params = {
            "method": "jd.industry.product.detail.get",
            "app_key": self.app_key,
            "timestamp": str(int(time.time() * 1000)),  # 毫秒级时间戳
            "format": "json",
            "v": "1.0",
            "param_json": json.dumps(biz_params, ensure_ascii=False)
        }
        
        # 生成签名
        params["sign"] = self._generate_sign(params)
        
        try:
            # 发送请求
            response = requests.post(
                self.base_url,
                data=params,
                timeout=15
            )
            response.raise_for_status()
            
            # 解析响应
            result = response.json()
            
            # 处理API错误
            if "error_response" in result:
                error = result["error_response"]
                return {
                    "success": False,
                    "error_code": error.get("code"),
                    "error_msg": error.get("msg")
                }
            
            # 处理正常响应
            detail_data = result.get("jd_industry_product_detail_get_response", {}).get("result", {})
            return self._parse_product_detail(detail_data)
            
        except requests.exceptions.RequestException as e:
            return {
                "success": False,
                "error_msg": f"请求异常: {str(e)}"
            }
        except Exception as e:
            return {
                "success": False,
                "error_msg": f"处理响应失败: {str(e)}"
            }
    
    def _parse_product_detail(self, raw_data: Dict[str, Any]) -> Dict[str, Any]:
        """解析原始商品详情数据为结构化格式"""
        if not raw_data:
            return {"success": False, "error_msg": "无商品详情数据"}
        
        # 基础信息解析
        base_info = {
            "product_id": raw_data.get("productId"),
            "sku_id": raw_data.get("skuId"),
            "name": raw_data.get("name"),
            "brand": {
                "id": raw_data.get("brandId"),
                "name": raw_data.get("brandName")
            },
            "category": {
                "id": raw_data.get("categoryId"),
                "name": raw_data.get("categoryName"),
                "parent_id": raw_data.get("parentCategoryId"),
                "parent_name": raw_data.get("parentCategoryName")
            },
            "model": raw_data.get("model"),  # 型号
            "spec": raw_data.get("spec"),    # 规格
            "production_date": raw_data.get("productionDate"),  # 生产日期
            "warranty_period": raw_data.get("warrantyPeriod"),  # 保修期
            "url": raw_data.get("productUrl")
        }
        
        # 价格信息解析
        price_info = {
            "retail_price": raw_data.get("retailPrice"),  # 零售价
            "wholesale_price": self._parse_wholesale_price(raw_data.get("wholesalePriceList", [])),  # 批发价
            "enterprise_price": raw_data.get("enterprisePrice"),  # 企业集采价
            "currency": raw_data.get("currency", "CNY"),
            "tax_included": raw_data.get("taxIncluded", True)  # 是否含税
        }
        
        # 技术参数解析
        tech_params = []
        for group in raw_data.get("techParamGroups", []):
            group_params = []
            for param in group.get("params", []):
                group_params.append({
                    "name": param.get("name"),
                    "value": param.get("value"),
                    "unit": param.get("unit"),
                    "standard": param.get("standard")  # 执行标准
                })
            tech_params.append({
                "group_name": group.get("groupName"),
                "params": group_params
            })
        
        # 认证信息解析
        certifications = []
        for cert in raw_data.get("certifications", []):
            certifications.append({
                "type": cert.get("type"),  # 认证类型
                "number": cert.get("number"),  # 认证编号
                "issuer": cert.get("issuer"),  # 发证机构
                "issue_date": cert.get("issueDate"),  # 发证日期
                "expiry_date": cert.get("expiryDate"),  # 有效期至
                "image_url": cert.get("imageUrl")  # 认证证书图片
            })
        
        # 库存信息解析
        inventory = {
            "total_stock": raw_data.get("totalStock"),
            "warehouses": []
        }
        for wh in raw_data.get("warehouseInventories", []):
            inventory["warehouses"].append({
                "id": wh.get("warehouseId"),
                "name": wh.get("warehouseName"),
                "location": wh.get("location"),  # 仓库位置
                "stock": wh.get("stock"),
                "lock_stock": wh.get("lockStock")  # 锁定库存
            })
        
        # 包装与物流信息
        logistics = {
            "packaging": {
                "length": raw_data.get("packageLength"),
                "width": raw_data.get("packageWidth"),
                "height": raw_data.get("packageHeight"),
                "weight": raw_data.get("packageWeight"),
                "unit": raw_data.get("packageUnit")
            },
            "delivery": {
                "min_delivery_days": raw_data.get("minDeliveryDays"),
                "max_delivery_days": raw_data.get("maxDeliveryDays"),
                "support_batch": raw_data.get("supportBatch", False),  # 是否支持批量发货
                "special_logistics": raw_data.get("specialLogistics", False)  # 是否需要特殊物流
            }
        }
        
        # 售后服务信息
        after_sales = {
            "support_return": raw_data.get("supportReturn", False),
            "return_days": raw_data.get("returnDays"),
            "maintenance_service": raw_data.get("maintenanceService", []),  # 维修服务
            "technical_support": raw_data.get("technicalSupport", False)  # 是否提供技术支持
        }
        
        return {
            "success": True,
            "base_info": base_info,
            "price_info": price_info,
            "tech_params": tech_params,
            "certifications": certifications,
            "inventory": inventory,
            "logistics": logistics,
            "after_sales": after_sales,
            "images": {
                "main_images": raw_data.get("mainImages", []),
                "detail_images": raw_data.get("detailImages", []),
                "tech_images": raw_data.get("techImages", []),  # 技术图纸
                "cert_images": raw_data.get("certImages", [])   # 认证证书图片
            }
        }
    
    def _parse_wholesale_price(self, wholesale_data: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
        """解析批发价格体系"""
        wholesale_prices = []
        for item in wholesale_data:
            wholesale_prices.append({
                "min_quantity": item.get("minQuantity"),
                "max_quantity": item.get("maxQuantity"),
                "price": item.get("price"),
                "discount": item.get("discount")  # 折扣比例
            })
        return wholesale_prices

# 使用示例
if __name__ == "__main__":
    # 替换为你的应用信息
    APP_KEY = "your_app_key"
    APP_SECRET = "your_app_secret"
    REDIRECT_URI = "your_redirect_uri"
    
    # 初始化API客户端
    jd_industry_api = JDIndustryProductAPI(APP_KEY, APP_SECRET, REDIRECT_URI)
    
    # 首次使用需要获取授权码
    # print("请访问以下URL进行授权:")
    # print(jd_industry_api.get_auth_url())
    # code = input("请输入授权后获取的code: ")
    # jd_industry_api.get_access_token(code=code)
    
    # 已获取过token的情况,可直接使用refresh_token刷新
    # jd_industry_api.refresh_token = "your_refresh_token"
    # jd_industry_api.get_access_token(refresh_token=jd_industry_api.refresh_token)
    
    # 示例:获取商品详情(替换为实际商品ID)
    if jd_industry_api.access_token:
        product_detail = jd_industry_api.get_product_detail(
            product_id="100012345678",
            need_tech_param=True,
            need_cert=True,
            need_inventory=True
        )
        
        if product_detail["success"]:
            print(f"商品名称: {product_detail['base_info']['name']}")
            print(f"型号: {product_detail['base_info']['model']}")
            print(f"零售价: {product_detail['price_info']['retail_price']}{product_detail['price_info']['currency']}")
            print(f"技术参数组数: {len(product_detail['tech_params'])}")
            print(f"认证数量: {len(product_detail['certifications'])}")
            print(f"总库存: {product_detail['inventory']['total_stock']}")
        else:
            print(f"获取失败: {product_detail['error_msg']}(错误码: {product_detail.get('error_code')})")
    else:
        print("无法获取有效的访问令牌")
    

四、代码核心功能解析

1. 认证机制实现

完整实现 OAuth2.0 认证流程,支持首次授权和令牌刷新

自动处理令牌过期问题,确保接口调用连续性

提供授权 URL 生成方法,简化首次接入流程

2. 工业数据解析增强

针对工业商品特性设计数据结构,重点解析技术参数、认证信息等专业字段

提取多维度价格体系(零售 / 批发 / 企业集采),适配 B2B 采购场景

解析库存分布、物流信息和售后服务,满足供应链管理需求

3. 签名与安全优化

严格按照京东工业 API 规范实现签名生成逻辑

采用毫秒级时间戳,避免时间同步问题导致的签名失效

完整保留参数处理逻辑,确保签名准确性

4. 错误处理机制

统一返回格式,包含成功标识、业务数据及错误信息

处理令牌无效、过期等常见认证问题

捕获 HTTP 请求异常,提供详细的故障排查依据

五、实战注意事项

1. 接口权限与申请

京东工业 API 需企业资质申请,个人开发者无法接入

不同等级的企业账号拥有不同的接口权限,高级权限需单独申请

部分敏感数据(如详细库存分布)需要特殊权限审批

2. 调用策略优化

技术参数和认证信息等数据更新频率低,建议本地缓存(6-24 小时)

库存数据实时性要求高,建议按需实时获取

批量获取商品详情时,需控制请求频率(建议 QPS≤5)

3. 工业场景适配

型号和规格是工业商品的核心标识,需重点处理和存储

认证信息需验证有效期,对过期认证商品进行风险提示

批发价格存在阶梯区间,需完整解析用于采购量决策

4. 安全与合规

妥善保管 app_secret 和 access_token,避免泄露

生产环境建议部署在服务端,禁止客户端直接调用

数据使用需遵守京东工业开放平台的开发者协议

六、功能扩展方向

商品对比工具:基于详情数据实现多维度参数对比,辅助采购决策

合规检查系统:自动校验商品认证是否满足行业标准和项目要求

库存预警功能:结合库存数据和历史采购量,实现关键物料预警

价格趋势分析:定期获取价格数据,分析价格波动规律

通过本文提供的方案,开发者可以快速实现京东工业平台商品详情数据的对接,为工业采购系统、供应链管理工具等应用提供精准的数据支持。实际开发中,建议结合具体工业领域(如制造业、能源业等)的特性,进一步优化数据解析和应用逻辑。​​​​

审核编辑 黄宇

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 接口
    +关注

    关注

    33

    文章

    9443

    浏览量

    156117
  • API
    API
    +关注

    关注

    2

    文章

    2146

    浏览量

    66205
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    标题:技术实战 | 如何通过API接口高效获取亚马逊平台商品详情数据

    、 为什么需要亚马逊商品详情API? 对于开发者、数据分析师和电商从业者而言,手动采集商品信息效率低下且难以规模化。通过API
    的头像 发表于 11-14 15:31 246次阅读
    标题:技术<b class='flag-5'>实战</b> | 如何通过API<b class='flag-5'>接口</b>高效获取亚马逊<b class='flag-5'>平台商品</b><b class='flag-5'>详情</b><b class='flag-5'>数据</b>

    京东平台获取商品详情数据API接口技术解析

    ​  在电商系统开发、价格监控、竞品分析等场景中,获取商品的原始详情数据是基础且关键的一环。京东作为国内领先的电商
    的头像 发表于 11-13 14:35 277次阅读
    <b class='flag-5'>京东平台</b>获取<b class='flag-5'>商品</b><b class='flag-5'>详情</b>原<b class='flag-5'>数据</b>API<b class='flag-5'>接口</b>技术<b class='flag-5'>解析</b>

    如何通过API获取1688平台商品详情

    获取商品详情,包括API概述、访问方法、请求示例和代码实现。 1. API概述 1688平台提供了一系列开放API接口,允许
    的头像 发表于 11-11 14:00 252次阅读
    如何通过API获取1688<b class='flag-5'>平台商品</b><b class='flag-5'>详情</b>

    京东商品详情 ID(即 SKU ID)获取商品详细信息参数

    ​ 利用京东商品详情 ID(即 SKU ID)获取商品详细信息,可通过京东开放平台官方 API
    的头像 发表于 11-11 10:47 280次阅读
    <b class='flag-5'>京东</b><b class='flag-5'>商品</b><b class='flag-5'>详情</b> ID(即 SKU ID)获取<b class='flag-5'>商品</b>详细信息参数

    淘宝商品详情API接口技术解析实战应用

    随着电商行业的快速发展,数据驱动的决策模式已成为企业核心竞争力的重要组成部分。淘宝作为国内领先的电商平台,其开放平台提供的商品详情API
    的头像 发表于 11-04 09:50 123次阅读

    全网最全面介绍京东API接口指南

    。本指南将全面解析京东API接口,涵盖从入门到实战的完整流程,帮助开发者高效利用
    的头像 发表于 10-29 16:02 1057次阅读
    全网最全面介绍<b class='flag-5'>京东</b>API<b class='flag-5'>接口</b><b class='flag-5'>指南</b>

    闲鱼平台获取商品详情API接口

    ​  闲鱼是阿里巴巴旗下的二手交易平台,为开发者提供了丰富的API接口,方便获取商品数据。本文将详细介绍如何通过API获取商品
    的头像 发表于 10-27 16:01 596次阅读
    闲鱼<b class='flag-5'>平台</b>获取<b class='flag-5'>商品</b><b class='flag-5'>详情</b>API<b class='flag-5'>接口</b>

    5 大主流电商商品详情解析实战手册:淘宝 / 京东 / 拼多多 / 1688 / 唯品会核心字段提取 + 反爬应对 + 代码示例

    本文详解淘宝、京东、拼多多、1688、唯品会五大电商平台商品详情页的数据解析逻辑,涵盖价格、SKU、库存、供应商等核心字段提取,针对各
    的头像 发表于 10-13 15:02 1565次阅读

    API实战指南:如何高效采集京东商品详情数据?这几个接口必须掌握!

    在电商领域,无论是做数据分析、竞品监控,还是搭建自己的商品推荐系统,采集商品详情数据都是一项基础且重要的工作。
    的头像 发表于 10-13 11:39 194次阅读

    京东商品详情接口实战解析:从调用优化到商业价值挖掘(附避坑代码)

    本文深入解析京东商品详情接口jd.union.open.goods.detail.query,涵盖核心特性、权限限制、关键参数及调用避坑
    的头像 发表于 10-10 09:28 506次阅读
    <b class='flag-5'>京东</b><b class='flag-5'>商品</b><b class='flag-5'>详情</b><b class='flag-5'>接口实战</b><b class='flag-5'>解析</b>:从调用优化到商业价值挖掘(附避坑代码)

    别踩分页坑!京东商品详情接口实战指南:从并发优化到数据完整性闭环

    京东商品详情接口(jingdong.ware.get)是电商数据开发的核心难点,本文详解其权限申
    的头像 发表于 09-30 15:50 854次阅读

    VVIC 平台商品详情接口高效调用方案:从签名验证到数据解析全流程

    本文详解VVIC平台商品详情接口调用全流程,涵盖参数配置、签名生成、异常处理与数据解析,提供可复用的Python代码及避坑
    的头像 发表于 09-23 10:28 385次阅读

    苏宁开放平台商品详情接口实战:多维度数据获取与结构化处理(附核心代码 + 避坑指南

    本文深入解析苏宁开放平台商品详情接口的技术对接方案,重点介绍其多维度数据获取优势及线下零售场景适配性。文章从
    的头像 发表于 09-18 10:05 435次阅读

    阿里巴巴开放平台商品详情接口实操:数据解析 + 核心实现方案(附避坑指南

    本文提供阿里巴巴商品详情接口的实用开发指南,涵盖B2B场景下的核心功能实现。重点解析
    的头像 发表于 09-17 13:54 288次阅读

    如何利用京东商品详情id拿到商品的详细信息 示例展示

    利用京东商品详情 ID(即 SKU ID)获取商品详细信息,可通过京东开放平台官方 API 或非
    的头像 发表于 07-10 09:37 994次阅读