做这类 Django 大屏 + 小程序的毕设,很多同学一开始都以为卡在技术上,真正动手了才发现卡在“数据”和“选题包装”上。《django基于用户评论的热点问题挖掘与反馈分析系统》,从名字就能看出来,它要干的不是简单做个评论列表,而是要把一堆原始评论,拆成“近期大家都在骂/都在夸什么”的可视化结论。这篇文章就把整个项目从头到尾拆开讲一遍,包括模块划分、算法落地、小程序联调、毕设文档和答辩需要准备的细节。适合正在选毕业设计题目、或者已经在做类似系统的同学参考,哪怕是刚学 Django 的新手,照着文章的思路也能把项目框架搭明白。
我有段时间密集帮人看过这类系统,源码我也看过不少。说句实在话,市面上的成品源码很多只做了一半:后端能跑,小程序能登录,但热点怎么挖出来的、反馈怎么分析的,讲不清楚,答辩一问就慌。所以这篇文章的重点不是贴一个能运行的源码出来,而是讲清楚这套系统的完整链路和每个环节里的实际取舍。
1. 这类系统到底在解决什么问题
毕设题目看起来很宏大,但拆开其实就一句话:把用户评论里反复出现的关键信息和情绪倾向,自动找出来,并且用小程序展示给运营人员看。
1.1 用户评论的数据价值与选题动机
现在稍微像样一点的产品,评论区每天都能产生几百上千条文本。电商平台有商品反馈,食堂有菜品吐槽,校园里也有对校园服务的意见征集。这些人写的每一句话都带着真实诉求,比如“取餐太慢了”,“系统又崩了”,“价格比上周贵了五块”。
但是人工去看这些评论,效率太低。一个人一天看几百条已经是极限,看完了还不一定能归纳出“最近大家集中反馈的是哪三类问题”。毕设做热点挖掘和反馈分析,本质上就是把“人工总结评论”这件事自动化:系统定期抓取评论,做清洗和分词,算权重,找突发词,再结合情感分析给出结论。
从毕设选题的角度来说,这个题目有几个天然优势:
- 数据来源灵活。可以做爬虫抓公开评论,也可以用公开数据集,甚至可以自己写一套模拟评论生成器。
- 技术栈覆盖广。Django后端、小程序前端、数据挖掘算法、可视化展示,全都能揉进去。
- 可展示性强。答辩现场打开小程序,点开一个热词,能看到相关评论、情感倾向、趋势变化,视觉效果好。
- 边界好控制。算法不需要做到科研级,能讲清楚TF-IDF和TextRank区别,已经能拿不错的分数。
1.2 需求拆解:从评论采集到反馈闭环
我当时帮同学A做系统规划时,直接按“数据链路”把系统切成了五段:
| 模块 | 核心功能 | 输出物 |
|---|---|---|
| 数据采集 | 抓取评论数据 / 导入已有数据 | 原始评论表 |
| 数据清洗 | 去重、去噪、分词、去停用词 | 干净语料库 |
| 热点挖掘 | 关键词提取 + 时间窗口突发检测 | 热点词表 |
| 反馈分析 | 情感倾向判断 + 主题聚类 | 情感分布/主题报告 |
| 小程序展示 | 热榜、评论流、图表报告 | 用户可操作的界面 |
这个拆法的好处是每一段都可以单独测试。数据采集挂了不影响算法,算法抽风不影响展示。很多同学上来就写爬虫,爬了两天发现网页结构变了,很崩溃。其实可以先用手工整理的评论数据把算法跑通,爬虫放后面再补。
另外要提醒的是:凡是涉及抓取真实平台评论,一定要控制频率、遵守网站协议,只做公开数据的研究性分析。毕设阶段完全可以采用脱敏后的公开数据集,或者构造一批模拟数据,重点是把处理链路跑通。
2. 技术选型:为什么是 Django 而不是 Flask 或 SpringBoot
选 Django 不是因为它是“毕设指定框架”,而是因为这类系统本身就需要:能快速建表、能自动生成管理后台、能优雅写接口。
2.1 Django 在毕设项目里的真实优势
第一是 ORM。一次定义模型,数据库表结构就出来了。评论表、热点词表、情感分析结果表,这三个核心表之间还有外键关系,比如一条热点词对应多条评论。如果人工写SQL,会浪费大量时间;Django ORM 只需要定义模型类,查询用filter、annotate就能组合出结果,特别适合时间紧的毕设。
第二是 Django Admin。系统里需要维护用户、管理停用词、手动标记“某条评论属于某热点”,这些操作如果都专门做页面,工程量不小。用 Admin 后台几行代码就能注册完,演示的时候还能展示后台的增删改查能力。
第三是生态成熟。配合django-rest-framework写小程序接口,身份认证、分页、序列化基本是现成的。再配合simplejwt,小程序登录后拿 token,后续请求都带 token,安全和规范都说得过去。
有人会问:用 Flask 更轻,为什么不用?我的看法是,Flask 自由度高,但自由度也意味着很多组件要自己拼。比如 Flask 里没有内置 ORM,默认连数据库配置都要自己整理。毕设周期通常就三四个月,Django 的“约定优于配置”能帮你省掉大量重复劳动。
2.2 整体架构与数据流向
整个系统的前后端是分离的:
- 后端:Django 提供 REST API,处理采集、分析、查询。
- 算法层:以 Python 脚本或 Django 管理命令的形式存在,读库,算完再写回分析结果表。
- 前端:小程序充当“展示与轻交互端”,不会直接处理算法逻辑。
- 数据库:MySQL 存业务数据;Redis 可选,用来做热词缓存,减轻查询压力。
数据流是这样的:评论先落库,由定时任务或者手动任务触发分析;分析脚本把热点词、情感结果写回数据库;小程序请求对应接口,拿到结果后渲染图表。
小程序端我建议用原生框架就够了。这个系统最复杂的页面也就是词云、饼图、柱状图和列表,原生wx-charts或者echarts小程序版都能搞定。不需要为了一个毕设上 uni-app,除非你想顺便展示跨端能力。
MySQL 和 SQLite 的选择上,个人建议直接用 MySQL。不是说 SQLite 不行,而是 MySQL 更贴近真实生产环境,且部署在服务器上比较顺手。如果你担心本机没有 MySQL,可以通过 Docker 装一个,一条命令的事。
3. 评论数据的获取与清洗:算法之前最脏的一步
很多同学把重心放在算法,实际上最后拖垮项目的往往是数据。我见过最典型的例子:爬下来的评论里有大量“感谢分享”“666666666”这种无效文本,不处理就去算词频,结果“666”成了热点词,答辩现场非常尴尬。
3.1 数据来源的三种方式
第一种是爬虫采集。优先选择有公开接口或结构稳定的页面,在遵守目标站点协议的前提下,控制请求频率,解析评论字段。要注意:大规模爬取存在合规风险,毕设项目建议小规模、节流采集,并且不做公开传播。
第二种是公开数据集。很多教学平台会提供脱敏后的评论数据,比如外卖评论、酒店评论、电商评论。字段包括用户ID、评分、评论文本、评论时间。这个方式最省事,也最能说明问题。
第三种是自己生成模拟数据。如果你希望演示效果完全可控,可以先写好一批“带热点”的评论,比如在一小段时间窗口内反复出现“配送太慢”,然后在算法结果里验证它确实被挖出来了。这样演示时更有说服力:造一个已知热点,看系统能不能挖出来。
我个人最推荐“公开数据 + 少量自造数据”的组合。公开数据证明系统能处理真实文本,自造数据证明系统对突发话题有敏感度。
3.2 清洗流程的完整链路
评论清洗没有多难,但步骤不能省。标准流程是这样的:
- 去重:同一个人重复提交的、同一句话刷屏的,按评论哈希去重。
- 去噪:去掉明显与主题无关的文本,比如“哈哈哈”“路过”这类低信息评论。
- 去掉特殊字符:URL、@用户名、手机号、表情符号、HTML标签,全部删掉或者转义。
- 统一格式:繁体转简体、全角转半角、英文统一小写。
- 分段结构:一句话如果太长,按标点切成短句,方便后续提取关键词。
伪代码大概是这样的:
import re def clean_comment(text: str) -> str: # 去除HTML标签 text = re.sub(r'<[^>]+>', '', text) # 去除URL text = re.sub(r'https?://\S+', '', text) # 去除@用户 text = re.sub(r'@\S+', '', text) # 去除表情符号(简单按非字符处理,可结合正则) text = re.sub(r'[^\u4e00-\u9fa5a-zA-Z0-9,。!?、:;""'' ]', '', text) # 繁体转简体可用 opencc 库 return text.strip()表情符号这条,很多人会忽略。微信生态下的评论里表情非常多,如果不清理,分词时会出现一堆难以理解的碎片词。建议在清洗阶段就处理掉。
3.3 中文分词与停用词处理
清洗完的文本进入分词环节。中文分词最常用的工具是jieba,支持三种模式,我这里一般用精确模式:
import jieba text = "这个餐厅的桌椅摆放有点乱,高峰期特别拥挤" words = jieba.lcut(text) print(words) # ['这个', '餐厅', '的', '桌椅', '摆放', '有点', '乱', ',', '高峰期', '特别', '拥挤']分词之后要按停用词表过滤。“的”“了”“是”这些词出现频率极高,但对热点分析没有帮助。停用词表网上有现成的,也可以自己在 Admin 后台维护一份,随时往里加。这个能力在答辩时很容易加分,说明你考虑到了可维护性。
还有一类词不能丢,比如“高峰期”“性价比”“客服态度”。这类词是评论里的关键实体,但它们可能被 jieba 切成碎片。解决办法是加载自定义词典,把领域词强制识别为整体。比如做外卖领域分析,就把“配送超时”“包装破损”加入自定义词典。
jieba.load_userdict("extra_dict.txt") # extra_dict.txt 每行: 词语 词频 词性 # 配送超时 5 n # 性价比 5 n清洗和分词做完,原始评论表之外应该有一张“分词结果表”或者至少加三个字段:words_json、clean_content、is_valid。后期做关键词提取、聚合评论都会方便很多。
4. 热点问题挖掘:从词频到“突发话题”的算法落地
热点挖掘是答辩评委最容易盯上的部分,因为它是整个系统的“智能点”。能讲清楚算法原理,比跑通代码更值钱。
4.1 为什么不能只用词频统计
如果直接对所有评论做词频统计,得到的结果通常是“的”“了”“好”“不”“很”这类常见词。即使过滤了停用词,“不错”“东西”“感觉”这类泛化词也会霸榜,因为它们几乎出现在每条评论里。
所以需要两个层面的改进:
- 用 TF-IDF 或者 TextRank 这种“关键词提取”算法,解决“常见词权重过高”的问题。
- 用时间窗口对比,解决“到底是长期问题还是最近突发”的问题。
一句话理解:热点 = 关键词 × 突发性。今天出现很高频的词,如果过去也一直很高频,那不叫热点,叫常态问题;今天暴涨的词才叫热点。
4.2 TF-IDF 的实现与局限
TF-IDF 的核心思想是:一个词在当前评论里出现得多,但在所有评论里出现得少,那这个词就有区分度,更像这篇文章或这条评论的特征词。
公式不用死记,但要能复述:
- TF(词频)= 词在文档中出现的次数 / 文档总词数
- IDF(逆文档频率)= log(总文档数 / 包含该词的文档数 + 1)
- TF-IDF = TF × IDF
在 Django 里实现时,可以直接用 sklearn 的TfidfVectorizer:
from sklearn.feature_extraction.text import TfidfVectorizer corpus = [ "配送超时 包装破损", "口味不错 就是太咸", "配送太慢 汤洒了" ] vectorizer = TfidfVectorizer(token_pattern=r'\S+') tfidf = vectorizer.fit_transform(corpus) names = vectorizer.get_feature_names_out() # 拿到每个词在所有评论里的 tf-idf 权重矩阵 for i in range(len(corpus)): row = tfidf.getrow(i).toarray()[0] word_weight = dict(zip(names, row)) top_words = sorted(word_weight.items(), key=lambda x: x[1], reverse=True)[:5] print(top_words)TF-IDF 适合做“单条评论特征词”的提取,但如果想对整个时间窗口内的“热点词”排序,还需要把权重再加总。至于没有做任何训练这一点,答辩时可以强调:无监督方法,适用于没有标注数据的情况。
不过 TF-IDF 有个缺点:它没有考虑词与词之间的顺序关系。“非常好吃”被拆成“非常”和“好吃”,如果只取权重,可能同时得到两个中低权重词,而不是一个高权重的短语。这时候可以引入 TextRank。
4.3 用 TextRank 挖掘短语级热点
TextRank 的思想和网页排序类似:把句子里的词当作节点,如果两个词在同一个窗口内共现,就认为它们之间存在“连接”。经过多轮迭代,被越多重要词连接的词就越重要。
jieba.analyse.textrank可以直接用:
import jieba.analyse text = "高峰期等位时间太长,服务员态度也不行,整体体验很差" keywords = jieba.analyse.textrank(text, topK=5) # 输出类似 ['等位', '高峰期', '服务员', '态度', '体验']TextRank 更擅长抽取长文本的关键词,但如果一条评论只有几十个字,效果可能没那么明显。所以实际项目里通常把一天内的所有评论文本拼接成一个大文本,再跑 TextRank,这样能提取出一天内的关键词集合。
我记得当时做测试时发现:TextRank 对“排队时间长”“上菜速度慢”这种明显带有情绪的短语识别度比 TF-IDF 好,因为它保留了词语共现关系。
4.4 时间窗口突变检测:真正让“热点”浮现的机制
关键词算法做了“降噪”,但还没解决“突发”。热点问题的定义是:某个时间段的词频显著高于历史均值。
具体做法是分层:把时间切成“当天”和“过去一段时间的基线窗口”两个维度。对每个关键词算一个突发分:
score = (当天的词频 + 1) / log(历史平均词频 + 1)如果 score 超过阈值,就认为该词在当天形成了热点。实际工程里也可以用标准差的方式,类似 Z-Score:
score = (当前窗口词频 - 历史均值) / 历史标准差为了不让分母变成 0,个人建议用平滑参数。下面是个简化代码思路:
import math def burst_score(today_count, history_avg): if history_avg <= 0: return 0.0 return (today_count + 1) / math.log(history_avg + 2) # 示例 today_counts = {"配送超时": 80, "口味": 100} history_avg = {"配送超时": 5, "口味": 90} for word, t_cnt in today_counts.items(): print(word, burst_score(t_cnt, history_avg[word]))计算出来,“配送超时”的突发分就远高于“口味”,哪怕“口味”出现次数更多,系统也能准确判断“配送超时”才是当前热点。这个对比非常适合在答辩现场演示,一张表就讲清楚“热点不等于高频”。
再往下做,还可以对新词挖掘增加一个“凝固度”指标。简单说,如果“包装”和“破损”总是黏在一起出现,那它们的凝固度就高,可以组成新词“包装破损”。这个属于加分项,时间不够可以略过。
在这个阶段,建议保留三张表:trend_keyword(关键词、日期、频次、突发分)、hotspot(热点问题、起止时间、相关评论数)、hotspot_comment_rel(热点和评论的多对多关系)。后续小程序展示需要这些关联。
5. 反馈分析:情感倾向和主题聚类怎么落库
热点挖掘解决了“大家在讨论什么”的问题,反馈分析要解决“大家是正向反馈还是负向吐槽”的问题。
5.1 基于情感词典的情感判别:性价比最高
毕设阶段,不一定要上深度学习模型。用情感词典的方式,速度快、可解释性强,答辩时逻辑也清晰。
先准备一份中文情感词典,包含正面词、负面词、程度副词和否定词。然后对每条评论做这样的打分:
- 分词后,逐个词匹配情感词典。
- 正面词加 1 分,负面词减 1 分。
- 如果情感词前存在否定词,比如“不满意”,情感分数要翻转。
- 如果存在程度副词,比如“非常”“特别”,分数乘以相应权重。
设计一个简单的判断函数:
def sentiment_score(words): score = 0 negate = False adverb_weight = 1.0 for w in words: if w in negative_words: score += -1 * adverb_weight * (-1 if negate else 1) negate = False adverb_weight = 1.0 elif w in positive_words: score += 1 * adverb_weight * (-1 if negate else 1) negate = False adverb_weight = 1.0 elif w in neg_words: negate = not negate elif w in adverb_words: adverb_weight = 2.0 else: negate = False adverb_weight = 1.0 return score最后根据总分映射为“好评/中评/差评”,然后按天统计正负面比例。
这个方法有缺点:无法理解“这餐厅太难吃了,服务员态度倒是挺好”这种转折句。但毕设不需要完美,你可以在文档里承认该方法的局限,并提出可以用 BERT 微调做优化——留一个“未来展望”的切口,反而显得你思考深入。
5.2 主题聚类:把同类型反馈归到一起
热点词只是关键词,为了生成“反馈分析报告”,还要把评论归类到几个核心主题下,比如“配送服务”“菜品质量”“价格问题”“环境卫生”。
最简单的做法是对清洗后的文本做向量化,再用 KMeans 聚类。向量化可以用 TF-IDF 或者 Word2Vec。KMeans 的簇数 K 可以预先设定为 4 到 6 类,然后对每个簇提取高频词,人工给簇打一个主题标签。
from sklearn.cluster import KMeans from sklearn.feature_extraction.text import TfidfVectorizer vectorizer = TfidfVectorizer(token_pattern=r'\S+', max_features=2000) X = vectorizer.fit_transform(cleaned_comments) model = KMeans(n_clusters=5, random_state=42) labels = model.fit_predict(X)聚类结果的解释性是这类系统的关键。KMeans 完成后,还得按簇输出 top 词,帮你决定这个簇到底叫“价格敏感”还是“服务态度”。这一步建议做成半自动:算法给候选,人工确认标签,然后在系统里落库。
5.3 可视化指标:小程序里呈现什么数据才显得专业
反馈分析的输出不建议直接丢一堆数字,而是做成四个维度:
| 指标 | 展示形式 | 说明 |
|---|---|---|
| 情感占比 | 饼图 | 当天正面/负面/中性评论占比 |
| 情感趋势 | 折线图 | 近7天负面情绪评论数量走向 |
| 主题分布 | 横向柱状图 | 各主题问题对应的评论条数 |
| 热词排行 | 词云 / 榜单 | 高突发分的词列表 |
我的经验是:小程序首页先放“今日热点词”,进入详情页再放“情感分布和趋势”,最后放“相关评论列表”。这个结构符合人的认知习惯:先看结论,再看数据,再看证据。
后台接口返回 JSON 时,不要前端拿到列表再自己统计。Django 里可以一次返回统计好的 summarizer 数据:
{ "date": "2025-06-01", "sentiment_ratio": {"positive": 0.55, "negative": 0.3, "neutral": 0.15}, "trend": [ {"date": "2025-05-26", "negative": 12}, {"date": "2025-05-27", "negative": 18} ], "hot_keywords": [ {"word": "配送超时", "burst_score": 8.2, "count": 80} ] }这种结构化的接口在答辩演示时最省心,小程序不用做二次计算,响应也快。
6. 小程序端:把算法结果变成可交互的产品
小程序表面是展示层,但它决定了评委的第一印象。在这个项目里,小程序要承担热榜查看、反馈报告浏览和评论详情查看三个核心任务。
6.1 页面结构与功能对照
我建议做四个 tab:
- 热点tab:顶部是今日热词排行,下面是可以横向滑动的突发分趋势图。
- 反馈tab:情感占比饼图 + 主题分布柱状图 + 近 7 天负面趋势。
- 评论tab:按热点词筛选的评论流,显示用户头像、昵称脱敏、评论文本、情感标签。
- 我的tab:登录注册、历史查看记录、关于系统。
热点详情页,从热词点击进入后展示该词的频次变化曲线、相关评论列表、情感占比。这一页是整个小程序的“高潮页面”,一定要把评论和热点之间的关联做清楚。
6.2 Django 接口设计与权限控制
接口设计推荐使用 Django REST Framework,路由如下:
| 接口 | 方法 | 说明 |
|---|---|---|
| /api/auth/token/ | POST | 用户登录获取 JWT |
| /api/hotspots/today/ | GET | 今日热点词列表 |
| /api/hotspots/{id}/detail/ | GET | 热点详情与相关评论 |
| /api/analysis/summary/ | GET | 情感占比与主题分布 |
| /api/comments/?keyword=xx | GET | 按关键词过滤的评论分页 |
权限方面,公开的统计接口可以用AllowAny或者只做简单限流;涉及用户浏览记录和收藏的接口,必须用 JWT 保护。用 simplejwt 之后,Django 里加一个权限类就能搞定:
from rest_framework.permissions import IsAuthenticated from rest_framework.views import APIView class UserHistoryView(APIView): permission_classes = [IsAuthenticated]小程序端在请求头里加上Authorization: Bearer <token>即可。
6.3 小程序本地联调:一定绕不开的问题
第一,开发时小程序要求 request 的域名必须备案且配置合法域名。本地调试时,最省事的办法是在小程序开发者工具的本地设置里勾选“不校验合法域名”,但正式上线前必须配置真实域名。毕设一般不要求上线,演示时勾选不校验即可,自己心里要清楚这一点。
第二,本地后端要能被手机访问。建议后端启动时用0.0.0.0:8000,然后通过局域网 IP 在小程序里配置baseUrl。注意 Windows 防火墙要放行 8000 端口,Android 模拟器里访问本机要用 10.0.2.2 而不是 127.0.0.1。
第三,接口跨域问题。小程序请求本身没有传统浏览器跨域限制,但如果你用开发者工具预览的页面模式调试 H5 版本时,则需要在 Django 里配置跨域白名单。
7. 毕设完整度:文档、演示脚本和答辩话术
这部分的权重,绝对不亚于代码本身。很多同学代码能跑但答辩不过,就是因为不会“叙事”。
7.1 交付的四件套
做这套系统,最终交付通常包括四块内容:
- 可运行的源码包(Django 后端 + 小程序前端 + 数据库初始化 SQL)
- 毕业论文文档
- 代码讲解视频或现场讲解稿
- 演示数据
我强烈建议在做项目第一天就建立目录结构,源码和文档分开放,不要最后打包成一个乱糟糟的 zip。
7.2 论文目录:按“提出问题—构建系统—验证效果”组织
论文可以按下面的章节来写:
- 绪论:背景、国内外研究现状、研究内容
- 相关技术介绍:Django、小程序、TF-IDF、TextRank、情感分析
- 需求分析:功能性需求、非功能性需求、用例图
- 系统设计:总体架构、数据库设计、接口设计、算法流程
- 系统实现:核心模块代码与截图
- 系统测试:功能测试用例、性能测试、结果分析
- 总结与展望
写文档时有个技巧:算法章节要多画流程图和数据流图,不要只贴代码。评委老师通常先翻图和表格,再决定要不要细看内容。
7.3 答辩演示脚本:一条能讲 10 分钟的故事线
演示前,先设计一个具体场景。比如:
“现在是某外卖平台的一天运营结束,系统自动抓取了 1000 条今日评论。经过数据清洗,剩余有效评论 850 条。系统通过 TF-IDF 和 TextRank 提取关键词,结合时间窗口的突发检测,发现‘包装破损’今天的突发分达到 8.5,远高于历史均值。点进这个热点,可以看到 85 条相关评论,其中 70% 为负面,主要集中在下雨天。因此运营人员应该优先处理包装供应商的问题。”
这套话术把技术指标、数据和业务决策串在一起,比干巴巴报“我用了 TF-IDF”强得多。
答辩常见问题我也列几个:
- 为什么要用 Django?答:快速开发、内置 ORM 和 Admin、适合中小型数据系统。
- 热点是怎么定义的?答:关键词权重 + 时间窗口突发分数。
- 情感词典和深度学习哪个更好?答:情感词典可解释性强、训练成本低,但深度学习更准,未来可以优化。
- 如果评论量很大,系统怎么扩展?答:可以引入消息队列和分布式爬虫,Django 负责 API,算法用 Celery 异步任务。
8. 排错复盘:这个项目最容易踩的五个坑
最后一部分,说几个这个系统特有的、几乎每做一个都会踩一遍的坑。
8.1 中文乱码问题
最容易踩的坑发生在 MySQL 建库时没有指定字符集。评论数据一写入,就出现一堆问号。建库时一定要写成:
CREATE DATABASE comment_system CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;如果是从外部数据文件导入,读取 CSV 时也注意编码,通常要指定encoding='utf-8'。有些数据源是 GBK,那就得按gbk读再转成 unicode。
8.2 时区问题导致热点统计错位
Django 默认USE_TZ=True,数据库里存的是 UTC 时间。如果你直接用date.today()去按天分组,到了晚上更新的时候,统计出来的“今天”可能少几个小时。正确的做法是:
from django.utils import timezone from datetime import timedelta now = timezone.localtime() today_start = now.replace(hour=0, minute=0, second=0, microsecond=0)我调试的时候,连续两次发现热点词在 00:00 附近的统计结果与直觉不符,最后定位就是时区问题。改完之后一切正常,这个小坑在文档里写出来也是加分项。
8.3 全量分割导致分词特别慢
如果每天抓几千条评论,跑一次全量分词还勉强能忍。但如果规模上万,直接在视图函数里做算法计算会让小程序接口卡死。解决方案是把分词、热点计算放到 Django 管理命令或者 Celery 异步任务里,生成结果后再提供查询接口。
python manage.py run_analysis --date=2025-06-01清早跑一次分析,白天只查表,性能和逻辑都会干净很多。
8.4 小程序请求后端失败
本地调试阶段,90% 的 request 失败不是因为代码问题,而是“未配置合法域名”和“手机访问不到电脑”。前者在开发者工具里可以临时关闭校验,后者要确保手机和电脑在同一局域网,并关闭防火墙限制。如果不想用局域网,也可以部署到一台云服务器,做好 HTTPS 后配置合法域名,唯一注意别把密钥暴露在代码里。
8.5 把评分字段和分析结果混在一起
很多平台自带评分(1到5分),有人会直接拿评分当情感分析结果,这是两码事。评分是用户的整体满意度,评论里可能先夸“好吃”再骂“等位太久”,这句评论的情绪其实是混合的。不要嫌麻烦,单独做一条“情绪极性”分析,和评分分开,论证才严谨。
最后一个实用建议:项目里的小程序端和后台 Admin 都记得先准备一份演示账号和数据。不要到答辩现场才临时去爬评论、跑任务。把今日热点词提前算好,录入照片和截图,演示时照着脚本走,整个节奏会非常顺畅。真正让评委信服的,不是你在台上敲了多少代码,而是你对这套系统从数据采集到热词展示的每一步都说得有理有据。这篇项目的核心价值,恰恰就在这个完整链路里。