news 2026/9/3 2:48:26

游戏评论数据分析系统全流程实战:采集、清洗、情感分析与可视化

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
游戏评论数据分析系统全流程实战:采集、清洗、情感分析与可视化

在实际的商业分析、游戏运营和毕业设计选题中,评论数据一直是被反复提起但又不好落地的数据源。以“黑悟空评论数据分析系统(项目编号 0180)”为例,这个课题并不是简单写一个爬虫,而是要把“评论采集、数据清洗、情感分析、统计聚合、可视化展示”串成一条完整的处理链路。整条链路跑通之后,用户可以看到评论量趋势、好评率变化、玩家高频关注点和情感倾向分布,进而为游戏口碑跟踪和运营决策提供依据。

这篇文章围绕一个可演示、可复现的评论数据分析系统展开,重点讲清四个问题:系统由哪些模块组成、每条数据从采集到展示经过哪些环节、关键代码和参数怎么设计、演示环境出问题时从哪里查起。整篇文章使用的技术方案适合本科毕业设计、课程实训和小型数据分析项目参考,读者可以按顺序把系统搭出来,并在答辩时解释清楚每个模块的设计理由。

1. 评论数据分析系统的需求拆解与技术选型

1.1 毕业设计演示要解决什么问题

毕业设计项目的演示效果,往往不在功能列表有多长,而在数据是否能从原始状态变成有价值的分析结果。很多同学拿到“评论数据分析系统”这个题目后,第一反应是“先写爬虫抓评论”,但抓下来之后发现数据是 JSON、是英文、是重复的,甚至夹杂大量无意义短文本,根本没法直接分析。真正的问题不是“缺数据”,而是“数据到知识的转换链路不完整”。

这个项目的核心目标是:把《黑神话:悟空》在 Steam 平台上的玩家评论作为分析对象,完成以下闭环:

  1. 采集评论原始数据,保存到关系型数据库。
  2. 对评论文本做去重、过滤、长度筛选。
  3. 统计评论的时间分布、推荐状态占比、评论长度等基础画像。
  4. 对中文评论做情感打分,判断玩家对游戏的整体情绪。
  5. 使用分词和关键词提取,找到玩家讨论的高频主题。
  6. 通过 Web 页面展示统计指标和图表,形成看板。

整个系统的亮点不在某一个算法有多深,而在每一层都有明确产出。评审老师问“数据从哪里来、结果怎么算出来、图表怎么渲染”时,你能从数据库表一路讲到 ECharts 页面,这比只贴一个爬虫代码要完整得多。

1.2 技术栈选型

技术选型的核心原则是“学习成本低、演示效果好、每个组件都能说明白”。本系统建议使用 Python 生态,原因有三:采集脚本容易写,pandas 处理表格数据方便,SnowNLP、jieba、wordcloud 这些中文文本处理库的安装和使用都很直接。

模块技术选型作用
数据采集Python + requests调用 Steam 官方评论接口,获取评论 JSON
数据存储MySQL 8.0保存评论明细和去重标记
数据处理pandas + numpy清洗、去重、聚合统计
情感分析SnowNLP对中文评论计算情感得分
分词与关键词jieba + jieba.analyse提取评论高频词与主题关键词
词云生成wordcloud + matplotlib生成词云图片用于看板展示
Web 服务Flask提供统计接口和页面渲染
前端图表ECharts展示折线图、柱状图、饼图、仪表盘

这里需要解释一下为什么选择 MySQL 而不是 SQLite。SQLite 在本地调试时确实省事,但毕业设计评阅时,老师通常希望看到“数据库设计”和“SQL 语句”,MySQL 的多表查询、索引、字符集配置也更容易讲出工程味道。如果演示机器上没有 MySQL 服务,可以使用 Docker 运行一个 MySQL 8.0 容器,这样环境干净、卸载方便。

1.3 数据流与模块划分

系统的数据流向按“源数据 -> 明细数据 -> 特征数据 -> 展示数据”四层划分,每一层对应独立的代码目录和功能模块。

第一层是采集层。采集器请求 Steam 评论接口,拿到评论列表后解析出作者、正文、时间、推荐状态、点赞数等字段,写入 MySQL 的wukong_comments表。

第二层是清洗层。使用 pandas 从数据库读入 DataFrame,删除评论字段为空的记录,按评论内容的 MD5 值去重,过滤过短文本,最后把清洗结果写回分析表,或者直接在 DataFrame 中继续分析。

第三层是分析层。对日期列做按月或按周聚合,统计推荐与不推荐的数量,计算好评率,运行 SnowNLP 对每条评论做情感打分,再使用 jieba 抽取 TOP 关键词。

第四层是展示层。Flask 提供/api/overview/api/trend/api/keywords等 JSON 接口,前端页面通过 ECharts 请求这些接口并渲染图表。

这样划分之后,每一层都能独立测试。采集层跑完,先看看数据库里有多少条记录;分析层跑完,先打印几个统计数字;展示层做出来之后,整个系统的演示流程就自然成立了。

2. 环境准备与项目骨架搭建

2.1 环境要求

开发机建议使用 Windows 10/11 或 Linux,Python 版本选择 3.9 或 3.10。这里要特别提醒:SnowNLP 在更高版本 Python 下通常也能用,但为了避免依赖编译问题,建议使用 3.10 以下版本。如果原始部署环境只支持 Python 3.11 以上,先测试pip install snownlp是否能成功,再继续后面的环节。

依赖建议版本用途
Python3.9 / 3.10主开发语言
requests2.31.x调用评论接口
pandas2.0.x数据处理
PyMySQL1.1.xMySQL 连接
Flask3.0.xWeb 服务
snownlp0.12.3中文情感分析
jieba0.42.1中文分词与关键词
wordcloud1.9.x词云生成
matplotlib3.7.x词云底图渲染

创建虚拟环境并安装依赖的命令如下:

mkdir wukong-comment-analysis cd wukong-comment-analysis python -m venv venv # Windows venv\Scripts\activate # Linux / macOS source venv/bin/activate pip install requests pandas pymysql flask snownlp jieba wordcloud matplotlib

安装完成后,用pip list检查版本。如果 wordcloud 安装失败,通常是本机缺少 C 编译器,可直接下载对应 Python 版本的.whl文件离线安装,也可以退回1.8.1版本重试。

2.2 初始化数据库

MySQL 中需要创建数据库和分析表。这里使用 Docker 启动 MySQL 最省事:

docker run -d \ --name mysql8 \ -p 3306:3306 \ -e MYSQL_ROOT_PASSWORD=123456 \ -e MYSQL_DATABASE=game_comment \ mysql:8.0

等容器启动后,连接数据库执行建表 SQL。评论表的字段设计要覆盖采集接口能提供的全部关键信息,同时额外增加review_md5字段用于去重。

CREATE DATABASE IF NOT EXISTS game_comment DEFAULT CHARACTER SET utf8mb4 DEFAULT COLLATE utf8mb4_unicode_ci; USE game_comment; CREATE TABLE IF NOT EXISTS wukong_comments ( id INT AUTO_INCREMENT PRIMARY KEY, appid INT NOT NULL COMMENT 'Steam 游戏 ID', author_id VARCHAR(64) NOT NULL COMMENT '评论者 ID', author_name VARCHAR(128) DEFAULT NULL, language VARCHAR(32) DEFAULT NULL COMMENT '评论语言', review_text TEXT NOT NULL COMMENT '评论正文', review_md5 CHAR(32) NOT NULL COMMENT '评论去重标识', timestamp_created DATETIME NOT NULL COMMENT '评论时间', voted_up TINYINT NOT NULL DEFAULT 0 COMMENT '是否推荐', votes_helpful INT DEFAULT 0 COMMENT '有帮助数', votes_funny INT DEFAULT 0 COMMENT '有趣数', weighted_vote_score FLOAT DEFAULT 0 COMMENT '加权评分', sentiment_score FLOAT DEFAULT NULL COMMENT '情感得分', created_at DATETIME DEFAULT CURRENT_TIMESTAMP, UNIQUE KEY uk_review_md5 (review_md5), KEY idx_time (timestamp_created), KEY idx_voted_up (voted_up), KEY idx_sentiment (sentiment_score) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='黑神话悟空评论明细表';

关键点是review_md5的唯一索引。评论接口在翻页过程中可能出现重复数据,靠这条唯一索引可以保证重复记录直接插入失败,配合INSERT IGNOREON DUPLICATE KEY UPDATE实现幂等写入。

2.3 项目目录与配置

目录结构按“采集、清洗、分析、展示、脚本”拆分,每个模块职责清晰:

wukong-comment-analysis/ ├── config.py # 数据库连接配置 ├── scripts/ │ ├── fetch_comments.py # 采集评论 │ └── generate_sample.py # 生成模拟评论数据 ├── analysis/ │ ├── clean_data.py # 清洗与统计 │ ├── sentiment_analysis.py # 情感分析 │ └── keyword_extract.py # 关键词提取与词云 ├── webapp/ │ ├── app.py # Flask 应用 │ ├── static/ # ECharts 和自定义 JS │ └── templates/ │ └── index.html # 看板页面 └── requirements.txt

数据库连接配置单独放到config.py,避免每个脚本都写一遍连接参数:

DB_CONFIG = { "host": "127.0.0.1", "port": 3306, "user": "root", "password": "123456", "database": "game_comment", "charset": "utf8mb4", }

实际项目如果使用远程数据库,把hostpassword改掉即可。生产环境不要把这些参数硬编码到代码里,建议读取环境变量,但没有项目背景时可以先把配置集中管理。

3. 评论采集:官方接口、翻页逻辑与入库

3.1 接口返回结构

Steam 提供的是公开评论接口,路径格式为:

https://store.steampowered.com/appreviews/{appid}?json=1

《黑神话:悟空》的 Steam appid 是1245620。接口返回的 JSON 中包含successcursorreviews等字段。其中cursor是下一页的游标标记,reviews是评论数组。

单个评论对象的关键字段如下:

字段含义
author.steamid评论者 Steam ID
author.name评论者昵称
language评论语言,如 schinese
review评论正文
timestamp_created评论创建时间戳
voted_up是否推荐该游戏
votes_helpful被认为有帮助的次数
votes_funny被认为有趣的次数
weighted_vote_score评论加权投票分数

如果请求参数中设置language=schinese,接口会优先返回中文评论。但 Steam 评论接口在不同网络环境下的可达性并不稳定,如果演示机器无法访问该域名,先用本地模拟数据把流程跑通,这一步在后面会专门说明。

3.2 编写采集器

采集器要完成三件事:请求接口、解析字段、写入 MySQL。为了降低对官方接口的压力,每翻一页后休眠 1 秒。

import hashlib import time import pymysql import requests from config import DB_CONFIG APPID = 1245620 BASE_URL = "https://store.steampowered.com/appreviews/{appid}" HEADERS = { "User-Agent": ( "Mozilla/5.0 (Windows NT 10.0; Win64; x64) " "AppleWebKit/537.36 (KHTML, like Gecko) " "Chrome/120.0 Safari/537.36" ) } def review_md5(text: str) -> str: return hashlib.md5(text.encode("utf-8", errors="ignore")).hexdigest() def insert_review(cursor, item: dict) -> None: author = item.get("author", {}) text = item.get("review", "") ts = item.get("timestamp_created", 0) created = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(ts)) sql = """ INSERT IGNORE INTO wukong_comments (appid, author_id, author_name, language, review_text, review_md5, timestamp_created, voted_up, votes_helpful, votes_funny, weighted_vote_score) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s) """ cursor.execute(sql, ( APPID, author.get("steamid", ""), author.get("name", ""), item.get("language", ""), text, review_md5(text), created, 1 if item.get("voted_up") else 0, item.get("votes_helpful", 0), item.get("votes_funny", 0), item.get("weighted_vote_score", 0), )) def fetch_comments(max_pages=20): conn = pymysql.connect(**DB_CONFIG) cursor = conn.cursor() start_cursor = "*" for page in range(max_pages): params = { "json": 1, "filter": "all", "language": "schinese", "num_per_page": 20, "cursor": start_cursor, "purchase_type": "all", } resp = requests.get(BASE_URL.format(appid=APPID), params=params, headers=HEADERS, timeout=10) data = resp.json() reviews = data.get("reviews", []) or [] for item in reviews: insert_review(cursor, item) conn.commit() print(f"page {page + 1}: fetched {len(reviews)} reviews") next_cursor = data.get("cursor") if not reviews or next_cursor == start_cursor: break start_cursor = next_cursor time.sleep(1) cursor.close() conn.close() if __name__ == "__main__": fetch_comments(max_pages=20)

运行脚本后,在 MySQL 中查看数据量:

SELECT COUNT(*) FROM game_comment.wukong_comments;

如果返回 0,先检查请求 URL 是否真实可达、返回 JSON 中success是否为 1。不要急着改代码,可以用下面这条命令确认接口内容:

curl "https://store.steampowered.com/appreviews/1245620?json=1&language=schinese&num_per_page=1"

3.3 入库去重策略

评论去重是必须处理的细节。原因有两个:第一,官方接口在翻页时可能存在重复返回;第二,同一条评论如果多次运行采集脚本,不处理会变成脏数据。

这里的方案是给评论内容计算 MD5,作为数据库唯一键。INSERT IGNORE在遇到重复主键或唯一键时不会报错,也不会写入,所以重复采集时数据量不会虚增。

另一个细节是时间解析。接口返回的timestamp_created是 Unix 时间戳,采集时直接转成 MySQL 的DATETIME格式。如果项目后续要按周或按月聚合,日期字段必须是数据库可排序的类型,不能保留为字符串。

4. 评论清洗与基础画像分析

4.1 清洗规则

采集到原始评论后,不能直接进分析层。评论数据常见的问题包括重复文本、过短评论、非中文评论、空作者等。清洗阶段的目标是生成一个干净、可统计的 DataFrame。

清洗规则如下:

检查项清洗策略原因
review_md5 重复保留第一条防止重复评论影响统计
review_text 为空删除无法参与文本分析
评论长度小于 5删除短文本情感判断不准确
时间字段为空删除无法参与时间趋势分析
超出业务时间范围保留并检查可能是指定时间窗口外的评论

清洗代码放在analysis/clean_data.py

import pandas as pd import pymysql from config import DB_CONFIG def load_data(): conn = pymysql.connect(**DB_CONFIG) sql = "SELECT * FROM wukong_comments" df = pd.read_sql(sql, conn) conn.close() return df def clean_data(df: pd.DataFrame) -> pd.DataFrame: print(f"原始数据量: {len(df)}") df = df.drop_duplicates(subset=["review_md5"], keep="first") print(f"去重后数据量: {len(df)}") df = df[df["review_text"].notna()] df = df[df["review_text"].str.strip() != ""] df["review_len"] = df["review_text"].apply(len) df = df[df["review_len"] >= 5] df["timestamp_created"] = pd.to_datetime(df["timestamp_created"]) df = df[df["timestamp_created"].notna()] print(f"清洗后数据量: {len(df)}") return df if __name__ == "__main__": raw = load_data() cleaned = clean_data(raw) print(f"清洗后剩余 {len(cleaned)} 条评论")

4.2 画像指标

基础画像指标不需要太复杂,但要能从业务角度讲清楚意义。通常输出四类指标:

第一类是总体量。评论总数、清洗后评论数、采集覆盖率,用来判断样本是否足够。

第二类是推荐率。按voted_up分组统计,voted_up=1表示玩家推荐,voted_up=0表示不推荐。好评率等于推荐数除以有效评论总数。

第三类是时间分布。按天、周、月统计评论量,可以观察游戏发售、版本更新等时间点的讨论热度变化。

第四类是评论长度分布。评论长度可以粗略反映玩家表达意愿,长评论往往带有更具体的体验细节。

统计代码:

def overview_stats(df: pd.DataFrame) -> dict: total = len(df) recommended = int(df["voted_up"].sum()) not_recommended = total - recommended rate = round(recommended / total * 100, 2) if total else 0 return { "total": total, "recommended": recommended, "not_recommended": not_recommended, "recommend_rate": rate, } def trend_stats(df: pd.DataFrame) -> pd.DataFrame: df["date"] = df["timestamp_created"].dt.strftime("%Y-%m-%d") trend = df.groupby("date").agg( total=("id", "count"), recommended=("voted_up", "sum"), ).reset_index() trend["not_recommended"] = trend["total"] - trend["recommended"] return trend

这段代码输出的overview_stats可以直接给 Flask 接口使用。trend_stats生成折线图所需的日期、总数和推荐数三列。

4.3 输出示例

清洗和统计完成后,可以在控制台看到类似输出:

原始数据量: 487 去重后数据量: 461 清洗后数据量: 428 清洗后剩余 428 条评论 总体概览: - 评论总数: 428 - 推荐: 366 - 不推荐: 62 - 好评率: 85.51%

这里的好评率只是基于评论的统计值,不等同于游戏真实好评率,因为采集数量有限,而且语言过滤后样本并不完整。答辩时一定要说明样本口径,可以在页面标题下标注“样本数据,仅用于系统演示”。

5. 情感分析、关键词提取与领域修正

5.1 情感分析的基本思路

评论分析系统如果只统计推荐和不推荐,说服力不够。很多玩家会写“游戏很好但优化有问题”这样的句子,单纯二分类会丢失情绪倾向。所以需要给每条评论计算一个情感得分,范围在 0 到 1 之间,越接近 1 表示情感越正面,越接近 0 表示情感越负面。

这里采用 SnowNLP。它的实现原理是基于朴素贝叶斯分类器训练出的中文情感分析模型,使用非常方便:

from snownlp import SnowNLP s = SnowNLP("画面非常震撼,期待很久了") print(s.sentiments)

输出通常大于 0.5,说明模型判断为正面情感。

但需要注意:SnowNLP 的训练语料以电商购物评论为主,对游戏领域词汇的覆盖不一定准确。直接用于游戏评论时,可能把“打击感不错但难度太高”判成负面。因此本系统在基础情感得分上增加领域修正规则,保证演示效果更贴近真实阅读感受。

5.2 基于 SnowNLP 的情感打分实现

打分函数放在analysis/sentiment_analysis.py

from snownlp import SnowNLP POSITIVE_WORDS = ["惊艳", "震撼", "好玩", "推荐", "神作", "满分", "满意"] NEGATIVE_WORDS = ["卡顿", "闪退", "难受", "失望", "优化差", "退款", "差评", "bug"] def adjust_score(text: str, base_score: float) -> float: score = base_score for word in POSITIVE_WORDS: if word in text: score = min(1.0, score + 0.1) for word in NEGATIVE_WORDS: if word in text: score = max(0.0, score - 0.1) return round(score, 4) def score_comment(text: str) -> float: base_score = SnowNLP(text).sentiments return adjust_score(text, base_score) def add_sentiment_scores(df): df["sentiment_score"] = df["review_text"].apply(score_comment) return df

这段代码的解释分两层:第一层是基础模型打分,SnowNLP 已经给出了 0 到 1 的分数;第二层是领域词典修正,游戏评论里的特定词能明显影响情绪判断,通过关键词加权让分数更接近玩家真实态度。

情感得分区间可以直接用于页面上的仪表盘:

情感得分区间判断倾向示例场景
0.0 - 0.4偏负面“优化太差,频繁闪退”
0.4 - 0.6中性“还行,就是难度有点高”
0.6 - 0.8偏正面“画面不错,战斗系统有特色”
0.8 - 1.0正向积极“年度最佳,值得购买”

5.3 关键词提取与词云

关键词提取使用 jieba 自带的关键词接口。需要过滤掉“真的、这个、一个、什么、游戏、还是”这类无信息量的词。这里准备一个自定义停用词集合,然后再调用jieba.analyse.extract_tags

import jieba.analyse STOP_WORDS = {"这个", "一个", "没有", "什么", "就是", "真的", "可以", "还是", "我们", "你们"} def extract_keywords(df, top_n=20): text_all = " ".join(df["review_text"].tolist()) jieba.analyse.set_stop_words_from_offline_text = None keywords = jieba.analyse.extract_tags( text_all, topK=top_n, withWeight=True, allowPOS=("n", "v", "vn", "a", "ad"), ) result = [{"name": k, "value": round(w, 4)} for k, w in keywords if k not in STOP_WORDS] return result

值得注意的一点:如果直接把全部评论拼接成一个超长字符串再提取关键词,高频词可能偏向“悟空”“游戏”“黑神话”这类反复出现的词。这其实是业务上的正常结果,但看板演示时重点应该是“画面、优化、战斗、剧情、打击感”这些有业务含义的词。因此可以在分析前把review_text中的“悟空”“黑神话”“游戏”“这款”等词加入停用词表,让关键词分布更真实。

词云生成部分依赖 wordcloud,中文字体在 Linux 下经常出问题,推荐在代码中显式指定字体路径:

from wordcloud import WordCloud import matplotlib.pyplot as plt import jieba def generate_wordcloud(text: str, output_path: str): wc = WordCloud( font_path="C:/Windows/Fonts/simhei.ttf", # Windows 示例路径 width=1200, height=600, background_color="white", max_words=100, ).generate(text) plt.figure(figsize=(12, 6)) plt.imshow(wc, interpolation="bilinear") plt.axis("off") plt.savefig(output_path, dpi=150, bbox_inches="tight")

Linux 服务器如果没有中文字体,可以先执行fc-list :lang=zh查看是否安装了中文字体。没有的话,可以把 Windows 下的simhei.ttf上传到项目字体目录,再用绝对路径引用。这一步虽然小,但很容易在演示现场变成空白方块图。

6. 可视化看板:Flask 接口与 ECharts 页面

6.1 数据接口设计

分析结果需要通过 Web 页面呈现。Flask 的作用不是复杂业务,而是把数据库中的统计结果转换成前端可以消费的 JSON 接口。这里设计 4 个核心接口:

接口返回内容对应图表
/api/overview评论总数、推荐数、好评率、情感均值顶部指标卡片
/api/trend按日期的评论量和推荐量折线图
/api/sentiment情感得分区间分布柱状图
/api/keywordsTOP 20 关键词及权重横向条形图或词云

app.py的核心实现如下:

from flask import Flask, jsonify, render_template import pandas as pd from analysis.clean_data import load_data, clean_data, overview_stats, trend_stats app = Flask(__name__) @app.route("/") def index(): return render_template("index.html") @app.route("/api/overview") def api_overview(): df = clean_data(load_data()) return jsonify(overview_stats(df)) @app.route("/api/trend") def api_trend(): df = clean_data(load_data()) trend = trend_stats(df) data = { "date": trend["date"].tolist(), "total": trend["total"].tolist(), "recommended": trend["recommended"].tolist(), } return jsonify(data) if __name__ == "__main__": app.run(host="0.0.0.0", port=5000, debug=True)

接口每次请求都重新加载数据,在演示场景下够用,但生产环境必须考虑缓存。不要在前端页面刷新时反复执行全量清洗逻辑,应该把统计结果提前计算好,存入一张聚合表或 Redis 缓存中。

6.2 页面配置

前端页面采用静态 HTML 加 ECharts 的方式,避免引入大型前端构建工具。页面在templates/index.html中加载本地 ECharts 文件,再依次请求接口。

<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>黑悟空评论数据分析看板</title> <script src="/static/js/echarts.min.js"></script> </head> <body> <div id="overview-cards"></div> <div id="trend-chart" style="height: 400px;"></div> <div id="sentiment-chart" style="height: 400px;"></div> <div id="keyword-chart" style="height: 400px;"></div> <script src="/static/js/dashboard.js"></script> </body> </html>

dashboard.js里,用fetch拿接口数据后交给 ECharts 渲染。折线图示例:

fetch('/api/trend') .then(res => res.json()) .then(data => { const chart = echarts.init(document.getElementById('trend-chart')); chart.setOption({ title: { text: '评论量趋势' }, tooltip: { trigger: 'axis' }, xAxis: { type: 'category', data: data.date }, yAxis: { type: 'value' }, series: [ { name: '评论总数', type: 'line', data: data.total }, { name: '推荐数', type: 'line', data: data.recommended } ] }); });

这里要注意:浏览器访问页面时,如果 Flask 运行在0.0.0.0:5000,演示环境可以先用浏览器打开http://127.0.0.1:5000。如果是远程服务器,要使用服务器 IP 替换127.0.0.1,并确保防火墙放行 5000 端口。

6.3 演示环境的启动顺序

演示时不要直接运行python webapp/app.py,应该按固定顺序启动,避免现场因为顺序错误导致数据为空。

第一步,确认 MySQL 容器运行,并且wukong_comments表有数据:

docker ps mysql -h127.0.0.1 -uroot -p123456 -e "select count(*) from game_comment.wukong_comments;"

第二步,检查关键 Python 依赖是否齐全:

pip list | grep -E "flask|snownlp|jieba|pandas"

第三步,启动 Flask:

cd wukong-comment-analysis python webapp/app.py

第四步,浏览器验证:

  1. 打开/api/overview,确认返回 JSON。
  2. 打开/api/trend,确认时间序列有数据。
  3. 打开首页,确认图表正常渲染。

注意:演示时最好在本地准备模拟数据。如果现场网络无法访问 Steam 评论接口,至少保证系统界面和统计流程可以展示。

7. 常见问题、排查链路与答辩准备

7.1 高频问题对照表

问题现象常见原因检查方式处理建议
采集脚本返回 0 条评论网络不可达、语言参数无数据、appid 错误用 curl 请求接口查看 JSON改用本地模拟数据;确认接口返回中 reviews 数组长度
MySQL 插入中文乱码数据库字符集不是 utf8mb4show variables like 'character_set_server';创建数据库时指定 utf8mb4;连接参数添加 charset
评论数很少,只有几十条接口默认只返回当前游标前数据,采集页数太少查看采集日志每页获取数量调大 max_pages;使用 filter=all 获取全部类型
情感得分几乎全是 0.9修正词加权过大或样本以正面评论为主抽查 10 条评论的 base_score检查自定义词典,避免得分溢出
wordcloud 生成空白方块系统缺少中文字体fc-list :lang=zh指定 simhei.ttf 等中文字体路径
Flask 页面图表不显示JS 文件路径错误、接口返回非 JSON打开浏览器 F12 查看 Network确认 static 目录和接口路径一致
重复运行采集后数据量翻倍唯一键未生效或去重字段写错查看 review_md5 是否唯一确认建表唯一索引 uk_review_md5

7.2 排查链路顺序

遇到系统不工作,不要东翻西找,按以下顺序排查:

  1. 先确认接口数据是否正常。用 curl 或浏览器直接访问/api/overview,如果接口返回报错,问题在后端逻辑。
  2. 再确认数据库数据是否为空。执行SELECT COUNT(*) FROM wukong_comments;,如果为空,问题是采集或清洗环节。
  3. 检查清洗代码是否误删了大部分数据。在控制台打印清洗前后的数据量,确认过滤条件是否过严。
  4. 检查 Flask 启动日志。留意ModuleNotFoundErrorOperationalErrorConnectionRefusedError,第一行异常通常就是根因。
  5. 最后检查前端控制台。如果接口正常但页面空白,优先查看 JS 报错和请求路径。

一个非常容易踩的坑是:在清洗代码中把timestamp_created列直接覆盖成pd.Timestamp对象,然后写回数据库时失败。如果只是展示统计结果,不需要把清洗后的 DataFrame 写回数据库;如果必须写回,需要先把时间列格式化为字符串。

7.3 答辩讲解主线

答辩时,老师通常不会只问“做了哪些功能”,更关心设计决策和问题意识。建议按以下主线讲解:

先讲背景。“黑神话:悟空”上线后讨论热度很高,玩家评论是口碑分析的重要信息来源,但评论量大、文本不规范,需要一套自动化系统处理。

再讲数据链路。从 Steam 评论接口采集到 MySQL,通过 pandas 清洗,使用 SnowNLP 打分,再通过 jieba 提取关键词,最终用 Flask 和 ECharts 展示。

接着讲关键技术点。重点解释review_md5的去重逻辑、SnowNLP 情感得分如何修正、时间序列怎么聚合。

然后讲实验过程。说明采集了多少条评论、清洗后剩多少、好评率是多少、情感分布长什么样,并坦白说明样本限制。

最后讲不足与改进。可以提到深度学习情感分类、多平台数据接入、自动定时增量采集等方向。这样回答既有深度,又显得诚恳。

7.4 可扩展的方向

这个系统改成毕业设计论文后,仍然有明显的扩展空间。

第一个方向是数据源扩展。当前只接了 Steam 评论,后续可以接入 TapTap、贴吧等渠道,不过要确认平台是否允许采集,避免合规风险。多源数据需要先统一字段格式,再进入同一套分析流程。

第二个方向是增量采集。当前脚本是手动一次性运行,生产环境应使用定时任务每日采集新增评论,并记录最近一次采集游标,避免重复拉全量数据。

第三个方向是模型升级。SnowNLP 属于基础模型,准确率有限。可以收集一批游戏领域标注数据,微调文本分类模型;也可以接入大模型做摘要和细粒度情感识别,但生产成本会明显增加。

第四个方向是报表能力。可以把每日统计结果写入 MySQL 聚合表,加入日期筛选、对比分析和 PDF 导出,让系统从个人分析工具变成运营报表平台。

建议:毕业设计阶段先把“数据采集、清洗、情感分析、可视化展示”这条主线做扎实,不要同时铺开太多功能。功能太多反而会让系统看起来像功能堆砌,缺少核心分析深度。

整个项目的核心收获不在于“爬了多少条评论”,而在于建立了一个完整的数据分析流程思维。采集、清洗、分析、展示中的任何一环出问题,都可能让最终看板失真。把每一步的输入输出都确认清楚,这个系统就能稳定复现。后续如果要在真实运营场景中投入使用,可以再补充监控、缓存、增量调度和生产级部署,当前版本的架构已经为这些扩展预留了清晰位置。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/3 2:48:07

从一键整合包到可控工作流:视频AI动作迁移与角色替换实战

我第一次拿到 Scail2 这类“一键整合包”时&#xff0c;心情其实很拧巴。拧巴的原因很简单&#xff1a;标题里写着加速补光、修脸修色、补帧、多人动作迁移、背景替换&#xff0c;甚至还有“无限抽卡”这种游戏感很强的说法&#xff0c;看起来好像不需要任何技术基础就能直接出…

作者头像 李华
网站建设 2026/9/3 2:47:48

智能体群集化:从单Agent到多智能体协作与编排实战解析

过去两年&#xff0c;大模型从“单轮对话工具”迅速进化成“能干活的工作流引擎”&#xff0c;各类 Agent 框架、智能体平台密集出现。但很多人把 Agent 用起来之后会发现一个尴尬的问题&#xff1a;单个智能体能力再强&#xff0c;也只能顺着一条任务线往下走&#xff1b;一旦…

作者头像 李华
网站建设 2026/9/3 2:46:52

华强北S15Plus智能手表技术解析:独立通话与RTOS系统深度评测

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/3 2:46:15

12864多级菜单设计:基于表驱动与状态机的嵌入式方案

简介&#xff1a;这是一份面向51单片机初学者的12864多级菜单设计示例&#xff0c;围绕LCD12864人机交互界面&#xff0c;完整展示按键扫描、菜单层级切换与界面刷新的实现思路&#xff0c;适合项目里需要加入菜单交互功能的中初级开发者。压缩包共53个文件&#xff0c;约382KB…

作者头像 李华
网站建设 2026/9/3 2:44:20

零代码构建药品查询工具:TRAE智能体开发平台实战解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/3 2:41:35

从零实现字节级BPE Tokenizer:大模型数据流水线第一课

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华