一、核心背景说明
京东开放平台所有 API 调用都需要签名验证 (MD5/HMAC-SHA256),这是平台的安全机制,防止请求被篡改或伪造。商品评论相关接口(如jd.union.open.goods.jingfen.query包含评论摘要、jd.comment.read.findCommentInfo需特殊权限)的调用流程,核心就是「参数组装→签名生成→接口调用→异常处理」。
二、完整实战方案
1. 核心思路
- 步骤 1:准备调用凭证(appkey、appsecret,需从京东开放平台申请);
- 步骤 2:组装接口请求参数(公共参数 + 业务参数);
- 步骤 3:按京东规则生成签名(核心);
- 步骤 4:发送 HTTP 请求调用接口;
- 步骤 5:针对不同异常类型(签名错误、权限不足、请求超时等)做针对性处理。
2. 完整代码实现(含签名 + 调用 + 异常处理)
python
运行
import requests
import time
import hashlib
import json
from urllib.parse import urlencode, quote_plus
class JDCommentAPIClient:
"""京东开放平台评论相关API客户端(含签名生成、接口调用、异常处理)"""
def __init__(self, appkey, appsecret, server_url="https://api.jd.com/routerjson"):
"""
初始化客户端
:param appkey: 京东开放平台申请的appkey
:param appsecret: 京东开放平台申请的appsecret
:param server_url: 京东API网关地址(正式环境)
"""
self.appkey = appkey
self.appsecret = appsecret
self.server_url = server_url
def _generate_sign(self, params):
"""
生成京东API签名(核心步骤)
签名规则:
1. 按参数名ASCII码升序排序
2. 拼接为 appsecret + key1 + value1 + key2 + value2 + ... + appsecret
3. MD5加密后转大写
:param params: 待签名的参数字典
:return: 签名串
"""
try:
# 步骤1:按参数名升序排序
sorted_params = sorted(params.items(), key=lambda x: x[0])
# 步骤2:拼接字符串(appsecret + key + value 串联)
sign_str = self.appsecret
for key, value in sorted_params:
# 空值不参与签名,值需转字符串
if value is None or value == "":
continue
sign_str += f"{key}{str(value)}"
sign_str += self.appsecret
# 步骤3:MD5加密并转大写
sign = hashlib.md5(sign_str.encode("utf-8")).hexdigest().upper()
return sign
except Exception as e:
raise RuntimeError(f"签名生成失败:{str(e)}")
def call_comment_api(self, method, business_params, version="1.0", format_type="json"):
"""
调用京东评论相关API
:param method: API接口名(如jd.comment.read.findCommentInfo)
:param business_params: 业务参数字典(如商品ID、页码等)
:param version: API版本号
:param format_type: 返回格式(固定json)
:return: 接口返回的原始数据(字典)
"""
# 1. 组装公共参数(所有API必传)
public_params = {
"app_key": self.appkey,
"method": method,
"format": format_type,
"v": version,
"timestamp": time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()), # 北京时间
"sign_method": "md5", # 签名方式(固定md5)
"param_json": json.dumps(business_params, ensure_ascii=False) # 业务参数转JSON
}
# 2. 生成签名
try:
sign = self._generate_sign(public_params)
public_params["sign"] = sign # 把签名加入参数
except RuntimeError as e:
print(f"【签名异常】{e}")
return None
# 3. 发送请求(京东API仅支持POST)
headers = {
"Content-Type": "application/x-www-form-urlencoded; charset=utf-8",
"User-Agent": "JD-OpenAPI-Python-Client/1.0"
}
try:
# 发送POST请求(参数需urlencode编码)
response = requests.post(
url=self.server_url,
data=urlencode(public_params, quote_via=quote_plus),
headers=headers,
timeout=15 # 超时时间15秒
)
response.raise_for_status() # 抛出HTTP状态码异常(4xx/5xx)
# 解析返回结果
result = response.json()
# 4. 处理业务异常(京东API自身的错误码)
if "error_response" in result:
error = result["error_response"]
error_code = error.get("code", "")
error_msg = error.get("msg", "")
sub_code = error.get("sub_code", "")
sub_msg = error.get("sub_msg", "")
raise ValueError(
f"【业务异常】错误码:{error_code},错误信息:{error_msg} "
f"子码:{sub_code},子信息:{sub_msg}"
)
return result
# 异常分类处理
except requests.exceptions.ConnectTimeout:
print("【网络异常】连接超时,请检查网络或京东API网关状态")
return None
except requests.exceptions.ReadTimeout:
print("【网络异常】读取超时,API响应过慢")
return None
except requests.exceptions.HTTPError as e:
print(f"【HTTP异常】状态码:{e.response.status_code},响应内容:{e.response.text}")
return None
except json.JSONDecodeError:
print("【解析异常】API返回非JSON格式数据:", response.text)
return None
except ValueError as e:
print(e)
return None
except Exception as e:
print(f"【未知异常】调用失败:{str(e)}")
return None
# ==================== 实战调用示例 ====================
if __name__ == "__main__":
# 替换为你从京东开放平台申请的真实凭证
APP_KEY = "你的appkey"
APP_SECRET = "你的appsecret"
# 初始化客户端
client = JDCommentAPIClient(appkey=APP_KEY, appsecret=APP_SECRET)
# 示例1:调用商品评论摘要接口(需先申请权限)
# 接口名:jd.union.open.goods.jingfen.query(包含评论数、好评率等)
method = "jd.union.open.goods.jingfen.query"
business_params = {
"skuIds": "100082848364", # 商品ID,多个用逗号分隔
"fields": "commentCount,goodRate,goodCount,generalCount,poorCount" # 需获取的评论相关字段
}
# 调用接口
result = client.call_comment_api(method=method, business_params=business_params)
# 打印结果
if result:
print("接口调用成功,返回数据:")
print(json.dumps(result, ensure_ascii=False, indent=2))
else:
print("接口调用失败(详见上方异常提示)")
3. 关键模块解析
(1)签名生成(核心)
京东签名的核心规则(必须严格遵守,否则签名无效):
- 参数排序:按参数名的 ASCII 码升序排列(如
app_key在method前); - 拼接规则:
appsecret + key1 + value1 + key2 + value2 + ... + appsecret; - 加密方式:MD5 加密后转大写(部分新接口支持 HMAC-SHA256,需对应调整);
- 注意点:空值参数不参与签名,参数值需为原始字符串(不能 urlencode)。
(2)接口调用
- 请求方式:京东开放平台 API仅支持 POST ,参数需
application/x-www-form-urlencoded编码; - 公共参数:
app_key(必填)、method(接口名)、timestamp(北京时间,格式YYYY-MM-DD HH:MM:SS)、sign(签名)等是所有 API 必传的; - 业务参数:需封装为 JSON 字符串,通过
param_json参数传递。
(3)异常处理(分 4 类)
表格
| 异常类型 | 场景说明 | 处理方式 |
|---|---|---|
| 签名异常 | 参数排序错误、appsecret 错误、空值参与签名 | 校验参数排序、核对 appsecret、过滤空值 |
| 网络异常(超时 / 连接失败) | 网络波动、API 网关不可用 | 增加重试机制、延长超时时间 |
| HTTP 异常(4xx/5xx) | 403(权限不足)、400(参数错误)、500(平台故障) | 核对权限、校验参数格式、稍后重试 |
| 业务异常(错误码) | 60000(appkey 无效)、60002(签名错误)、20000(业务参数错误) | 按错误码查京东开放平台文档,针对性修复 |
4. 前置条件与注意事项
-
凭证获取 :
- 需先注册京东开放平台企业账号(https://open.jd.com/),完成资质认证;
- 申请对应评论接口的调用权限(审核周期 1-3 个工作日);
- 获取
appkey和appsecret(需妥善保管,不要泄露)。
-
依赖安装 :
bash
运行
pip install requests -
避坑点 :
timestamp必须是北京时间,且与京东服务器时间误差不超过 10 分钟;- 业务参数中的特殊字符(如中文、空格)需在 JSON 序列化时保留(
ensure_ascii=False); - 不要高频次调用(平台有 QPS 限制,超出会被限流)。