基于Python的黑悟空评论数据分析系统:从爬虫到可视化完整实战
2026/9/3 18:21:00 网站建设 项目流程

1. 项目背景与功能拆解

在做毕业设计选题时,很多同学会纠结:既要体现技术栈的完整度,又要有足够的数据分析深度,还得保证演示效果直观可见。之前一位学弟选的就是游戏评论方向,最初只想用 Python 爬虫抓几十条评论做词云,做得过程中发现,评论数据从采集、清洗、分词、情感分析到可视化展示,每一步都能拆出不少技术点,最后做成了一个完整的数据分析系统。

本文将围绕“黑悟空评论数据分析系统”展开,从《黑神话:悟空》的玩家评论出发,设计一套具备数据采集、数据存储、文本预处理、情感分析、可视化展示能力的完整项目。这个项目不仅适合作为毕业设计,也适合作为数据分析实战练手项目。

1.1 项目需求分析

黑悟空评论数据分析系统面向的核心业务场景是:从游戏社区、视频平台或电商平台的评论中采集用户反馈,通过数据分析手段量化玩家对游戏的整体评价、各个维度(画面、剧情、战斗、优化等)的关注度与情感倾向。

具体需求拆解如下:

功能模块需求描述核心产出
数据采集获取用户评论数据,至少包含评论内容、评分、时间、点赞数CSV 原始数据集
数据清洗去除重复评论、无效字符、广告内容干净的结构化数据集
文本预处理中文分词、停用词过滤、词频统计高频词表、词云数据
情感分析对每条评论计算情感得分,划分正向、负向、中性情感占比统计
数据分析分析评论长度分布、时间趋势、评分与情感关系分析结论
数据可视化以图表形式展示分析结果词云图、柱状图、折线图
Web 展示将分析结果以网页形式呈现,方便演示与答辩可视化大屏页面

1.2 系统适用场景

这个选题并不局限于“黑悟空”这一款游戏。整个分析链路可以平移到任何带有用户评论的互联网产品上,比如电商平台商品评论、电影评论、App 应用商店评论、外卖平台用户评价等。

之所以选择黑神话悟空作为切入点,是因为该游戏的玩家评论量足够大、情感表达丰富、话题维度多(画面、剧情、优化、战斗手感等),分析出来的结果更容易看出规律,也方便在答辩时讲出业务分析结论。

2. 技术选型与环境准备

技术选型决定了项目的开发效率和演示效果。本系统采用 Python 全栈方案,从数据采集到网页展示全部使用 Python 生态完成,便于在一个语言体系内串联所有功能。

2.1 技术栈说明

技术用途说明
Python 3.8+开发语言本文示例以 Python 3.9 常见环境为基础
requests数据采集模拟 HTTP 请求,获取网页评论数据
pandas数据清洗与分析表格数据处理、统计分析
jieba中文分词对评论内容进行分词处理
snownlp情感分析计算评论情感倾向得分
pyecharts数据可视化生成交互式图表
FlaskWeb 展示搭建本地可视化展示服务
MySQL / SQLite数据存储持久化存储评论数据
WordCloud词云生成绘制评论关键词词云

版本说明:以上库的版本可以根据本地环境灵活调整,示例代码以常见稳定版本为准。如果遇到依赖冲突,优先建议为项目创建独立虚拟环境。

2.2 环境搭建

# 创建虚拟环境 python -m venv wukong_env # 激活虚拟环境(Windows) wukong_env\Scripts\activate # 激活虚拟环境(Mac / Linux) source wukong_env/bin/activate # 安装依赖 pip install requests pandas jieba snownlp pyecharts flask wordcloud matplotlib

如果使用 MySQL 存储,还需要安装连接驱动:

pip install pymysql sqlalchemy

2.3 项目目录结构

为了便于毕业设计论文写作和代码维护,建议目录结构如下:

wukong_comment_system/ ├── data/ │ ├── raw_comments.csv # 原始评论数据 │ ├── cleaned_comments.csv # 清洗后的评论数据 │ └── comment_analysis.db # SQLite 数据库文件 ├── crawler/ │ └── comment_spider.py # 数据采集模块 ├── analysis/ │ ├── data_clean.py # 数据清洗模块 │ ├── text_process.py # 分词与词频统计模块 │ ├── sentiment_analysis.py # 情感分析模块 │ └── visual_analysis.py # 可视化模块 ├── web/ │ ├── app.py # Flask 应用入口 │ └── templates/ │ └── index.html # 展示页面 ├── requirements.txt # 依赖清单 └── README.md # 项目说明文档

3. 数据采集模块设计

3.1 数据来源说明

评论数据的获取方式有多种:可以通过公开 API 获取、通过网页接口解析获取,也可以使用平台导出的数据。为了确保项目合规且可复现,本文以“本地已有评论数据 + 抓取演示接口”的方式说明。

需要注意的是:抓取任何平台数据前,务必确认该平台的服务条款,并控制请求频率。毕业设计演示场景下,建议使用测试数据或已授权的开放数据。

3.2 数据采集代码实现

下面以模拟抓取评论列表的接口为例,演示如何将评论保存到本地 CSV 文件。

# 文件路径:crawler/comment_spider.py import requests import csv import time import random def fetch_comments(page=1, page_size=20): """ 模拟获取评论数据。 在实际项目中,这里需要替换为真实的接口地址和请求参数。 """ # 示例接口地址,仅用于演示代码逻辑 url = "https://example-api.com/comments" params = { "page": page, "page_size": page_size, "game": "black_myth_wukong" } headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" } try: response = requests.get(url, params=params, headers=headers, timeout=10) response.raise_for_status() data = response.json() return data.get("data", {}).get("list", []) except Exception as e: print(f"请求失败:{e}") return [] def save_to_csv(comments, file_path="data/raw_comments.csv"): """将评论数据追加写入 CSV 文件""" if not comments: print("没有获取到评论数据") return fieldnames = ["user", "content", "score", "comment_time", "like_count"] with open(file_path, "a", encoding="utf-8-sig", newline="") as f: writer = csv.DictWriter(f, fieldnames=fieldnames) # 如果文件为空,写入表头 if f.tell() == 0: writer.writeheader() for comment in comments: writer.writerow({ "user": comment.get("user", ""), "content": comment.get("content", ""), "score": comment.get("score", ""), "comment_time": comment.get("comment_time", ""), "like_count": comment.get("like_count", 0) }) def main(): """循环抓取前 5 页评论""" for page in range(1, 6): print(f"正在抓取第 {page} 页...") comments = fetch_comments(page=page) save_to_csv(comments) # 控制抓取频率,避免对目标服务器造成压力 time.sleep(random.uniform(1, 3)) if __name__ == "__main__": main()

这里有几个设计点值得说明:

  • utf-8-sig编码写入 CSV,可以避免 Excel 打开中文乱码问题。
  • 抓取间隔使用random.uniform(1, 3),随机延时策略更接近真实用户行为。
  • 异常捕获放在请求层,避免单条数据失败导致整个程序退出。

如果接入真实平台接口,还需要处理登录 Cookie、签名参数等问题,这些内容需要结合具体接口文档来实现。

4. 数据清洗与预处理

爬虫采集到的评论数据通常比较杂乱,不能直接用于分析。常见问题包括重复评论、HTML 标签、URL 链接、表情符号、无意义短句等。

4.1 数据清洗逻辑

# 文件路径:analysis/data_clean.py import pandas as pd import re def load_raw_data(file_path="data/raw_comments.csv"): """加载原始评论数据""" df = pd.read_csv(file_path, encoding="utf-8-sig") print(f"原始数据量:{len(df)} 条") return df def clean_comment_text(text): """清洗单条评论内容""" if not isinstance(text, str): return "" # 去除 HTML 标签 text = re.sub(r"<.*?>", "", text) # 去除 URL 链接 text = re.sub(r"http[s]?://\S+", "", text) # 去除多余空白字符 text = re.sub(r"\s+", " ", text).strip() return text def clean_data(df): """完整清洗流程""" # 1. 删除空值行 df = df.dropna(subset=["content"]) # 2. 清洗评论内容 df["content"] = df["content"].apply(clean_comment_text) # 3. 去除清洗后为空的数据 df = df[df["content"] != ""] # 4. 去除重复评论(保留第一条) df = df.drop_duplicates(subset=["content"], keep="first") # 5. 去除字数过少的评论(如纯表情、灌水评论) df = df[df["content"].str.len() >= 5] # 6. 重置索引 df = df.reset_index(drop=True) print(f"清洗后数据量:{len(df)} 条") return df if __name__ == "__main__": raw_df = load_raw_data() cleaned_df = clean_data(raw_df) cleaned_df.to_csv("data/cleaned_comments.csv", index=False, encoding="utf-8-sig") print("清洗完成,已保存至 data/cleaned_comments.csv")

清洗前后的数据量对比,是毕业设计答辩中比较有说服力的数据。比如原始数据 5000 条,清洗后剩 4200 条,说明 800 条是无效或重复数据,这个比例本身就是分析结论的一部分。

4.2 为什么推荐用 pandas 而非直接操作 CSV

pandas 提供了强大的数据筛选、去重、聚合函数,处理几千条评论数据性能完全足够。而且清洗后的 DataFrame 可以直接用于后续的统计分析,不需要反复读写中间文件。

如果数据量达到几十万条以上,建议引入数据库存储,并用 SQL 完成部分清洗工作,比如:

DELETE FROM comments WHERE LENGTH(TRIM(content)) < 5; DELETE FROM comments WHERE content IN (SELECT content FROM comments GROUP BY content HAVING COUNT(*) > 1);

但在毕业设计场景下,数据量通常不会太大,用 pandas 更直观、更容易讲清楚。

5. 中文分词与词频统计

5.1 分词原理简述

中文文本不像英文那样天然有空格分词,需要借助分词工具。jieba 是目前最常用的 Python 中文分词库,支持精确模式、全模式和搜索引擎模式。

本系统中,我们选择精确模式,因为它最适合做词频统计和文本分析。

# 文件路径:analysis/text_process.py import jieba import pandas as pd from collections import Counter # 加载停用词表 def load_stopwords(file_path="data/stopwords.txt"): """加载停用词表,每行一个词""" stopwords = set() try: with open(file_path, "r", encoding="utf-8") as f: for line in f: word = line.strip() if word: stopwords.add(word) except FileNotFoundError: # 如果文件不存在,使用默认停用词 stopwords = {"的", "了", "是", "我", "你", "他", "也", "就", "都", "而", "及", "与"} return stopwords def segment_text(text, stopwords): """对单条评论分词并过滤停用词""" words = jieba.lcut(text) return [w.strip() for w in words if w.strip() and w not in stopwords and len(w) > 1] def get_word_frequency(df, top_n=50): """统计评论分词后的词频,返回 Top N 高频词""" stopwords = load_stopwords() all_words = [] for content in df["content"]: words = segment_text(content, stopwords) all_words.extend(words) word_counter = Counter(all_words) return word_counter.most_common(top_n) if __name__ == "__main__": df = pd.read_csv("data/cleaned_comments.csv", encoding="utf-8-sig") word_freq = get_word_frequency(df, top_n=50) print(word_freq[:20])

停用词表非常关键。如果不加过滤,“真的”“感觉”“游戏”这类高频但无区分度的词会占据词云中心,分析价值不大。停用词表建议根据实际数据集迭代补充。

5.2 高频词输出效果

运行上述代码后,输出效果如下:

[('画面', 356), ('剧情', 342), ('战斗', 318), ('优化', 275), ('悟空', 268), ('好玩', 235), ...]

从高频词就能初步判断玩家讨论的核心维度:画面、剧情、战斗、优化。这为后续的维度分析提供了依据。

6. 情感分析模块

6.1 情感分析方法的选型

情感分析常见方法有三种:

方法说明适用场景
基于词典维护情感词典,统计评论中正负向词数量实现简单,可解释性强
基于机器学习训练分类模型(如 SVM、朴素贝叶斯)需要标注数据集
基于深度学习使用 LSTM、BERT 等模型准确率高,但训练成本高

毕业设计场景下,基于词典的方法和深度学习方法是两种主流选择。本文先展示基于 SnowNLP 的快速实现,同时在扩展方向中介绍 BERT 模型的接入思路。

6.2 基于 SnowNLP 的情感分析

# 文件路径:analysis/sentiment_analysis.py import pandas as pd from snownlp import SnowNLP def analyze_sentiment(text): """ 返回评论情感得分,范围 [0, 1] 越接近 1 表示越正向,越接近 0 表示越负向 """ try: s = SnowNLP(text) return s.sentiments except Exception as e: print(f"情感分析失败:{text},错误:{e}") return 0.5 def get_sentiment_label(score): """将情感得分映射为情感标签""" if score >= 0.6: return "正向" elif score <= 0.4: return "负向" else: return "中性" def add_sentiment_column(df): """为 DataFrame 增加情感得分列和情感标签列""" df["sentiment_score"] = df["content"].apply(analyze_sentiment) df["sentiment_label"] = df["sentiment_score"].apply(get_sentiment_label) return df if __name__ == "__main__": df = pd.read_csv("data/cleaned_comments.csv", encoding="utf-8-sig") df = add_sentiment_column(df) df.to_csv("data/comments_with_sentiment.csv", index=False, encoding="utf-8-sig") # 统计情感分布 sentiment_stats = df["sentiment_label"].value_counts() print("情感分布统计:") print(sentiment_stats)

6.3 评分与情感的一致性分析

如果评论数据中包含用户评分(比如 1-5 分),我们还可以做评分与情感得分的一致性分析。这个分析可以作为毕业设计论文中的一个研究点。

# 计算评分与情感得分的相关性 correlation = df["score"].astype(float).corr(df["sentiment_score"]) print(f"评分与情感得分的相关系数:{correlation:.3f}")

如果相关系数接近 0.6 以上,说明人工评分的玩家与评论文本表达的情感基本一致;如果相关系数很低,则说明评论区可能存在“评分低但文字中立”或“评分高但吐槽优化”的错位情况,这也是值得深入分析的业务现象。

6.4 基于大模型 / BERT 的扩展方案

如果题目要求更高的分析质量,可以考虑 Hugging Face 的中文预训练模型。以下代码展示基于transformers的情感分析扩展方式:

# 扩展思路:使用预训练模型进行情感分析 from transformers import pipeline # 加载中文情感分析模型(需要联网下载模型权重) classifier = pipeline( "sentiment-analysis", model="uer/roberta-base-finetuned-jd-binary-chinese" ) def analyze_with_pretrained(text): result = classifier(text)[0] label = result["label"] # 正面 / 负面 score = result["score"] return label, score

注意,这种方式需要下载模型权重,首次运行时间较长,且需要保持网络畅通。毕业设计中可以选择作为“扩展模块”或“创新点”来展示,不需要在答辩现场实时跑通全量数据。

7. 数据可视化与 Web 展示

7.1 使用 pyecharts 生成图表

pyecharts 是一个强大的交互式可视化库,生成的图表可以在浏览器中交互,适合毕业设计演示。

# 文件路径:analysis/visual_analysis.py import pandas as pd from pyecharts.charts import Bar, Pie, Line, WordCloud from pyecharts import options as opts def create_wordcloud(word_freq, output_path="output/wordcloud.html"): """生成词云图""" data = [(word, freq) for word, freq in word_freq] c = ( WordCloud() .add("", data, word_size_range=[20, 100], shape="diamond") .set_global_opts(title_opts=opts.TitleOpts(title="黑悟空评论关键词词云")) ) c.render(output_path) def create_sentiment_pie(df, output_path="output/sentiment_pie.html"): """生成情感分布饼图""" sentiment_counts = df["sentiment_label"].value_counts() data_pair = [list(item) for item in sentiment_counts.items()] c = ( Pie() .add("", data_pair, radius=["35%", "70%"]) .set_global_opts( title_opts=opts.TitleOpts(title="评论情感分布"), legend_opts=opts.LegendOpts(orient="vertical", pos_top="15%", pos_left="2%") ) .set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {c} ({d}%)")) ) c.render(output_path) def create_score_bar(df, output_path="output/score_bar.html"): """生成评分分布柱状图""" score_counts = df["score"].value_counts().sort_index() c = ( Bar() .add_xaxis([str(score) for score in score_counts.index]) .add_yaxis("评论数量", score_counts.tolist()) .set_global_opts( title_opts=opts.TitleOpts(title="玩家评分分布"), xaxis_opts=opts.AxisOpts(name="评分"), yaxis_opts=opts.AxisOpts(name="评论数量") ) ) c.render(output_path)

7.2 Flask 搭建可视化展示页面

为了让答辩演示更直观,我们可以用 Flask 搭建一个简易的 Web 页面,将各类图表统一展示。

# 文件路径:web/app.py import os import pandas as pd from flask import Flask, render_template app = Flask(__name__) @app.route("/") def index(): """加载分析数据并返回展示页面""" df = pd.read_csv("../data/comments_with_sentiment.csv", encoding="utf-8-sig") # 基础统计信息 total_comments = len(df) sentiment_counts = df["sentiment_label"].value_counts().to_dict() avg_score = round(df["score"].astype(float).mean(), 2) stats = { "total_comments": total_comments, "positive_count": sentiment_counts.get("正向", 0), "neutral_count": sentiment_counts.get("中性", 0), "negative_count": sentiment_counts.get("负向", 0), "avg_score": avg_score } return render_template("index.html", stats=stats) if __name__ == "__main__": app.run(host="0.0.0.0", port=5000, debug=True)

对应的模板页面web/templates/index.html可以放统计卡片和生成的图表 HTML 文件。

<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>黑悟空评论数据分析系统</title> <style> body { font-family: "Microsoft YaHei", sans-serif; background: #f5f5f5; padding: 20px; } .card { background: #fff; padding: 20px; border-radius: 8px; margin-bottom: 20px; } .stats { display: flex; gap: 20px; flex-wrap: wrap; } .stat-item { flex: 1; min-width: 150px; padding: 15px; background: #fafafa; border-radius: 6px; text-align: center; } .stat-item h3 { margin: 0; color: #555; font-size: 14px; } .stat-item p { font-size: 24px; font-weight: bold; color: #333; margin: 8px 0 0; } </style> </head> <body> <h1>黑悟空评论数据分析系统</h1> <div class="card"> <h2>核心统计指标</h2> <div class="stats"> <div class="stat-item"> <h3>评论总数</h3> <p>{{ stats.total_comments }}</p> </div> <div class="stat-item"> <h3>正向评论</h3> <p>{{ stats.positive_count }}</p> </div> <div class="stat-item"> <h3>中性评论</h3> <p>{{ stats.neutral_count }}</p> </div> <div class="stat-item"> <h3>负向评论</h3> <p>{{ stats.negative_count }}</p> </div> <div class="stat-item"> <h3>平均评分</h3> <p>{{ stats.avg_score }}</p> </div> </div> </div> <div class="card"> <h2>情感分布饼图</h2> <iframe src="/static/sentiment_pie.html" width="100%" height="400" frameborder="0"></iframe> </div> <div class="card"> <h2>评分分布柱状图</h2> <iframe src="/static/score_bar.html" width="100%" height="400" frameborder="0"></iframe> </div> </body> </html>

需要把生成的 HTML 图表文件复制到web/static/目录下:

mkdir -p web/static cp output/*.html web/static/

然后运行:

cd web python app.py

浏览器访问http://localhost:5000即可看到展示页面。

8. 常见问题与排查思路

8.1 jieba 分词后出现单个字或无意义词

现象:词频统计结果中出现大量单字、标点、无意义词。

原因:停用词表不完整,或者没有过滤长度小于 2 的词。

解决

words = [w for w in words if len(w) > 1 and w not in stopwords]

同时定期维护停用词表,把不需要的高频词加入进去。

8.2 Excel 打开 CSV 中文乱码

现象:用 Excel 打开清洗后的 CSV 文件,中文显示乱码。

原因:CSV 保存时使用了utf-8编码,而 Excel 默认按GBK解析。

解决:写入时使用utf-8-sig编码:

df.to_csv("data/cleaned_comments.csv", index=False, encoding="utf-8-sig")

8.3 Flask 页面图表不显示

现象:页面打开正常,但图表区域空白。

原因:生成的 HTML 图表文件没有正确放到static目录,或者文件路径不对。

解决:检查web/static/目录下是否存在对应的 HTML 文件,并确认模板中的src路径与文件名一致。

8.4 SnowNLP 情感分析结果偏向中性

现象:大部分评论的情感得分都在 0.5 左右,区分度不高。

原因:SnowNLP 自带的模型是基于购物评论语料训练的,对游戏评论场景不一定完全适配。

解决:将情感得分在 0.45-0.55 之间的样本单独标记为中性,或使用自训练的词典方法、预训练模型。也可收集少量游戏评论样本,用SnowNLP提供的训练接口做模型微调。

9. 毕业设计答辩与优化建议

9.1 答辩讲解重点

毕业设计答辩时间通常只有 10-15 分钟,建议按照以下主线来讲:

  1. 项目背景:为什么选择黑悟空评论数据分析系统,解决了什么问题。
  2. 系统架构:数据采集 → 清洗 → 分析 → 可视化 → Web 展示。
  3. 技术难点:中文分词处理、情感分析模型选择、数据清洗规则设计。
  4. 系统演示:现场演示 Web 页面,展示核心图表和统计结论。
  5. 创新与不足:说明当前系统的优点,也坦诚指出分析模型的局限性,再给出未来优化方向。

9.2 可以扩展的方向

  • 引入更多数据源,比如弹幕数据、论坛帖子、短视频评论,形成多源数据对比分析。
  • 使用 BERT 等预训练模型提升情感分析准确率。
  • 加入用户画像分析,比如不同用户群体对游戏各维度的偏好差异。
  • 搭建评论主题聚类模型,自动归纳玩家讨论的热点话题。
  • 将系统部署到云服务器,支持在线访问。

9.3 项目优化的优先级

如果时间有限,优先优化以下内容:

优先级优化内容带来的收益
扩充数据量到 5000 条以上分析结论更有说服力
完善停用词表词云和高频词更准确
优化情感分析阈值情感分布更符合人工判断
增加图表之间的联动说明答辩演示更流畅
引入数据库替代 CSV体现工程完整度

10. 总结

黑悟空评论数据分析系统作为毕业设计选题,覆盖了从数据采集到数据分析、数据可视化的完整流程,技术栈实用,分析结果有业务含义,非常适合作为数据科学、大数据技术、软件工程等方向的毕业设计项目。

整套系统的核心在于把数据采集、清洗、分词、情感分析、可视化串联成一个可演示的闭环,让评委能直观看到数据从原始状态变成分析结论的全过程。建议在动手开发前先确定数据源是否可访问,然后按数据采集 → 数据清洗 → 情感分析 → 可视化 → Web 展示的顺序逐步完成,每一阶段都有明确产出,答辩时也更容易讲清楚自己的工作量和技术亮点。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询