✅ Python微博舆情分析系统 Flask+SnowNLP情感分析 词云可视化 爬虫大数据 爬虫+机器学习+可视化
【摘要】该项目基于Python技术栈开发了一套微博舆情分析系统,整合了爬虫抓取、情感分析、可视化展示等完整功能。系统采用Flask框架搭建Web平台,通过requests+代理池技术实现微博数据抓取,结合SnowNLP进行情感倾向分析,并利用ECharts生成热词统计、词云、舆情走势等多维度可视化图表。核心功能包括:实时舆情监测、情感极性判定、热词追踪、用户画像分析等,支持数据导出与后台管理。该系
博主介绍:✌全网粉丝50W+,前互联网大厂软件研发、集结硕博英豪成立软件开发工作室,专注于计算机相关专业项目实战6年之久,累计开发项目作品上万套。凭借丰富的经验与专业实力,已帮助成千上万的学生顺利毕业,选择我们,就是选择放心、选择安心毕业✌
> 🍅想要获取完整文章或者源码,或者代做,拉到文章底部即可与我联系了。🍅🍅感兴趣的可以先收藏起来,点赞、关注不迷路,大家在毕设选题,项目以及论文编写等相关问题都可以给我留言咨询,希望帮助同学们顺利毕业 。🍅
1、毕业设计:2026年计算机专业毕业设计选题汇总(建议收藏)✅
1、项目介绍
技术栈:Python语言、Flask框架、MySQL数据库、requests网络爬虫技术、scikit-learn机器学习、snownlp情感分析、词云、舆情分析
功能:微博数据爬取→情感倾向判定→热词/词云/IP地域→可视化大屏→CSV/MySQL导出
研究背景:社交媒体已成为舆情主阵地,快速感知网民情绪对品牌、政务、金融风控价值巨大;Python+爬虫+ML可低成本构建舆情洞察原型。
研究意义:将“爬虫-清洗-NLP-可视化”完整链路封装成Flask Web系统,为舆情监测、市场营销、毕业设计提供一键复用的开源方案。
2、项目界面
(1)系统首页-数据概况
(2)微博舆情统计分析
(3)舆情文章分析
(4)IP地址分析
(5)舆情数据
(6)舆情评论分析
(7)舆情分析
(8)文章内容词云分析
3、项目说明
-
开发工具
本项目在PyCharm IDE下使用Python 3.8完成,借助其强大的调试、虚拟环境与Git集成,显著提高开发效率。 -
数据获取
通过requests+Session池模拟登录微博,采用随机UA、IP代理与重试机制绕过反爬,定时抓取微博正文、发布时间、用户昵称、IP归属地、点赞/评论/转发量等字段;数据经过去重、清洗后使用PyMySQL+SQLAlchemy写入MySQL,同时生成CSV备份,确保后续分析任务数据完整且更新及时。 -
微博热词统计
① 热点年份变化趋势:按年聚合高频关键词,折线图展示话题迁移轨迹,可观察社会焦点从“娱乐明星”向“社会事件”再向“科技前沿”的演变。
② 热词情感分析:调用SnowNLP计算每条微博的positive/negative概率,堆叠面积图呈现情感比例随时间波动,帮助捕捉突发事件引发的舆论反转。
③ 热词频率分析:使用Counter+Jieba分词,剔除停用词后生成Top30词频柱状图,支持交互式下钻查看具体微博列表。 -
微博文章分析
① 类型占比:按“原创/转发/长文”打标签,饼图展示分布,洞察平台内容生态。
② 评论量&转发量:箱线图呈现区间分布,辅助评估话题互动深度。
③ 词云:TF-IDF提取关键词,蒙版轮廓采用微博logo,增强品牌识别度。
④ 基本信息统计:折线图展示阅读量、发布时间24h分布,为内容运营提供数据依据。 -
微博评论分析
① 性别占比:爬取用户资料页性别字段,玫瑰图展示男女比例,可辅助判断话题受众偏向。
② 评论词云:单独对评论分词,高频词以心形蒙版呈现,直观反映网友情绪焦点。
③ 点赞排行:柱状图展示高赞评论,点击条目可跳转原文,快速定位“金句”或“爆点”。 -
微博舆情分析
① 热词情感趋势:以周为粒度,绘制positive/negative曲线,叠加微博发布量柱状图,一眼看出“量增情降”或“量降情升”的异常周。
② 舆情走势:融合文章与评论情感,采用7日滑动平均,预测未来3天情绪走向(线性回归),为品牌方或政务部门提供决策参考。
系统采用Flask+MySQL架构,前端使用Bootstrap+ECharts,所有图表支持一键导出PNG/CSV;后台管理可配置爬虫频率、敏感词过滤、用户权限;整个工程代码开源、环境一键复现,是舆情监控、市场营销、毕业设计的理想模板。
4、核心代码
from utils import getPublicData
import jieba
import matplotlib.pyplot as plt
from wordcloud import WordCloud, ImageColorGenerator
from PIL import Image # 图片处理
import numpy as np
from snownlp import SnowNLP
def getTypeList():
typeList = list(set([x[8] for x in getPublicData.getAllData()]))
return typeList
def getArticleCharOneData(defaultType):
articleList = getPublicData.getAllData()
xData = []
rangeNum = 1000
for item in range(1,15):
xData.append(str(rangeNum * item)+ '-' + str(rangeNum*(item+1)))
yData = [0 for x in range(len(xData))]
for article in articleList:
if article[8] != defaultType:
for item in range(14):
if int(article[1]) < rangeNum*(item+2):
yData[item] += 1
break
return xData,yData
def getArticleCharTwoData(defaultType):
articleList = getPublicData.getAllData()
xData = []
rangeNum = 1000
for item in range(1,15):
xData.append(str(rangeNum * item)+ '-' + str(rangeNum*(item+1)))
yData = [0 for x in range(len(xData))]
for article in articleList:
if article[8] != defaultType:
for item in range(14):
if int(article[2]) < rangeNum*(item+2):
yData[item] += 1
break
return xData,yData
def getArticleCharThreeData(defaultType):
articleList = getPublicData.getAllData()
xData = []
rangeNum = 50
for item in range(1, 30):
xData.append(str(rangeNum * item) + '-' + str(rangeNum * (item + 1)))
yData = [0 for x in range(len(xData))]
for article in articleList:
if article[8] != defaultType:
for item in range(29):
if int(article[2]) < rangeNum * (item + 2):
yData[item] += 1
break
return xData, yData
def getGeoCharDataTwo():
cityList = getPublicData.cityList
commentList = getPublicData.getAllCommentsData()
cityDic = {}
for comment in commentList:
if comment[3] == '无': continue
for j in cityList:
if j['province'].find(comment[3]) != -1:
if cityDic.get(j['province'], -1) == -1:
cityDic[j['province']] = 1
else:
cityDic[j['province']] += 1
cityDicList = []
for key, value in cityDic.items():
cityDicList.append({
'name': key,
'value': value
})
return cityDicList
def getGeoCharDataOne():
cityList = getPublicData.cityList
articleList = getPublicData.getAllData()
cityDic = {}
for article in articleList:
if article[4] == '无':continue
for j in cityList:
if j['province'].find(article[4]) != -1:
if cityDic.get(j['province'],-1) == -1:
cityDic[j['province']] = 1
else:
cityDic[j['province']] += 1
cityDicList = []
for key, value in cityDic.items():
cityDicList.append({
'name': key,
'value': value
})
return cityDicList
def getCommetCharDataOne():
commentList = getPublicData.getAllCommentsData()
xData = []
rangeNum = 20
for item in range(1, 100):
xData.append(str(rangeNum * item) + '-' + str(rangeNum * (item + 1)))
yData = [0 for x in range(len(xData))]
for comment in commentList:
for item in range(99):
if int(comment[2]) < rangeNum * (item + 2):
yData[item] += 1
break
return xData, yData
def getCommetCharDataTwo():
commentList = getPublicData.getAllCommentsData()
genderDic = {}
for i in commentList:
if genderDic.get(i[6],-1) == -1:
genderDic[i[6]] = 1
else:
genderDic[i[6]] += 1
resultData = [{
'name':x[0],
'value':x[1]
} for x in genderDic.items()]
return resultData
def stopwordslist():
stopwords = [line.strip() for line in open('./model/stopWords.txt',encoding='UTF-8').readlines()]
return stopwords
def getContentCloud():
text = ''
stopwords = stopwordslist()
articleList = getPublicData.getAllData()
for article in articleList:
text += article[5]
cut = jieba.cut(text)
newCut = []
for word in cut:
if word not in stopwords: newCut.append(word)
string = ' '.join(newCut)
img = Image.open('./static/content.jpg') # 打开遮罩图片
img_arr = np.array(img) # 将图片转化为列表
wc = WordCloud(
width=1000, height=600,
background_color='white',
colormap='Blues',
font_path='STHUPO.TTF',
mask=img_arr,
)
wc.generate_from_text(string)
# 绘制图片
fig = plt.figure(1)
plt.imshow(wc)
plt.axis('off') # 不显示坐标轴
# 显示生成的词语图片
# plt.show()
# 输入词语图片到文件
plt.savefig('./static/contentCloud.jpg', dpi=500)
def getCommentContentCloud():
text = ''
stopwords = stopwordslist()
commentsList = getPublicData.getAllCommentsData()
for comment in commentsList:
text += comment[4]
cut = jieba.cut(text)
newCut = []
for word in cut:
if word not in stopwords:newCut.append(word)
string = ' '.join(newCut)
img = Image.open('./static/comment.jpg') # 打开遮罩图片
img_arr = np.array(img) # 将图片转化为列表
wc = WordCloud(
width=1000, height=600,
background_color='white',
colormap='Blues',
font_path='STHUPO.TTF',
mask=img_arr,
)
wc.generate_from_text(string)
# 绘制图片
fig = plt.figure(1)
plt.imshow(wc)
plt.axis('off') # 不显示坐标轴
# 显示生成的词语图片
# plt.show()
# 输入词语图片到文件
plt.savefig('./static/commentCloud.jpg', dpi=500)
def getYuQingCharDataOne():
hotWordList = getPublicData.getAllCiPingTotal()
xData = ['正面', '中性', '负面']
yData = [0,0,0]
for hotWord in hotWordList:
emotionValue = SnowNLP(hotWord[0]).sentiments
if emotionValue > 0.5:
yData[0] +=1
elif emotionValue == 0.5:
yData[1] += 1
elif emotionValue < 0.5:
yData[2] += 1
bieData = [{
'name': '正面',
'value': yData[0]
}, {
'name': '中性',
'value': yData[1]
}, {
'name': '负面',
'value': yData[2]
}]
return xData,yData,bieData
def getYuQingCharDataTwo():
bieData1 = [{
'name':'正面',
'value':0
},{
'name':'中性',
'value':0
},{
'name':'负面',
'value':0
}]
bieData2 = [{
'name': '正面',
'value': 0
}, {
'name': '中性',
'value': 0
}, {
'name': '负面',
'value': 0
}]
commentList = getPublicData.getAllCommentsData()
articleList = getPublicData.getAllData()
for comment in commentList:
emotionValue = SnowNLP(comment[4]).sentiments
if emotionValue > 0.5:
bieData1[0]['value'] += 1
elif emotionValue == 0.5:
bieData1[1]['value'] += 1
elif emotionValue < 0.5:
bieData1[2]['value'] += 1
for article in articleList:
emotionValue = SnowNLP(article[5]).sentiments
if emotionValue > 0.5:
bieData2[0]['value'] += 1
elif emotionValue == 0.5:
bieData2[1]['value'] += 1
elif emotionValue < 0.5:
bieData2[2]['value'] += 1
return bieData1,bieData2
def getYuQingCharDataThree():
hotWordList = getPublicData.getAllCiPingTotal()
return [x[0] for x in hotWordList],[int(x[1]) for x in hotWordList]
🍅✌感兴趣的可以先收藏起来,点赞关注不迷路,想学习更多项目可以查看主页,大家在毕设选题,项目编程以及论文编写等相关问题都可以给我留言咨询,希望可以帮助同学们顺利毕业!🍅✌
5、源码获取方式
🍅由于篇幅限制,获取完整文章或源码、代做项目的,拉到文章底部即可看到个人联系方式。🍅
点赞、收藏、关注,不迷路,下方查看👇🏻获取联系方式👇🏻
火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。
更多推荐
所有评论(0)