一、项目背景:为什么要分析京东手机评论数据?
现在买手机,大家都会先看评论——但京东上某款手机动辄几万条评论,手动翻根本看不出规律:
- 商家想知道“用户最在意手机的哪些点?(是续航还是性能?)”“哪些型号差评多,需要改进?”;
- 消费者想知道“同价位手机里,哪款好评率最高?”“大家吐槽的问题是不是普遍存在?”。
我的毕业设计目标就是解决这个“信息过载”问题:用Python爬取京东热门手机评论,通过数据清洗、情感分析,最后用Echarts做可视化展示,让“评论数据”变成“看得见的洞察”——比如用词云显示高频评价词,用折线图看价格与好评率的关系,帮商家和消费者快速获取关键信息。
二、核心技术栈:从爬取到可视化的全套工具
整个项目分“数据采集→存储→分析→可视化”4步,技术栈都是Python生态+前端框架,上手难度低,适合本科生:
| 技术模块 | 具体工具/库 | 核心作用 |
|---|---|---|
| 数据采集 | Python + requests + 正则 | 模拟浏览器请求京东商品页,爬取手机评论(内容、评分、时间、用户昵称),避开反爬机制。 |
| 数据存储 | MySQL + CSV | 用CSV临时存储爬取的原始数据,清洗后导入MySQL,方便后续查询和分析(比如按品牌筛选评论)。 |
| 数据预处理 | Pandas + jieba | 清洗数据(去重、删无效评论)、文本分词(把“手机续航很给力”拆成“手机”“续航”“给力”)、情感打分。 |
| 可视化展示 | Echarts + Flask + Vue | 用Flask写后端接口(从MySQL取数据),Vue搭前端页面,Echarts画图表(词云、柱状图、折线图等)。 |
| 情感分析 | 自定义情感词典 | 给每条评论打情感分(正面1-5分,负面-1-0分),统计某款手机的整体情感倾向。 |
三、项目全流程:从爬取评论到可视化的5步实战
3.1 第一步:数据采集——爬取京东手机评论
核心是用requests模拟请求,处理京东的反爬(比如设置User-Agent、Cookie),这里以“iPhone 15”为例,贴关键代码:
3.1.1 爬取准备:解决反爬问题
京东会检测“非浏览器请求”,所以要先做两件事:
- 打开京东评论页,按F12→Network,找到评论接口的Request Headers,复制User-Agent和Cookie;
- 分析评论接口规律:京东评论是分页加载的,接口URL里的“page”参数控制页码,每次请求10条评论。
3.1.2 核心爬虫代码
import requests
import json
import csv
import time
# 1. 配置请求头(从浏览器复制,替换成你的)
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0.0.0 Safari/537.36",
"Cookie": "你的Cookie", # 关键!没有Cookie会被拒绝访问
"Referer": "https://item.jd.com/100060000000.html" # 商品详情页URL
}
# 2. 评论接口URL(page参数控制页码,0=第1页,1=第2页...)
def get_comment_url(page):
return f"https://club.jd.com/comment/productPageComments.action?productId=100060000000&score=0&sortType=5&page={page}&pageSize=10&isShadowSku=0&fold=1"
# 3. 爬取单页评论
def crawl_one_page(page):
url = get_comment_url(page)
try:
# 加延迟,避免被封IP
time.sleep(2)
response = requests.get(url, headers=headers)
if response.status_code == 200:
data = json.loads(response.text)
comments = data["comments"] # 评论列表在comments字段里
comment_list = []
for com in comments:
# 提取需要的字段
comment_info = {
"商品ID": "100060000000",
"评论内容": com["content"],
"评分": com["score"], # 1-5分
"评论时间": com["creationTime"],
"用户昵称": com["nickname"]
}
comment_list.append(comment_info)
return comment_list
else:
print(f"请求失败,状态码:{response.status_code}")
return []
except Exception as e:
print(f"爬取出错:{e}")
return []
# 4. 爬取多页,保存到CSV
def crawl_multiple_pages(start_page, end_page):
# 打开CSV文件,写入表头
with open("京东iPhone15评论.csv", "w", newline="", encoding="utf-8-sig") as f:
fieldnames = ["商品ID", "评论内容", "评分", "评论时间", "用户昵称"]
writer = csv.DictWriter(f, fieldnames=fieldnames)
writer.writeheader()
# 循环爬取每一页
for page in range(start_page, end_page):
print(f"正在爬取第{page+1}页...")
comments = crawl_one_page(page)
if comments:
for com in comments:
writer.writerow(com)
print("爬取完成!")
# 调用函数:爬取前50页(共500条评论)
crawl_multiple_pages(0, 50)
3.1.3 爬取结果
最终得到CSV文件,包含500条评论,每条有“商品ID、评论内容、评分、时间、昵称”,后续所有分析都基于这个数据集。
3.2 第二步:数据预处理——清洗+分词+情感打分
爬取的原始数据有“脏数据”(比如空评论、重复评论),需要用Pandas处理,还要给评论分词、打情感分:
3.2.1 数据清洗代码
import pandas as pd
# 1. 读取CSV数据
df = pd.read_csv("京东iPhone15评论.csv", encoding="utf-8-sig")
# 2. 数据清洗
# 去除重复评论(根据“评论内容”去重)
df = df.drop_duplicates(subset=["评论内容"], keep="first")
# 去除空值(评论内容为空的行)
df = df.dropna(subset=["评论内容"])
# 过滤无效评论(长度<5的评论,比如“不错”“好”)
df = df[df["评论内容"].str.len() >= 5]
# 3. 保存清洗后的数据
df.to_csv("京东iPhone15评论_清洗后.csv", index=False, encoding="utf-8-sig")
print(f"清洗前:{len(df_raw)}条")
print(f"清洗后:{len(df)}条")
print("清洗完成,保存到新CSV!")
3.2.2 文本分词与情感分析
用jieba分词,再用自定义情感词典给评论打分(正面词加1分,负面词减1分):
import jieba
import pandas as pd
# 1. 加载自定义情感词典(自己整理的手机相关词,比如“续航好”“卡顿”)
positive_words = ["流畅", "续航好", "像素高", "手感棒", "清晰", "给力"]
negative_words = ["卡顿", "续航差", "发热", "像素低", "卡顿", "掉电快"]
# 2. 分词函数
def cut_text(text):
return jieba.lcut(text) # 精确分词
# 3. 情感打分函数
def get_sentiment_score(text):
words = cut_text(text)
score = 0
for word in words:
if word in positive_words:
score += 1
elif word in negative_words:
score -= 1
# 归一化到1-5分(原始分范围:-5~5,映射到1-5)
normalized_score = (score + 5) / 10 * 4 + 1
return round(normalized_score, 1)
# 4. 给评论打分
df = pd.read_csv("京东iPhone15评论_清洗后.csv", encoding="utf-8-sig")
df["分词结果"] = df["评论内容"].apply(cut_text)
df["情感得分"] = df["评论内容"].apply(get_sentiment_score)
# 5. 保存带情感分的数据到MySQL(用pandas的to_sql方法)
from sqlalchemy import create_engine
# 连接MySQL(替换成你的数据库信息)
engine = create_engine("mysql+pymysql://用户名:密码@localhost:3306/京东评论数据库?charset=utf8mb4")
# 写入数据库表
df.to_sql("iPhone15评论", engine, if_exists="replace", index=False)
print("数据已写入MySQL!")
3.3 第三步:可视化实现——用Echarts画6类核心图表
前端用Vue搭页面,后端用Flask写接口从MySQL取数据,最后用Echarts可视化,重点展示6类图表,每类都有“业务意义+代码片段”:
3.3.1 图表1:评论情感分布柱状图——看正面/负面评论占比
业务意义:快速判断某款手机的整体评价(比如正面评论占80%,说明口碑好)。
Echarts核心代码:
// 从Flask接口获取情感分布数据(比如:正面400条,中性50条,负面50条)
axios.get("/api/comment_sentiment?productId=100060000000").then(res => {
const data = res.data;
const myChart = echarts.init(document.getElementById("sentimentChart"));
const option = {
title: { text: "iPhone 15评论情感分布" },
xAxis: { type: "category", data: ["正面", "中性", "负面"] },
yAxis: { type: "value", name: "评论数量" },
series: [{
type: "bar",
data: [data.positive, data.neutral, data.negative],
itemStyle: { color: ["#4CAF50", "#FFC107", "#F44336"] } // 绿/黄/红
}]
};
myChart.setOption(option);
});
3.3.2 图表2:高频词云图——看用户最关注的点
业务意义:词越大说明提到次数越多(比如“续航”“流畅”最大,说明用户最在意这两点)。
Echarts核心代码:
axios.get("/api/comment_keywords?productId=100060000000").then(res => {
const keywords = res.data; // 格式:[{name: "续航", value: 200}, {name: "流畅", value: 180}, ...]
const myChart = echarts.init(document.getElementById("wordCloud"));
const option = {
title: { text: "iPhone 15评论高频词云" },
series: [{
type: "wordCloud",
shape: "circle",
left: "center",
top: "center",
width: "80%",
height: "80%",
textStyle: {
color: function() {
return `rgb(${Math.floor(Math.random()*255)}, ${Math.floor(Math.random()*255)}, ${Math.floor(Math.random()*255)})`;
}
},
data: keywords
}]
};
myChart.setOption(option);
});
3.3.3 图表3:价格与好评率折线图——看价格是否影响口碑
业务意义:比如“3000-4000元价位好评率最高”,帮商家定最优定价。
Echarts核心代码:
axios.get("/api/price_rating").then(res => {
const data = res.data; // 格式:{priceRanges: ["2000以下", "2000-3000", ...], ratings: [85, 90, ...]}
const myChart = echarts.init(document.getElementById("priceRatingChart"));
const option = {
title: { text: "手机价格与好评率关系" },
xAxis: { type: "category", data: data.priceRanges },
yAxis: { type: "value", name: "好评率(%)", max: 100 },
series: [{
type: "line",
data: data.ratings,
symbol: "circle", // 圆点标记
lineStyle: { width: 3, color: "#2196F3" }
}]
};
myChart.setOption(option);
});
3.3.4 其他图表
还实现了“店铺评分排名柱状图”“评论时间趋势折线图”“不同品牌情感对比雷达图”,核心逻辑类似——都是从后端取数据,用Echarts配置对应图表类型。
3.4 第四步:系统整体效果
最终的系统界面分3个模块:
- 数据概览:显示某款手机的评论总数、平均评分、正面评论占比;
- 可视化图表:6类图表按需切换,支持按品牌/价格筛选;
- 后台管理:查看原始评论、导出数据(CSV/Excel)、更新爬虫任务。
四、毕业设计复盘:踩过的坑与经验
4.1 那些踩过的坑
-
京东反爬导致IP被封
- 问题:一开始没加延迟,连续爬100页,IP被封,无法访问京东;
- 解决:在爬虫代码里加
time.sleep(2)(每爬1页停2秒),同时用代理IP池(免费的比如西刺代理),轮换IP爬取。
-
情感分析打分不准
- 问题:一开始用简单的词匹配,比如“不流畅”会被误判为正面(因为有“流畅”);
- 解决:优化情感词典,加入否定词处理(比如“不+正面词”算负面),同时调整打分权重(比如“发热严重”比“发热”减更多分)。
-
Echarts中文乱码
- 问题:前端页面的图表标题、坐标轴标签显示“方框”;
- 解决:在Vue项目的
index.html里引入中文字体(比如微软雅黑),并在Echarts的textStyle里指定字体。
4.2 给学弟学妹的建议
-
爬取数据前先分析接口
不要直接爬网页HTML(京东评论是动态加载的,HTML里没有评论内容),一定要用F12找评论接口(JSON格式),这样爬取效率高,还能避开页面解析的麻烦。 -
数据清洗要“狠”
原始数据里有很多无效评论(比如“此用户未填写评论”“好评!”),一定要过滤掉,否则会影响后续情感分析的准确性——我一开始没过滤,导致情感分偏高10%,清洗后才恢复正常。 -
可视化要“为业务服务”
不要为了炫技做复杂图表,比如用雷达图对比10个品牌的情感分,不如用柱状图只展示Top5,更直观。记住:可视化的核心是“传递信息”,不是“好看”。
五、项目资源获取
完整项目包含:
- 爬虫代码:京东评论爬取脚本(含反爬策略、多线程爬取);
- 分析代码:数据清洗、情感分析、MySQL存储代码(注释清晰);
- 前后端代码:Flask后端接口(10+个API)、Vue前端页面(含Echarts配置);
- 情感词典:手机领域专用的正面/负面词库(可直接用);
- 答辩PPT:含系统架构、实现效果、测试结果,可直接修改;
- 测试数据:5款热门手机的评论数据(共5000+条,CSV+MySQL格式)。
如果本文对你的电商数据分析、Python爬虫学习或毕业设计有帮助,欢迎点赞 + 收藏 + 关注,后续