资讯动态

京东商品评论API接口调用全攻略:从申请到数据落库

发布时间:2026/9/7 17:20:14 来源:尧图企业网站定制
京东平台商品评论API接口技术指南做过电商数据采集的朋友应该都熟悉这个场景领导扔过来一个任务“把京东商品评论抓下来分析一下”第一反应是写个爬虫去解析页面结果折腾半天发现京东的反爬越来越狠验证码一个接一个就算侥幸跑到数据字段也不全。实际上京东平台本身是有公开的商品评论API接口的只是很多开发者不知道入口在哪或者卡在了权限申请和签名验证上。这篇文章我会从零开始把京东商品评论API接口的完整调用链路讲清楚包括开放平台资质要求、应用创建、接口权限申请、签名算法、请求参数、返回字段解析、数据入库以及我实际调接口时踩过的各种坑。内容面向有基础Java或Python经验的开发者看完可以直接照着写代码。如果你是刚接触API调用的新手我也尽量把每一处关键点拆开讲明白保证你能顺着流程走通。先说结论京东平台的商品评论API并不是一个完全公开、注册就能用的接口它挂在京东联盟开放平台京东联盟API体系内申请流程和普通开放平台有差异很多开发者没搞清楚这点所以一直在门外打转。搞清楚这个定位是成功调通接口的第一步。1. 先搞懂京东商品评论API到底是什么1.1 这个接口能解决什么业务问题京东商品评论API接口本质上是京东联盟CPS联盟开放平台向开发者提供的一组商品信息查询接口中的一个它专门返回指定商品SKU下的用户评价内容。通过这个接口你可以拿到评论总数、好评率、各星级评论数量分布以及具体的评论列表包括评论内容、评论时间、用户等级、商品属性评分等。它能解决什么业务问题我举几个实际场景竞品分析批量抓取竞品SKU的评论数据分析用户对产品功能、价格、物流、售后各维度的吐槽点和好评点反推竞品的优劣势。选品调研在铺货前通过评论数量走势判断一个商品是爆款还是冷门款通过好评率判断品控是否稳定避免选到“刷单重灾区”商品。舆情监控对自己店铺或供货商品的评论进行监控及时发现差评集中爆发的问题比如批次质量事故、物流大面积投诉提前做舆情预案。商城数据可视化把评论数据落到自己的报表系统里通过API定时拉取替代人工做Excel统计。本质上这是一条合规、稳定的数据通道比爬虫页面解析可靠得多。虽然字段丰富程度不如爬虫能拿到的完整DOM但胜在稳定、合法、字段结构化不会因为页面改版而失效。1.2 为什么京东不开放“纯商品评论API”给你调用这里有个容易踩的认知坑。很多开发者想象中京东应该提供一个类似“ item.comments.get ”这样的独立评论接口注册开放平台账号就能调。实际你去京东开放平台open.jd.com看确实有商品查询相关的API但多数都需要企业资质而且评论类接口通常寄生在京东联盟的“商品详情”接口组里。为什么这么设计底层逻辑是商业战略京东希望把高价值数据开放给能为平台带来流量和成交的合作方而不是单纯给爬虫提供便利。京东联盟接口的定位是服务推广者所以商品评论接口被归入“京东联盟API-商品类”下调用条件里通常包含“已开通京东联盟推广位”甚至部分子接口有“月度GMV要求”。这意味着什么直白地说想调用评论API你需要先注册京东联盟账号、创建推广位、申请API权限而不是傻乎乎去开放平台找错方向。我第一次做这个项目时就绕了弯路——在开放平台找了一整天白白申请了一堆没用的权限。1.3 适用人群与实际调用条件基于我多次调用和帮朋友对接的经验目前能顺利开通并使用京东商品评论API接口的一般是这几类人京东联盟推广者自己有推广位在联盟后台创建过推广链接或物料有正常的推广数据。电商代运营/数据服务商以企业身份入驻京东联盟平台通过API为品牌方提供数据服务。个人技术爱好者只要能通过京东联盟的资质审核个人也可以注册联盟账号也能申请到部分API权限但评论类接口中高敏感字段如用户ID可能被脱敏。需要说明的是京东开放平台的权限政策随业务调整会变化。如果你在应用审核时发现某个接口权限名称不对以开放平台后台当前展示的“可申请API列表”为准。下面我按当前比较常见的“京东联盟-商品评论查询”接口流程来写。2. 调用前必须做好的准备工作2.1 注册京东联盟账号并创建应用调用京东商品评论API接口的第一步是注册一个京东联盟账号。直接在搜索引擎搜索“京东联盟”进入官网用京东账号登录按提示完成实名认证个人实名或企业实名二选一。这一步通常几分钟就能通过审核。登录京东联盟后台后找到“我的合作”-“推广管理”-“媒体管理”创建一个媒体App或网站均可。媒体创建完成后系统会给一个对应的“推广位ID”这个ID在后续API请求中会用到务必保存好。接下来在京东联盟后台找到“API授权”或“开放平台”入口点击“创建应用”。应用名称随便填但应用类型建议选“服务市场”或“自定义工具”因为评论类接口通常不对“导购类”应用开放。创建完成后你会拿到一对关键凭证AppKey应用Key和AppSecret应用密钥。这两个值非常重要AppSecret仅展示一次创建时一定要复制存档。注意我遇到过有人把AppSecret直接贴在代码里又传到GitHub上导致密钥泄露被刷接口。正确做法是存到环境变量或配置中心千万别硬编码提交到公开仓库。2.2 申请评论接口权限应用创建好了不代表就能直接调评论API。在京东联盟开放平台接口权限是“按需申请、后台审核”的。你需要找到“权限管理”-“申请API权限”在接口列表中搜索“商品评论”或“商品详情”相关的接口名称提交申请。申请时通常要填写使用场景说明这里一定要写清楚业务用途。我这边有个小技巧别只写“分析评论数据”尽量写得具体一点比如“用于辅助选品决策分析商品用户反馈为推广选品提供依据”审核通过率会高很多。权限审核时间一般是1-3个工作日。审核通过后在“权限管理”页面能看到该接口的授权状态变为“已开通”。这时打开接口文档页面你会看到完整的请求地址、参数定义和签名规则可以进行联调了。2.3 下载SDK还是自己写签名京东开放平台提供了Java、PHP、Python等语言的SDK推荐优先使用官方SDK能省去不少签名和HTTP封装的麻烦。不过SDK版本迭代较慢有时接口返回的JSON结构更新了SDK解析类没跟上这时候就需要自己写。自己写也没多复杂京东开放平台的签名机制和淘宝、拼多多这类电商平台大同小异用的是MD5密钥拼接的方式。下面我会把完整算法和示例代码贴出来方便你如果不想装SDK或者SDK年久失修时自己动手实现完整调用流程。3. 商品评论API核心接口解析与参数详解3.1 请求地址与公共参数京东联盟商品评论相关API一般通过京东联盟的“宙斯”网关即京东开放平台网关访问请求地址形如https://api.jd.com/routerjson所有请求都需要携带公共参数。公共参数是所有接口通用的它们负责身份认证和请求元信息传递。以京东联盟API为例公共参数一般包括参数名类型必填说明methodString是具体接口名称如jingdong.union.open.goods.queryapp_keyString是应用的AppKeyaccess_tokenString是调用凭证Token可在授权后获取timestampString是请求时间格式yyyy-MM-dd HH:mm:ss与服务器时间差不能超过一定范围formatString否返回格式默认jsonvString是API协议版本一般是2.0sign_methodString是签名算法一般传md5signString是请求签名注意评论接口实际调用时method名称可能随平台调整。这里我拿京东联盟商品查询接口的通用结构来说明真正的评论查询接口往往是jingdong.union.open.goods.comment.query之类的新版接口不同时期命名有差异你需要以自己在“权限管理”里申请到的接口文档为准但调用方式和参数结构基本一致。access_token的获取方式通常有两种一种是OAuth授权后拿到另一种是京东联盟的“服务市场”模式下直接用AppKeyAppSecret换取。如果你是在联盟后台创建应用多数场景下调用商品类接口可以直接使用AppKey和AppSecret生成签名不需要单独的access_token但有些新接口强制要求带token这个要仔细看你申请接口的文档说明。3.2 关键业务参数说明商品评论接口的业务参数核心就几个skuId商品SKU ID就是商品详情页URL里/100012043978.html这一段数字必填。pageIndex页码从1开始。pageSize每页条数一般在1-100之间建议按文档限制设置不要贪多。sortType排序方式常用的是按时间排序或按推荐排序看业务需求。score按星级筛选比如只看差评传1或2看中评传3看好评传4或5。这里有一个容易忽略的点京东评论接口的skuId是纯数字ID不是商品货号Item Code也不是你推广链接里的短链ID。你通过商品搜索API拿到商品列表时返回的skuId可以直接用来查评论。但如果你手里只有推广链接得先解析出真实SKU ID或者调用商品查询接口反查。另外评论接口通常只支持单个SKU查询不支持批量。如果你有100个SKU要查评论就得循环调100次接口。这时候并发控制很重要后面我在“常见问题”里会专门讲限频这件事。3.3 签名生成算法含计算示例签名是京东开放平台API调用中最容易出错、也最重要的一环。签名算法整体逻辑是把所有请求参数不包括sign本身按参数名ASCII码升序排列拼接成key1value1key2value2...的格式然后在拼接串首尾加上AppSecret做MD532位小写得到sign值。我把完整计算过程给大家拆解一下假设AppSecret是abc123请求参数如下app_key: your_app_key method: jingdong.union.open.goods.comment.query timestamp: 2024-05-20 12:00:00 v: 2.0 skuId: 100012043978 pageIndex: 1 pageSize: 10第一步把所有参数名按ASCII码升序排列排除sign本身。排序结果大致是app_key、method、pageIndex、pageSize、skuId、timestamp、v。第二步按“参数名参数值”顺序拼接成字符串app_keyyour_app_keymethodjingdong.union.open.goods.comment.querypageIndex1pageSize10skuId100012043978timestamp2024-05-20 12:00:00v2.0第三步在拼接串首尾加上AppSecretabc123app_keyyour_app_keymethodjingdong.union.open.goods.comment.querypageIndex1pageSize10skuId100012043978timestamp2024-05-20 12:00:00v2.0abc123第四步对这串内容做MD5得到32位小写字符串作为sign参数值。下面给出Java版本的完整签名工具类import java.io.UnsupportedEncodingException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; public class JdSignUtil { public static String createSign(MapString, String params, String appSecret) { // 1. 去除sign本身和空值参数 ListString keys new ArrayList(); for (String key : params.keySet()) { if (!sign.equals(key) params.get(key) ! null !params.get(key).isEmpty()) { keys.add(key); } } // 2. 按ASCII升序排列 Collections.sort(keys); // 3. 拼接 key1value1key2value2 StringBuilder sb new StringBuilder(); for (String key : keys) { sb.append(key).append(params.get(key)); } String source appSecret sb appSecret; // 4. MD5加密 return md5(source); } private static String md5(String source) { try { MessageDigest md MessageDigest.getInstance(MD5); byte[] bytes md.digest(source.getBytes(UTF-8)); StringBuilder result new StringBuilder(); for (byte b : bytes) { String hex Integer.toHexString(b 0xFF); if (hex.length() 1) { result.append(0); } result.append(hex); } return result.toString(); } catch (NoSuchAlgorithmException | UnsupportedEncodingException e) { throw new RuntimeException(MD5签名计算失败, e); } } }注意timestamp参数在签名时要保持和请求时传过去的值完全一致一个空格都不能差。我踩过这种坑先签了名然后重新获取了一次当前时间传过去结果签名校验失败排查了半天才发现是时间不一致。4. 从请求到落地的完整实操流程4.1 组装请求并发送Java示例把所有参数组装好计算签名后通过HTTP POST或GET请求发送到https://api.jd.com/routerjson。这里给出一段完整可运行的Java调用示例import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLEncoder; import java.util.HashMap; import java.util.Map; public class JdCommentApiClient { private static final String API_URL https://api.jd.com/routerjson; public static void main(String[] args) throws Exception { String appKey your_app_key; String appSecret your_app_secret; String method jingdong.union.open.goods.comment.query; String timestamp 2024-05-20 12:00:00; String v 2.0; String skuId 100012043978; MapString, String params new HashMap(); params.put(method, method); params.put(app_key, appKey); params.put(timestamp, timestamp); params.put(format, json); params.put(v, v); params.put(skuId, skuId); params.put(pageIndex, 1); params.put(pageSize, 10); String sign JdSignUtil.createSign(params, appSecret); params.put(sign, sign); // 拼接GET请求URL StringBuilder urlBuilder new StringBuilder(API_URL).append(?); for (Map.EntryString, String entry : params.entrySet()) { urlBuilder.append(URLEncoder.encode(entry.getKey(), UTF-8)) .append() .append(URLEncoder.encode(entry.getValue(), UTF-8)) .append(); } String requestUrl urlBuilder.substring(0, urlBuilder.length() - 1); String response httpGet(requestUrl); System.out.println(response); } private static String httpGet(String urlStr) throws Exception { URL url new URL(urlStr); HttpURLConnection conn (HttpURLConnection) url.openConnection(); conn.setRequestMethod(GET); conn.setConnectTimeout(5000); conn.setReadTimeout(10000); BufferedReader reader new BufferedReader(new InputStreamReader(conn.getInputStream(), UTF-8)); StringBuilder sb new StringBuilder(); String line; while ((line reader.readLine()) ! null) { sb.append(line); } reader.close(); return sb.toString(); } }如果access_token是必填的就在params里加上access_token再参与签名。签名规则不变仍然是所有参数含token按ASCII排序后拼装。这一点容易漏漏了token导致签名对不上接口会直接报“签名错误”。4.2 解析返回的评论数据接口返回的是标准JSON结构评论列表一般嵌套在jingdong_union_open_goods_comment_query_responce之类的响应节点下。结构大致如下{ jingdong_union_open_goods_comment_query_responce: { result: {\code\:200,\data\:{\skuId\:100012043978,\commentCount\:12345,\goodRate\:0.96,\commentList\:[{\id\:\123456789\,\content\:\质量很好物流很快\,\score\:5,\commentTime\:\2024-05-01 10:30:00\,\nickname\:\j***d\,\productSize\:\合适\,\productColor\:\黑色\}]}} } }注意一个比较坑的点京东联盟接口的result字段经常是字符串包裹的JSON而不是直接嵌套的JSON对象。这意味着你需要先取出result字符串再用JSON库二次解析。下面用Java封装一个简单的解析方法import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; public class JdCommentParser { public static void parse(String responseJson) throws Exception { ObjectMapper mapper new ObjectMapper(); JsonNode root mapper.readTree(responseJson); // 注意这里节点名要以实际返回为准 JsonNode respNode root.path(jingdong_union_open_goods_comment_query_responce); String resultStr respNode.path(result).asText(); JsonNode result mapper.readTree(resultStr); if (result.path(code).asInt() ! 200) { System.err.println(接口返回错误: result); return; } JsonNode data result.path(data); int commentCount data.path(commentCount).asInt(); double goodRate data.path(goodRate).asDouble(); System.out.println(评论总数: commentCount , 好评率: goodRate); JsonNode commentList data.path(commentList); for (JsonNode comment : commentList) { String content comment.path(content).asText(); int score comment.path(score).asInt(); String commentTime comment.path(commentTime).asText(); System.out.println(评分: score , 时间: commentTime , 内容: content); } } }4.3 数据落库与定时任务设计拿到评论数据后一般不会临时打印一下就算了通常要落库。我建议按场景选择存储方案轻量分析几千条级别用SQLite或MySQL单表就够了表结构包含评论ID、SKU ID、评论内容、评分、评论时间、点赞数等字段。大规模分析百万条以上考虑Hive或ClickHouse但多数个人项目到不了这个量级不必过度设计。建表SQL可以参考下面这段CREATE TABLE jd_comment ( id VARCHAR(64) PRIMARY KEY COMMENT 评论ID, sku_id VARCHAR(32) NOT NULL COMMENT 商品SKU ID, content TEXT COMMENT 评论内容, score TINYINT COMMENT 评分 1-5, comment_time DATETIME COMMENT 评论时间, nickname VARCHAR(64) COMMENT 用户昵称脱敏, product_size VARCHAR(32) COMMENT 商品规格-尺码, product_color VARCHAR(32) COMMENT 商品规格-颜色, create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT 采集时间, KEY idx_sku (sku_id), KEY idx_time (comment_time) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT京东商品评论采集表;定时任务方面建议使用Quartz或XXL-JOB这类调度框架每天凌晨跑一次增量同步即可。为什么建议增量而不是全量因为评论接口每页能拿到的数据有限全量拉取对接口压力大也容易触达限频阈值。增量同步策略就是记录当前SKU已拉取的最大评论时间下次只拉该时间点之后的新评论这样既省请求次数又高效。4.4 Python版本的快速实现方案考虑到很多做数据分析的同学更熟悉Python我把同一个流程用Python实现一遍核心逻辑完全一致import hashlib import time import requests from urllib.parse import urlencode APP_KEY your_app_key APP_SECRET your_app_secret API_URL https://api.jd.com/routerjson def create_sign(params, secret): # 过滤空值和sign本身 filtered {k: v for k, v in params.items() if v and k ! sign} # 按key排序 sorted_keys sorted(filtered.keys()) source secret .join(f{k}{filtered[k]} for k in sorted_keys) secret return hashlib.md5(source.encode(utf-8)).hexdigest() def fetch_comments(sku_id, page_index1, page_size10): params { method: jingdong.union.open.goods.comment.query, app_key: APP_KEY, timestamp: time.strftime(%Y-%m-%d %H:%M:%S), format: json, v: 2.0, skuId: sku_id, pageIndex: str(page_index), pageSize: str(page_size), } params[sign] create_sign(params, APP_SECRET) resp requests.get(API_URL, paramsparams, timeout10) return resp.json() if __name__ __main__: data fetch_comments(100012043978, 1, 10) print(data)Python版本里有个细节requests库会自动对URL参数做编码但不会改变签名参数本身的拼接顺序。只要签名时用的参数值和你传参时一致就不会出问题。很多新手在这里翻车点在于time.strftime生成的时间和签名时的timestamp不一致——这在单次请求里不会出问题但如果你在循环里多次调用同一函数每次都会重新生成时间需要确保每次调用get/post都使用同一个params字典不要先签了名再改时间。5. 常见问题与排查技巧实录5.1 错误码对照表与京东开放平台API联调最怕的就是报错后看不懂错误码。这里整理一份高频错误码对照表遇事可以直接对号入座错误码错误信息常见原因与解决方式0调用成功正常返回无特殊处理1系统错误京东网关内部异常重试2-3次若仍失败则稍后再试3未授权方法接口权限未开通回后台检查权限申请状态12无效的AppKeyAppKey错误或应用被删除检查配置13签名错误(Sign)签名算法不正确检查AppSecret、参数排序、时间一致性15签名被禁用AppSecret异常检查是否泄露并重置19请求超时服务器时间偏差过大校准本机时间确保timestamp准确100参数错误某个业务参数不合法比如pageSize超出范围、skuId不存在200无权限调用需要更高等级的接口权限联系平台或升级账号资质其中“签名错误”和“无效的AppKey”出现频率最高。签名错误九成是以下三个原因之一参数名排序没按ASCII码、AppSecret拼错注意大小写、timestamp不一致。无效AppKey八成是环境变量没生效或复制时带了空格。5.2 调用频率限制与并发控制京东开放平台对接口QPS每秒请求数有严格限制商品类接口一般限额较低普通应用可能只有1-5 QPS。如果你在代码里用多线程并发拉评论很容易触发“请求过于频繁”的限流错误码。解决思路有两种第一加本地限流。用Guava的RateLimiter或Java的Semaphore控制请求速率每个SKU按顺序走每秒最多发1个请求。第二退避重试。当接口返回限流提示时不要立刻重试而是等1秒、2秒、4秒……指数退避最多重试3次。如果连续多次限流建议拉长任务调度周期。另外提一个经验如果你有多个SKU要拉评论可以把请求分散到不同时间片比如每隔5秒拉一个SKU的第一页然后回头再拉第二页避免短时间内对同一个接口发起连击。5.3 评论数据不全或字段缺失怎么办有时候接口返回成功但评论列表为空或者某个字段缺失。常见原因score参数传了特定星级但该星级下暂时无评论比如新品只有好评传score1自然查不到数据。pageIndex超出了最大页数评论接口一般最多返回前N页超出后返回空列表这是平台侧的数据截断。部分敏感字段如用户昵称、完整头像在未申请高等级权限时被脱敏返回j***d这种掩码昵称。这是正常现象不是接口Bug。遇到字段缺失先打印完整JSON排查别急着怀疑代码。我自己就遇到过因为字段名是commentCnt还是commentCount纠结半天的情况。建议每次都先用接口文档返回的样例JSON和实际JSON做对比确认字段结构再写解析逻辑。5.4 线上调试与日志埋点技巧调这种外部API最忌讳黑盒运行。我在写采集服务时一定会加三层日志请求日志记录完整URL参数脱敏掉sign和响应时间。响应日志记录返回的原始JSON方便事后排查数据问题。异常日志记录重试次数、限流触发频率和错误码。日志级别要区分开正常请求用DEBUG错误响应用WARN网络异常用ERROR。如果线上出现问题直接grep日志里的错误码和skuId能最快定位是哪个商品哪次请求出的问题。提示日志中不要打印完整sign值和AppSecret防止日志文件泄露导致接口被盗刷。我习惯把sign前8位打出来用于核对完整值不落盘。6. API调用之外的一点经验总结京东商品评论API接口从申请权限到真正跑通整个流程不复杂但细节非常多。回到最开始的话题这个接口最大的价值不在于“能拿到评论”而在于它把“数据获取”这件事从灰色地带的爬虫方案变成了合规、稳定、可持续的技术方案。对于需要长期做电商数据分析和选品决策的团队或个人投入精力把这条链路做好后续收益远大于临时性爬虫脚本。最后分享一个我自己在实操中的体会接口的稳定运行很大程度上不取决于接口本身而取决于你调用方的代码质量。参数校验做扎实、限流退避做稳妥、日志埋点做全面、数据落库做幂等这套基本功在任何平台API对接中都通用。京东评论API只是入口真正考验功力的是你围绕这个入口搭起来的那套工程体系。如果后续有时间我打算再写一篇关于如何基于这些评论数据做情感分析和口碑趋势可视化的文章把从“拿到数据”到“用上数据”这段路走完。当前这篇文章的流程和代码已经足够你跑通从申请到落库的完整环节遇到问题欢迎在评论区交流。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价