以下是使用Python采集京东商品评论API的完整代码示例,包含JSON数据解析和反爬处理:
1. 准备工作
安装必要库:
bash
pip install requests fake_useragent
2. 核心代码实现
python
python
import requests
import json
import time
from fake_useragent import UserAgent
import hashlib
import random
class JDCommentScraper:
def __init__(self, sku_id):
self.sku_id = sku_id # 商品ID(如:100012014970)
self.base_url = "https://club.jd.com/comment/productPageComments.action"
self.ua = UserAgent()
def generate_sign(self, params):
"""模拟京东签名算法(简化版)"""
sorted_params = sorted(params.items(), key=lambda x: x[0])
raw_str = "".join([f"{k}{v}" for k, v in sorted_params]) + "你的加密密钥" # 实际需逆向京东签名算法
return hashlib.md5(raw_str.encode()).hexdigest()
def get_comments(self, page=1, score=0, sort_type=5):
"""获取商品评论"""
headers = {
"User-Agent": self.ua.random,
"Referer": f"https://item.jd.com/{self.sku_id}.html",
}
params = {
"productId": self.sku_id,
"score": score, # 0:全部, 1:差评, 2:中评, 3:好评
"sortType": sort_type, # 5:推荐, 6:时间
"page": page,
"pageSize": 10,
"callback": "fetchJSON_comment98", # 京东JSONP回调函数名
"_": str(int(time.time() * 1000)), # 时间戳
}
# 实际开发中需替换为合法签名(需逆向京东签名算法)
# params["sign"] = self.generate_sign(params)
try:
response = requests.get(
url=self.base_url,
headers=headers,
params=params,
timeout=10
)
# 处理JSONP响应(去除回调函数名)
if response.status_code == 200:
json_str = response.text.replace("fetchJSON_comment98(", "").replace(");", "")
data = json.loads(json_str)
return data
else:
print(f"请求失败,状态码: {response.status_code}")
return None
except Exception as e:
print(f"请求异常: {e}")
return None
def parse_comments(self, data):
"""解析评论数据"""
if not data or "comments" not in data:
return []
comments = []
for item in data["comments"]:
comment = {
"id": item.get("id"),
"content": item.get("content"),
"score": item.get("score"),
"nickname": item.get("nickname"),
"creation_time": item.get("creationTime"),
"images": [img.get("imgUrl") for img in item.get("images", [])],
"after_comment": item.get("afterUserComment", {}).get("content"),
}
comments.append(comment)
return comments
def run(self, max_pages=5):
"""主采集逻辑"""
all_comments = []
for page in range(1, max_pages + 1):
print(f"正在采集第 {page} 页...")
data = self.get_comments(page=page)
if data:
comments = self.parse_comments(data)
all_comments.extend(comments)
# 随机延迟,避免触发反爬
time.sleep(random.uniform(1, 3))
else:
break
return all_comments
# 使用示例
if __name__ == "__main__":
scraper = JDCommentScraper(sku_id="100012014970") # 替换为目标商品ID
comments = scraper.run(max_pages=3)
# 保存为JSON文件
with open("jd_comments.json", "w", encoding="utf-8") as f:
json.dump(comments, f, ensure_ascii=False, indent=2)
print(f"共采集 {len(comments)} 条评论,已保存到 jd_comments.json")
3. 关键说明
-
签名算法
- 京东API实际使用
sign
参数验证请求合法性,需逆向其JS加密逻辑(可通过浏览器调试sign
生成过程)。 - 示例中简化了签名逻辑,实际需替换为合法签名。
- 京东API实际使用
-
JSONP处理
- 京东返回的是JSONP格式(如
fetchJSON_comment98({...});
),需去除回调函数名后解析JSON。
- 京东返回的是JSONP格式(如
-
反爬策略
- User-Agent轮换 :使用
fake_useragent
模拟不同浏览器。 - 请求间隔:随机延迟1-3秒避免高频请求。
- Referer头:必须携带商品页URL作为Referer。
- User-Agent轮换 :使用
-
字段解析
- 评论内容、评分、图片、追评等关键字段已提取,可根据需求扩展。
4. 输出示例(jd_comments.json)
css
json
[ { "id": 123456789, "content": "包装完好,物流速度快,手机运行流畅", "score": 5, "nickname": "jd_7e8f9g", "creation_time": "2023-01-01 10:00:00", "images": [ "//img30.360buyimg.com/n1/s450x450_jfs/t1/213456/7/8901/123456/63d1f2a1E12345678/1a2b3c4d5e6f7g8h.jpg" ],
"after_comment": "使用一周后无卡顿,推荐购买!"
},
{
"id": 987654321,
"content": "屏幕有亮点,申请换货中",
"score": 1,
"nickname": "jd_9a8b7c",
"creation_time": "2023-01-02 15:30:00",
"images": [],
"after_comment":
}
]