词云 + 情感分析:爬取评论数据做舆情可视化实战
一、为什么要做这件事
舆情不是等爆了才发现的。一条产品评论、一段用户吐槽,背后是真实情绪的温度计。
词云 解决"大家在聊什么",情感分析解决"大家怎么看"。两个工具组合,就是一套低成本的舆情预警系统。
本文用一个完整案例,跑通从数据获取到可视化输出的全链路。
二、案例背景
假设你负责一款新上线的 App,应用商店里有 5000+ 条评论。老板问了三个问题:
| 序号 | 问题 | 对应工具 |
|---|---|---|
| 1 | 用户最常提到哪些功能? | 词云 |
| 2 | 整体好评率是多少? | 情感分析 |
| 3 | 差评集中在哪些点? | 情感 + 词云筛选 |
下面一步步拆解。
三、技术选型(Python)
| 环节 | 工具 | 理由 |
|---|---|---|
| 爬虫 | requests + parsel |
轻量、够用 |
| 情感分析 | snownlp |
中文 NLP 入门首选,开箱即用 |
| 分词 | jieba |
中文分词事实标准 |
| 词云 | wordcloud |
成熟、可定制 |
| 可视化 | matplotlib |
基础绘图够用 |
安装命令:
bash
1pip install requests parsel snownlp jieba wordcloud matplotlib
2
四、完整代码实战
Step 1:爬取评论数据
以某应用商店评论页为例(仅作演示,实际使用需遵守平台规则):
scss
python
1import requests
2from parsel import Selector
3import csv
4import time
5
6def crawl_comments(url, pages=5):
7 comments = []
8 for page in range(1, pages + 1):
9 resp = requests.get(url.format(page=page), headers={
10 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
11 })
12 sel = Selector(resp.text)
13 items = sel.css('.comment-item')
14 for item in items:
15 comments.append({
16 'user': item.css('.user-name::text').get(),
17 'content': item.css('.comment-text::text').get().strip(),
18 'score': item.css('.score::text').get(),
19 'time': item.css('.time::text').get()
20 })
21 time.sleep(1.5) # 礼貌爬取
22 return comments
23
24data = crawl_comments('https://example.com/comments?page={page}', pages=3)
25
26# 保存为 CSV
27with open('comments.csv', 'w', newline='', encoding='utf-8') as f:
28 writer = csv.DictWriter(f, fieldnames=['user', 'content', 'score', 'time'])
29 writer.writeheader()
30 writer.writerows(data)
31
32print(f'共爬取 {len(data)} 条评论')
33
关键提醒 :爬取前务必查看目标网站的
robots.txt和服务协议,合规是底线。
Step 2:情感分析打分
python
python
1from snownlp import SnowNLP
2
3def get_sentiment(text):
4 s = SnowNLP(text)
5 return s.sentiments # 返回 0~1,越接近 1 越正面
6
7for item in data:
8 item['sentiment'] = get_sentiment(item['content'])
9
10# 简单分类
11for item in data:
12 if item['sentiment'] >= 0.6:
13 item['label'] = '正面'
14 elif item['sentiment'] >= 0.4:
15 item['label'] = '中性'
16 else:
17 item['label'] = '负面'
18
19# 统计
20positive = sum(1 for d in data if d['label'] == '正面')
21negative = sum(1 for d in data if d['label'] == '负面')
22neutral = sum(1 for d in data if d['label'] == '中性')
23
24print(f'正面: {positive} | 中性: {neutral} | 负面: {negative}')
25print(f'好评率: {positive / len(data) * 100:.1f}%')
26
输出示例:
makefile
1正面: 1823 | 中性: 987 | 负面: 1190
2好评率: 45.6%
3
Step 3:生成词云
ini
python
1import jieba
2from wordcloud import WordCloud
3import matplotlib.pyplot as plt
4
5# 拼接所有评论文本
6all_text = ' '.join([d['content'] for d in data])
7
8# 分词
9words = jieba.cut(all_text)
10filtered_words = ' '.join([w for w in words if len(w) > 1])
11
12# 词云生成
13wc = WordCloud(
14 font_path='simhei.ttf', # Windows 黑体,Mac 用 'Arial Unicode MS'
15 width=1200,
16 height=800,
17 background_color='white',
18 max_words=200,
19 stopwords={'的', '了', '是', '在', '我', '有', '和', '就', '不', '人'}
20)
21wc.generate(filtered_words)
22
23# 展示
24plt.figure(figsize=(12, 8))
25plt.imshow(wc, interpolation='bilinear')
26plt.axis('off')
27plt.title('评论词云', fontsize=16)
28plt.tight_layout()
29plt.savefig('wordcloud.png', dpi=150)
30plt.show()
31
Step 4:情感词云(核心亮点)
光看全部词云不够,把正面和负面评论分开做词云,差异一目了然:
ini
python
1# 正面词云
2pos_text = ' '.join([d['content'] for d in data if d['label'] == '正面'])
3pos_words = ' '.join([w for w in jieba.cut(pos_text) if len(w) > 1])
4wc_pos = WordCloud(font_path='simhei.ttf', width=800, height=600,
5 background_color='white', stopwords={'的', '了', '是'}).generate(pos_words)
6
7# 负面词云
8neg_text = ' '.join([d['content'] for d in data if d['label'] == '负面'])
9neg_words = ' '.join([w for w in jieba.cut(neg_text) if len(w) > 1])
10wc_neg = WordCloud(font_path='simhei.ttf', width=800, height=600,
11 background_color='white', stopwords={'的', '了', '是'}).generate(neg_words)
12
13# 并排展示
14fig, axes = plt.subplots(1, 2, figsize=(16, 8))
15axes[0].imshow(wc_pos, interpolation='bilinear')
16axes[0].set_title('正面评论词云', fontsize=14)
17axes[0].axis('off')
18axes[1].imshow(wc_neg, interpolation='bilinear')
19axes[1].set_title('负面评论词云', fontsize=14)
20axes[1].axis('off')
21plt.tight_layout()
22plt.savefig('sentiment_wordcloud.png', dpi=150)
23plt.show()
24
结果解读示例:
| 正面词云高频词 | 负面词云高频词 |
|---|---|
| 流畅、好用、推荐、升级 | 卡顿、闪退、卸载、垃圾 |
一张图就能看出:产品体验本身没问题,稳定性是最大痛点。
Step 5:情感趋势图(加分项)
按时间维度看情感变化,判断舆情走向:
ini
python
1from collections import defaultdict
2
3# 按日期聚合(假设 time 格式为 '2026-06-10')
4daily_sentiment = defaultdict(list)
5for d in data:
6 date = d['time'][:10] # 截取日期部分
7 daily_sentiment[date].append(d['sentiment'])
8
9# 计算每日平均情感值
10dates = sorted(daily_sentiment.keys())
11avg_scores = [sum(daily_sentiment[d]) / len(daily_sentiment[d]) for d in dates]
12
13plt.figure(figsize=(12, 5))
14plt.plot(dates, avg_scores, marker='o', color='#2b7a78')
15plt.axhline(y=0.5, color='red', linestyle='--', alpha=0.5, label='中性线')
16plt.title('每日评论情感趋势', fontsize=14)
17plt.ylabel('情感得分')
18plt.legend()
19plt.xticks(rotation=45)
20plt.tight_layout()
21plt.savefig('sentiment_trend.png', dpi=150)
22plt.show()
23
五、输出一张舆情看板长什么样
把以上结果拼成一页报告:
css
1┌─────────────────────────────────────────────────┐
2│ 📊 舆情速报 | 某App 评论分析 | 2026-06-17 │
3├──────────────┬──────────────┬───────────────────┤
4│ 好评率 45.6% │ 评论总数 3000 │ 负面占比 39.7% │
5├──────────────┴──────────────┴───────────────────┤
6│ [正面词云] │ [负面词云] │
7│ 流畅 好用 推荐 │ 卡顿 闪退 卸载 │
8├─────────────────────────────────────────────────┤
9│ 📈 情感趋势:近7日从 0.42 上升至 0.51,有所好转 │
10│ 🎯 核心结论:稳定性问题是当前最大舆情风险点 │
11└─────────────────────────────────────────────────┘
12
六、常见坑与避坑指南
| 坑 | 解决方案 |
|---|---|
| SnowNLP 对网络用语识别差 | 手动补充领域词典,或换用 paddlenlp 的情感模型 |
| 词云全是"的""了"等停用词 | 加大 stopwords 列表,或用 jieba.analyse.extract_tags 提关键词 |
| 爬虫被封 IP | 加 time.sleep(),用代理池,设置随机 User-Agent |
| 情感阈值 0.6/0.4 太绝对 | 结合业务场景调参,或用人工标注数据微调 |
七、进阶方向
如果你想把这个项目从"能跑"升级到"能用":
- 换更强的模型 :
paddlenlp的 SKEP 情感模型,准确率比 SnowNLP 高 10~15 个百分点 - 做 LDA 主题模型:词云只能看到高频词,LDA 能发现隐藏话题簇(如"登录问题""支付问题")
- 接入自动化 pipeline :用
schedule定时爬取 + 分析,每周自动生成舆情周报 - 做成 Dashboard :用
streamlit搭一个可交互的网页看板,老板自己就能查
写在最后
词云给你"一眼看全",情感分析给你"一眼看透"。这两个工具组合,成本不到 100 行代码,但能回答 80% 的舆情判断问题。
真正值钱的不是代码,是你看到词云后那句话------ "卡顿和闪退是当前最大的舆情风险,建议优先排查。"
这才是数据分析该有的终点。