Flask+MySQL多角色舆情监控系统实战
2026/9/17 3:40:29 网站建设 项目流程

简介:本资源是一套完整的基于Python开发的网络舆情分析系统源码,面向高校计算机专业毕业生、课程设计学生及舆情监控领域初学者,解决多用户协同下的网络言论采集、情感分析与可视化呈现问题。系统采用前后端分离架构,含MySQL 5.7数据库脚本、PyCharm工程、LayUI前端静态资源(css/js/html)及Python后端逻辑(42个.py文件),支持饼状图统计、用户密码维护、管理员多级权限管理等功能。压缩包共289个文件,涵盖42个Python源码、34个JavaScript脚本、28个JPG图片、15个CSS样式表及12个HTML页面等,总大小83.39MB,结构清晰,便于理解MVC分层与舆情数据流闭环。已有100人学习下载,配套说明文档与LW(论文)齐全,开箱即用,适合毕设快速部署、技术栈整合实践与NLP应用入门拓展。

1. 这不是又一个“词云+情感分析”的Demo,而是一套可上线的多角色舆情监控系统

你见过太多用jieba分词+TextBlob打分+echarts画图的“舆情分析”课程设计——界面简陋、数据静态、权限形同虚设、部署文档只有三行字。但这个基于Python的网络舆情分析系统完全不同:它内置MySQL 5.7完整建表脚本与初始化数据,前端用LayUI 2.x构建了带登录态、角色隔离、动态日期控件(laydate)、可点击列交互(layui table)的真实管理后台;后端采用Flask 1.1.2(非Django,从源码结构和路由组织方式可确认),实现了用户会话校验、SQL注入防护、密码SHA256加盐存储、管理员级用户CRUD闭环。它面向的是真实场景中的舆情监控岗人员——需要同时处理多个监测关键词、查看实时情感分布饼图、导出原始评论CSV、重置下属账号密码。如果你正为毕业设计卡在“如何让系统看起来像真正在用”,或课程设计被要求“必须支持多用户+权限分级+数据库持久化”,这套代码就是你跳过90%重复劳动的起点。

2. Flask后端架构解析与MySQL数据模型落地

2.1 为什么选Flask而非Django?从源码结构看工程权衡

项目未使用Django的ORM和Admin后台,而是选择轻量级Flask框架,这并非技术退步,而是针对课程设计场景的务实选择。查看app.py主入口文件,其路由组织清晰体现三层职责分离:/login/logout处理认证,/admin/*路径强制@admin_required装饰器校验,/user/profile等接口则通过session.get('role')动态控制返回字段。这种显式权限控制比Django的ModelAdmin更易理解、更易调试——尤其对Python 3.6.8环境下的初学者而言,避免了Django中间件链和信号机制带来的黑盒感。更重要的是,所有数据库操作均通过pymysql原生执行(而非SQLAlchemy ORM),这意味着你在models.py里看到的每一条INSERT INTO t_user ...语句,都能直接对应到MySQL实际执行计划,便于排查慢查询和索引缺失问题。

提示:不要试图将此项目强行改造成Django项目。Flask的简洁性正是其教学价值所在——它强迫你直面HTTP请求生命周期、Session管理、SQL拼接风险等底层概念,而这恰恰是毕业答辩时最能体现你“真正懂了”的部分。

2.2 MySQL 5.7建模逻辑:从舆情业务流反推表结构

系统共定义6张核心表,全部位于sql/init.sql中。关键设计点在于舆情数据采集与分析解耦t_comment表仅存储原始文本、来源平台、发布时间、关联关键词ID;而t_analysis_result表则记录每次分析任务的ID、执行时间、情感正/负/中数量、高频词TOP10 JSON字符串。这种分离使系统支持“同一组评论多次分析”(如更换停用词库后重跑),避免数据污染。以下是t_user表的关键字段说明:

字段名类型约束说明
idINT(11) PK AI主键自增用户唯一标识
usernameVARCHAR(50) UNIQUE非空+唯一登录账号,长度限制防SQL注入
passwordVARCHAR(128)非空SHA256加盐哈希值,盐值存于config.py
roleTINYINT(1) DEFAULT 00=普通用户,1=管理员权限判断唯一依据,无冗余角色表
create_timeDATETIME DEFAULT CURRENT_TIMESTAMP账号创建时间,用于审计

执行建库命令时需注意字符集统一:

mysql -u root -p -e "CREATE DATABASE IF NOT EXISTS舆情分析 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;" mysql -u root -p 舆情分析 < sql/init.sql

注意:utf8mb4是必须项。原始评论可能含Emoji(如👍、🔥),若用utf8会导致插入失败或乱码。Navicat 11连接时需在连接属性→高级→字符集选utf8mb4,否则即使建库正确,客户端仍显示?号。

2.3 Flask配置与安全加固:从开发到部署的参数迁移

config.py中定义了三套环境配置,但实际部署只需关注ProductionConfig

class ProductionConfig(Config): DEBUG = False SECRET_KEY = os.environ.get('SECRET_KEY') or 'your_production_secret_key_here' SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:password@127.0.0.1:3306/舆情分析?charset=utf8mb4' # 关键:禁用SQLAlchemy事件监听,因本项目直接使用pymysql SQLALCHEMY_TRACK_MODIFICATIONS = False

但源码中并未使用SQLAlchemy,因此该配置实为冗余。真正生效的是db.py中的连接池设置:

import pymysql from DBUtils.PooledDB import PooledDB pool = PooledDB( creator=pymysql, maxconnections=6, # 并发用户数上限 mincached=2, # 初始化连接数 host='127.0.0.1', port=3306, user='root', password='your_mysql_password', database='舆情分析', charset='utf8mb4', autocommit=True )

此处autocommit=True至关重要——舆情分析任务常涉及批量插入(如一次导入5000条评论),若手动commit,网络波动可能导致事务挂起,阻塞后续请求。而自动提交虽牺牲部分ACID,却极大提升高并发场景下的响应稳定性。

3. LayUI前端实现细节与动态交互开发

3.1 LayUI组件链式调用:从登录页到管理员面板的权限流转

系统前端未使用Vue或React,而是基于LayUI 2.8.18(从static/layui/layui.js末尾注释可确认版本)。其核心优势在于零构建工具依赖:所有JS/CSS直接引用,适合课程设计快速验证。登录流程的关键在于login.js中对layer.msglocation.href的组合使用:

// login.js 第42行 $.post('/login', {username: username, password: password}, function(res) { if (res.code === 0) { layer.msg('登录成功', {icon: 1}); // 根据role字段跳转不同首页 if (res.data.role === 1) { location.href = '/admin/index.html'; // 管理员进入后台 } else { location.href = '/user/index.html'; // 普通用户进入仪表盘 } } else { layer.msg(res.msg, {icon: 2}); // 错误提示图标 } });

这种服务端返回role字段、前端跳转不同HTML的方案,比单页应用(SPA)更易调试——你可以在浏览器Network面板直接看到/login返回的JSON,确认data.role值是否正确,避免Vue Router路由守卫的隐式跳转陷阱。

3.2 LayDate日期控件实战:绑定当前日期并限制最大可选范围

舆情分析常需指定“近7天”、“本月”等时间范围。laydate.render()admin/statistics.html中被这样调用:

laydate.render({ elem: '#dateRange', range: true, format: 'yyyy-MM-dd', max: 0, // 关键参数:最大日期为今天 done: function(value, date, endDate) { // value为'2024-03-01 - 2024-03-07'格式字符串 $('#searchBtn').click(); // 触发搜索 } });

max: 0是LayUI特有语法,表示“以当天为最大可选日期”。若需限制为“过去30天”,则改为min: laydate.now(-30, 'yyyy-MM-dd')。此处done回调函数的设计优于change事件——它确保用户完成双日期选择后才触发搜索,避免单侧日期变更就发起无效请求。

3.3 LayUI Table列事件绑定:实现“点击用户名查看详情”的交互

普通用户列表页(admin/user_list.html)需支持点击用户名弹出详情Modal。LayUI Table默认不支持单列事件,需通过cellEvent扩展:

table.render({ elem: '#userTable', url: '/admin/get_users', cols: [[ {type: 'checkbox'}, {field: 'username', title: '用户名', width: 120, templet: '<div class="layui-table-link" lay-event="view">{{d.username}}</div>'}, {field: 'role', title: '角色', width: 80, templet: '<span>{{d.role==1?"管理员":"普通用户"}}</span>'}, {title: '操作', width: 180, align: 'center', toolbar: '#userBar'} ]], page: true, limit: 10 }); // 绑定自定义事件 table.on('tool(userTable)', function(obj) { if (obj.event === 'view') { layer.open({ title: '用户详情', content: '/admin/user_detail.html?id=' + obj.data.id, area: ['600px', '400px'] }); } });

关键点在于templet中添加lay-event="view"属性,并在table.on()中监听tool(userTable)事件。这种写法比jQuery.on('click', '.layui-table-link', ...)更可靠——它由LayUI内部事件代理机制保证,即使表格翻页后新渲染的行也能响应。

4. 舆情分析核心算法实现与可视化配置

4.1 基于SnowNLP的情感极性计算:为何不用BERT?

项目在analysis/sentiment.py中采用SnowNLP而非BERT或RoBERTa,这是课程设计场景下的理性选择。SnowNLP训练语料来自微博短文本,对中文网络用语(如“绝绝子”、“yyds”)识别率高于通用预训练模型。其核心代码仅3行:

from snownlp import SnowNLP def get_sentiment(text): s = SnowNLP(text) # 返回0~1之间数值,>0.5为正面,<0.5为负面 return round(s.sentiments, 3) # 批量处理示例 comments = ["这个产品太棒了!", "客服态度差,再也不买了"] results = [get_sentiment(c) for c in comments] # [0.821, 0.134]

s.sentiments返回的是情感倾向概率,非简单正/负标签。系统在analysis/analysis_service.py中将其离散化:

if sentiment_score > 0.6: category = 'positive' elif sentiment_score < 0.4: category = 'negative' else: category = 'neutral'

阈值0.6/0.4经过实测调整——若用0.5分割,大量中性评论(如“还行”、“一般”)会被错误归类。你可在config.py中修改SENTIMENT_THRESHOLD_POSITIVESENTIMENT_THRESHOLD_NEGATIVE参数进行微调。

4.2 饼状图数据生成:从MySQL聚合到ECharts渲染

前端user/index.html中ECharts饼图的数据源来自/api/get_sentiment_stats接口。后端SQL查询高度优化:

SELECT SUM(CASE WHEN sentiment='positive' THEN 1 ELSE 0 END) as positive, SUM(CASE WHEN sentiment='negative' THEN 1 ELSE 0 END) as negative, SUM(CASE WHEN sentiment='neutral' THEN 1 ELSE 0 END) as neutral FROM t_analysis_result ar JOIN t_comment c ON ar.comment_id = c.id WHERE c.create_time >= %s AND c.create_time <= %s

注意%s占位符由Python传入,避免字符串拼接导致SQL注入。返回JSON结构直接匹配EChartsseries.data

{ "code": 0, "data": [ {"value": 128, "name": "正面"}, {"value": 42, "name": "负面"}, {"value": 30, "name": "中性"} ] }

前端初始化代码精简有效:

option = { tooltip: {trigger: 'item'}, series: [{ type: 'pie', radius: ['40%', '70%'], data: response.data, // 直接赋值 label: {formatter: '{b}: {c} ({d}%)'} }] };

5. 部署排错与性能调优实战技巧

5.1 Navicat 11连接MySQL 5.7常见报错及修复方案

学生在Windows上用Navicat 11连接MySQL 5.7时,90%的失败源于驱动版本不匹配。Navicat 11默认使用mysql-connector-java-5.1.39.jar,而MySQL 5.7需mysql-connector-java-5.1.47.jar或更高。修复步骤:

  1. 下载mysql-connector-java-5.1.47.jar(官网归档版)
  2. 替换Navicat安装目录下drivers/mysql/中的旧jar包
  3. 在Navicat连接属性→驱动→选择新jar包路径
  4. 测试连接时勾选“允许在URL中使用SSL”

若仍报错Client does not support authentication protocol requested by server,需重置root密码:

-- 在MySQL命令行执行 ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'your_new_password'; FLUSH PRIVILEGES;

5.2 PyCharm调试Flask时端口冲突与热重载失效问题

PyCharm默认配置FLASK_APP=app.pyFLASK_ENV=development,但源码中app.run()未启用debug模式。需手动修改app.py末尾:

if __name__ == '__main__': app.run(host='0.0.0.0', port=5000, debug=True, use_reloader=True)

use_reloader=True是热重载关键。若修改templates/下HTML文件后页面不刷新,检查PyCharm设置:File→Settings→Tools→Python Console→勾选“Use IPython if available”并重启控制台。

5.3 LayUI日期控件位置偏移:CSS层叠冲突解决方案

部分用户反馈laydate日历面板出现在屏幕左上角而非输入框下方。根本原因是layui.css与自定义admin.css.layui-form-labelposition:relative被覆盖。临时修复方法(不推荐改源码):

/* 在admin.css末尾追加 */ .laydate-icon { position: relative !important; } .laydate-main-list { z-index: 999999 !important; }

长期方案是在admin.css中全局重置LayUI定位:

.layui-laydate { position: absolute !important; }

此问题在Chrome 115+版本中高频出现,本质是浏览器对position:fixed元素的渲染优化变更所致。

部署完成后访问http://localhost:5000/login,使用初始账号admin/123456登录,即可进入完整的舆情监控工作台——此时你拥有的不再是一个演示Demo,而是一套经得起课堂答辩、教师抽查、甚至稍作修改就能投入小型机构试用的生产级原型系统。

本文还有配套的精品资源,点击获取

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

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

立即咨询