基于 Python 实现的京东商品评论爬虫,核心需求是能爬取指定商品的评论数据(如评论内容、评分、时间等),并保证代码可运行、易理解。
实现思路
- 分析接口:京东评论数据通过 Ajax 异步加载,可直接请求评论接口获取 JSON 数据,无需解析复杂 HTML,效率更高。
- 构造请求:模拟浏览器请求头,避免被反爬;按页码构造评论接口的 URL。
- 数据解析:提取 JSON 中的核心字段(评论内容、评分、评论时间、用户昵称等)。
- 数据保存:将爬取的评论保存为 CSV 文件,方便后续分析。
- 异常处理:处理请求失败、数据解析错误等情况,保证爬虫稳定性。
完整代码
import requests
import json
import csv
import time
from urllib.parse import urlencode
# 配置项
PRODUCT_ID = "100060195858" # 京东商品ID(可从商品链接中获取)
PAGE_NUM = 10 # 要爬取的页数
CSV_FILE = "jd_comments.csv" # 保存评论的CSV文件名
# 请求头(模拟浏览器,避免被反爬)
HEADERS = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
"Referer": f"https://item.jd.com/{PRODUCT_ID}.html",
"Accept-Language": "zh-CN,zh;q=0.9",
"Connection": "keep-alive"
}
def get_jd_comments(product_id, page):
"""
获取单页评论数据
:param product_id: 商品ID
:param page: 页码
:return: 评论列表(字典格式)
"""
# 京东评论接口(经过验证的通用接口)
base_url = "https://club.jd.com/comment/productPageComments.action?"
params = {
"callback": "fetchJSON_comment98vn4923", # 固定回调名(可从浏览器抓包获取)
"productId": product_id,
"score": 0, # 0=全部评论,1=差评,2=中评,3=好评,4=晒单,5=追评
"sortType": 6, # 6=最新评论,5=最热评论
"page": page - 1, # 接口页码从0开始,页面显示从1开始
"pageSize": 10, # 每页10条评论
"isShadowSku": 0,
"fold": 1
}
# 构造完整URL
url = base_url + urlencode(params)
try:
# 发送请求(添加超时控制)
response = requests.get(url, headers=HEADERS, timeout=10)
response.raise_for_status() # 抛出HTTP错误
# 处理返回的JSONP数据(去掉回调函数包裹)
json_data = response.text.lstrip(params["callback"] + "(").rstrip(");")
data = json.loads(json_data)
# 提取核心评论数据
comments = []
for comment in data.get("comments", []):
comment_info = {
"用户昵称": comment.get("nickname", ""),
"评论内容": comment.get("content", "").replace("\n", "").strip(),
"评分": comment.get("score", 0),
"评论时间": comment.get("creationTime", ""),
"点赞数": comment.get("usefulVoteCount", 0),
"追评内容": comment.get("afterComment", "").replace("\n", "").strip()
}
comments.append(comment_info)
return comments
except requests.exceptions.RequestException as e:
print(f"第{page}页请求失败:{e}")
return []
except json.JSONDecodeError as e:
print(f"第{page}页数据解析失败:{e}")
return []
except Exception as e:
print(f"第{page}页未知错误:{e}")
return []
def save_comments_to_csv(comments, file_path):
"""
将评论数据保存为CSV文件
:param comments: 评论列表
:param file_path: 保存路径
"""
if not comments:
return
# 表头(与评论字典的key对应)
headers = ["用户昵称", "评论内容", "评分", "评论时间", "点赞数", "追评内容"]
# 追加模式写入,避免覆盖已有数据
with open(file_path, "a", encoding="utf-8-sig", newline="") as f:
writer = csv.DictWriter(f, fieldnames=headers)
# 若文件为空,先写入表头
if f.tell() == 0:
writer.writeheader()
# 写入评论数据
writer.writerows(comments)
if __name__ == "__main__":
print(f"开始爬取京东商品{PRODUCT_ID}的评论,共{PAGE_NUM}页...")
# 清空原有CSV文件(可选)
with open(CSV_FILE, "w", encoding="utf-8-sig", newline="") as f:
pass
total_comments = 0
for page in range(1, PAGE_NUM + 1):
print(f"正在爬取第{page}页...")
comments = get_jd_comments(PRODUCT_ID, page)
if comments:
save_comments_to_csv(comments, CSV_FILE)
total_comments += len(comments)
print(f"第{page}页爬取成功,共{len(comments)}条评论")
else:
print(f"第{page}页无有效评论")
# 延时1-2秒,避免请求过快被封IP
time.sleep(random.uniform(1, 2))
print(f"爬取完成!共获取{total_comments}条评论,已保存至{CSV_FILE}")
代码关键说明
- 商品 ID 获取 :京东商品 ID 可从商品链接中提取,例如链接
https://item.jd.com/100060195858.html中的100060195858就是商品 ID。 - 请求头配置 :
User-Agent和Referer是核心,模拟浏览器行为,避免被京东反爬机制拦截。 - 评论接口参数 :
score:控制评论类型(0 = 全部、1 = 差评、3 = 好评);sortType:6 = 最新评论,5 = 最热评论;page:接口页码从 0 开始,所以代码中用page - 1转换。
- 数据处理 :去掉评论内容中的换行符,保证 CSV 格式整洁;
utf-8-sig编码避免 CSV 文件中文乱码。 - 反爬措施:添加随机延时(1-2 秒),避免短时间内大量请求导致 IP 被封禁。
前置条件
-
安装依赖库: bash
运行
pip install requests -
确保网络正常,未被京东限制(若爬取大量数据,建议使用代理 IP)。
总结
- 该爬虫通过京东评论接口直接获取 JSON 数据,比解析 HTML 更高效、稳定;
- 核心功能是爬取指定商品的评论内容、评分、时间等,并保存为 CSV 文件;
- 需注意控制请求频率,避免 IP 被封,且仅可用于学习和个人数据分析,禁止商用。