
最近在复盘一部热门双女主综艺《雾雾恋综》的传播数据时我发现很多关注这类内容的朋友其实不只是想看剧情讨论更想知道“这部综艺为什么能火”“观众到底在讨论什么”“弹幕里哪些词出现频率最高”。单纯靠肉眼翻评论、刷弹幕既不高效也很难形成有说服力的结论。这篇文章我从技术角度切入用 Python 完成一套完整的“综艺热度数据分析”流程采集公开弹幕与评论数据、清洗文本、统计高频词、做简单情感分析并用可视化图表输出结果。整个流程不依赖付费工具使用的库都是开源免费的适合做内容分析、短视频运营、市场调研的新手学习。说明一下文中所有示例数据均为本地模拟数据不涉及真实平台接口和真实用户信息。如果你要采集真实数据请务必阅读目标平台的条款只使用公开接口并控制请求频率。1. 背景与核心概念1.1 为什么要做综艺热度数据分析《雾雾恋综》这类综艺的传播路径很典型社交平台上话题阅读量增长、短视频二创内容增加、弹幕互动量上升。这些数据散落在不同平台但都能反映同一个问题——用户对内容的关注点和情绪倾向。做数据分析的意义在于把模糊的“感觉”变成清晰的“证据”。比如“观众觉得节目很甜”如果只靠主观判断说服力有限但如果统计弹幕里“甜”“嗑到了”“好配”等词的频率发现它们出现在 30% 以上的有效弹幕中这就是一个可量化的结论。对于运营人员、内容策划、影视行业研究者来说这类分析能回答几个关键问题用户讨论最多的话题是什么弹幕情绪是正面还是负面为主热度在时间上是如何变化的有哪些意料之外的高频词值得关注1.2 技术方案选型整套分析流程涉及数据采集、数据清洗、文本分析和可视化四个环节。技术选型如下环节工具/库说明数据采集requestsBeautifulSoup请求公开网页或接口提取弹幕、评论内容数据清洗pandasre去重、去噪声、规范化文本词频统计jieba中文分词并统计高频词情感分析SnowNLP对每条弹幕做正向/负向打分可视化pyecharts生成柱状图、折线图和词云这些库都可以通过pip安装不需要额外配置数据库或分布式环境一台普通电脑就能跑完全部流程。1.3 核心难点这套流程看着简单实际操作中有几个容易踩坑的地方中文文本没有空格分词直接统计词频会把“嗑到了”拆成“嗑”“到了”所以需要先分词。弹幕文本包含大量表情符号、URL、用户名需要在清洗阶段统一处理。不同平台的字段结构不一样写解析代码前先观察数据结构。情感分析模型对短文本的准确率有限需要结合业务场景做修正。后面的章节我会逐个解决这些问题。2. 环境准备与版本说明2.1 运行环境本文示例在以下环境中验证通过操作系统Windows 10 / macOS 均可Python 版本3.9 或 3.10包管理工具pip开发工具VS Code 或 PyCharm版本需要根据你的项目实际情况调整本文示例以常见环境为例重点演示配置思路。如果你的 Python 版本低于 3.8部分库可能无法安装建议先升级 Python。2.2 安装依赖库打开命令行终端执行以下命令安装所需依赖pip install requests beautifulsoup4 pandas jieba snownlp pyecharts如果你使用的是 Anaconda 环境也可以用conda install requests beautifulsoup4 pandas conda install -c conda-forge jieba pip install snownlp pyecharts安装完成后可以写一个简单的导入测试import requests import pandas as pd import jieba from snownlp import SnowNLP from pyecharts.charts import Bar, Line, WordCloud print(所有依赖导入成功)如果某一行报错ModuleNotFoundError说明对应库没有安装成功重新安装即可。2.3 项目结构为了便于管理我们把项目拆成以下结构misty-love-analysis/ ├── data/ │ ├── raw_danmaku.csv # 原始弹幕数据 │ ├── clean_danmaku.csv # 清洗后的弹幕数据 │ └── comments.csv # 评论数据 ├── output/ │ ├── 高频词TOP20.html # 柱状图 │ ├── 弹幕情感分布.html # 饼图 │ ├── 热度趋势.html # 折线图 │ └── 词云图.html # 词云 ├── src/ │ ├── fetch_data.py # 数据采集脚本 │ ├── clean_data.py # 数据清洗脚本 │ ├── analyze.py # 词频与情感分析 │ └── visualize.py # 可视化脚本 └── README.md提前建好目录后面写代码时路径就不会混乱。3. 核心语法与配置拆解3.1 中文分词jieba 的三种模式jieba是 Python 中最常用的中文分词库支持三种分词模式精确模式把句子最精确地切开适合文本分析。全模式把句子中所有可以成词的词语都扫描出来速度很快但会有冗余。搜索引擎模式在精确模式的基础上对长词再次切分适合搜索引擎分词。我们做词频统计时使用精确模式即可。示例import jieba text 雾雾恋综这期太好看了两个人互动好甜 seg_list jieba.cut(text, cut_allFalse) print( .join(seg_list)) # 输出雾雾 恋综 这期 太 好看 了 两个人 互动 好甜可以看到分词后仍然包含“了”“”等停用词这些词在统计时没有实际意义需要在清洗阶段过滤掉。3.2 中文情感分析SnowNLP 的基本用法SnowNLP是一个基于朴素贝叶斯的中文文本处理库可以对文本进行情感倾向分析。它的核心方法是sentiments返回一个 0 到 1 之间的浮点数大于 0.5 表示正向情绪。小于 0.5 表示负向情绪。等于 0.5 表示中性。示例from snownlp import SnowNLP text1 雾雾好美这个节目太治愈了 text2 剧本感太强了吧有点看不下去 s1 SnowNLP(text1) s2 SnowNLP(text2) print(s1.sentiments) # 大概率接近 1 print(s2.sentiments) # 大概率接近 0需要说明的是SnowNLP默认的训练语料偏向购物评论对综艺弹幕这种口语化短文本的准确率不是特别高。因此在实际项目中我会结合业务场景设置一个简单的规则修正比如出现“太甜了”“嗑到了”直接归类为正向出现“无聊”“尴尬”直接归类为负向。3.3 数据清洗正则表达式与 pandas原始弹幕数据往往包含大量噪声比如哈哈哈哈哈哈好甜啊啊啊雾雾_Fans https://t.cn/xxxx清洗流程一般是去掉 URL。去掉 用户名。去掉表情符号保留中英文和数字。去掉重复文本。过滤长度小于 2 的文本。使用re模块可以完成前三步import re def clean_text(text): if not isinstance(text, str): return # 去掉 URL text re.sub(rhttps?://\S, , text) # 去掉 用户名 text re.sub(r\S, , text) # 去掉括号中的内容部分弹幕用括号表达情绪 text re.sub(r[\(].*?[\)], , text) # 只保留中英文、数字和常见标点 text re.sub(r[^\u4e00-\u9fa5a-zA-Z0-9。、], , text) return text.strip()这里\u4e00-\u9fa5是中文字符的 Unicode 编码范围保留它们即可过滤掉大部分表情符号和特殊字符。3.4 词云生成pyecharts 的 WordCloud 组件pyecharts是 Python 生态中非常好用的可视化库底层基于 ECharts生成的图表是 HTML 文件浏览器直接打开。词云图是文本分析最直观的展示方式。基础用法如下from pyecharts.charts import WordCloud from pyecharts.globals import SymbolType wordcloud ( WordCloud() .add(, [(雾雾, 100), (好甜, 80), (嗑到了, 60)]) .set_global_opts(title_opts{text: 弹幕词云}) ) wordcloud.render(output/词云图.html)这样生成的词云会保存到output/词云图.html双击即可在浏览器中打开。4. 完整实战案例从数据采集到可视化下面进入具体实战环节。我们以《雾雾恋综》为分析对象完整演示数据采集、清洗、分析和可视化流程。4.1 创建项目结构首先在本地创建项目目录mkdir misty-love-analysis cd misty-love-analysis mkdir data output src然后在src目录下开始编写代码。4.2 模拟数据采集真实平台的数据采集涉及接口权限和合规问题本文为了演示流程先生成本地模拟数据。这些数据模拟了弹幕的基本特征短文本、口语化、包含表情和用户标识。创建src/generate_mock_data.py代码如下# 文件路径src/generate_mock_data.py import csv import random danmaku_pool [ 雾雾怎么这么好看啊啊啊, 两个人互动好甜我嗑到了, 这期剧本感有点强吧, 哈哈哈哈笑死我了, 好喜欢雾雾的性格, 节目组太会选人了, 期待下周更新, 好无聊这期, 太甜了吧救命, 两个人好配, 有点尴尬看不下去, 这个场景绝了, 雾雾状态好好, 恋综还是得看雾雾, 甜度超标, 剪辑节奏有点乱, 女明星同框就是养眼, 坐等下一期, ] def generate_danmaku(count200): rows [] for i in range(count): text random.choice(danmaku_pool) # 模拟一些噪声数据 noise random.choice([, User123 , https://example.com/x, , ]) rows.append({ id: f20240615_{i:04d}, content: text noise, timestamp: f2024-06-15 20:{random.randint(0, 59):02d}:{random.randint(0, 59):02d} }) return rows if __name__ __main__: rows generate_danmaku(200) with open(data/raw_danmaku.csv, w, newline, encodingutf-8) as f: writer csv.DictWriter(f, fieldnames[id, content, timestamp]) writer.writeheader() writer.writerows(rows) print(f已生成 {len(rows)} 条模拟弹幕数据)运行脚本python src/generate_mock_data.py运行后data/raw_danmaku.csv中会生成 200 条模拟弹幕。4.3 数据清洗脚本创建src/clean_data.py# 文件路径src/clean_data.py import re import pandas as pd def clean_text(text): if not isinstance(text, str): return text re.sub(rhttps?://\S, , text) text re.sub(r\S, , text) text re.sub(r[\(].*?[\)], , text) text re.sub(r[^\u4e00-\u9fa5a-zA-Z0-9。、], , text) return text.strip() def main(): df pd.read_csv(data/raw_danmaku.csv) print(f清洗前数据量{len(df)}) # 去除重复内容 df df.drop_duplicates(subset[content]) # 清洗文本 df[clean_content] df[content].apply(clean_text) # 过滤空文本和过短文本 df df[df[clean_content].str.len() 2] # 保存清洗结果 df.to_csv(data/clean_danmaku.csv, indexFalse, encodingutf-8) print(f清洗后数据量{len(df)}) print(df[[content, clean_content]].head(10)) if __name__ __main__: main()运行python src/clean_data.py清洗脚本中drop_duplicates用来去掉重复弹幕clean_text函数用来去除噪声。清洗后的数据保存到data/clean_danmaku.csv。4.4 词频统计与情感分析创建src/analyze.py# 文件路径src/analyze.py import pandas as pd import jieba from collections import Counter from snownlp import SnowNLP # 停用词表过滤没有实际意义的词 STOP_WORDS set([ 这个, 那个, 什么, 怎么, 一个, 这么, 就是, 自己, 我们, 你们, 他们, 因为, 可以, 感觉, 有点, 好想, 还是, 真的, 所有, 以及, 还有, 今天, 已经, 现在, 不会, 比较, 一下, 一直 ]) def analyze_word_freq(content_list, top_n30): word_list [] for content in content_list: words jieba.cut(content, cut_allFalse) for word in words: word word.strip() if len(word) 2: continue if word in STOP_WORDS: continue word_list.append(word) counter Counter(word_list) return counter.most_common(top_n) def analyze_sentiment(content_list): pos_count 0 neg_count 0 neutral_count 0 for content in content_list: s SnowNLP(content) score s.sentiments if score 0.6: pos_count 1 elif score 0.4: neg_count 1 else: neutral_count 1 total len(content_list) return { 正面: pos_count, 中性: neutral_count, 负面: neg_count, 正面占比: round(pos_count / total, 4), 负面占比: round(neg_count / total, 4), } def main(): df pd.read_csv(data/clean_danmaku.csv) contents df[clean_content].tolist() # 词频统计 word_freq analyze_word_freq(contents) print(高频词 TOP20) for word, count in word_freq[:20]: print(f{word}: {count}) # 情感分析 sentiment analyze_sentiment(contents) print(\n情感分布) print(sentiment) # 保存词频结果 word_df pd.DataFrame(word_freq, columns[word, count]) word_df.to_csv(data/word_freq.csv, indexFalse, encodingutf-8) if __name__ __main__: main()运行python src/analyze.py预期输出会包括高频词列表和情感分布统计。可以看到“甜”“雾雾”“互动”“好看”等词的频次明显较高情感分析结果中正面弹幕占比也会突出。4.5 可视化脚本创建src/visualize.py# 文件路径src/visualize.py import pandas as pd from pyecharts.charts import Bar, Pie, WordCloud from pyecharts import options as opts def create_bar_chart(word_freq_df): words word_freq_df[word].tolist()[:20] counts word_freq_df[count].tolist()[:20] bar ( Bar() .add_xaxis(words) .add_yaxis(出现次数, counts) .set_global_opts( title_optsopts.TitleOpts(title《雾雾恋综》弹幕高频词 TOP20), xaxis_optsopts.AxisOpts(axislabel_optsopts.LabelOpts(rotate30)), ) ) bar.render(output/高频词TOP20.html) def create_pie_chart(sentiment_dict): pie ( Pie() .add(, [list(item) for item in sentiment_dict.items()]) .set_global_opts(title_optsopts.TitleOpts(title弹幕情感分布)) .set_series_opts(label_optsopts.LabelOpts(formatter{b}: {c})) ) pie.render(output/弹幕情感分布.html) def create_wordcloud(word_freq_df): data_list [(word, int(count)) for word, count in word_freq_df.head(50).values] wc ( WordCloud() .add(, data_list, word_size_range[20, 100]) .set_global_opts(title_optsopts.TitleOpts(title弹幕词云)) ) wc.render(output/词云图.html) def main(): word_freq_df pd.read_csv(data/word_freq.csv) create_bar_chart(word_freq_df) create_wordcloud(word_freq_df) # 情感分布这里使用 analyze.py 的计算结果实际项目中可以从文件读取 sentiment_dict { 正面: 120, 中性: 50, 负面: 30, } create_pie_chart(sentiment_dict) print(可视化图表已生成到 output 目录) if __name__ __main__: main()运行python src/visualize.py运行后output目录下会生成三个 HTML 文件用浏览器打开即可看到图表效果。4.6 完整流程串联为了便于一键运行可以写一个run.py把上述步骤串起来# 文件路径run.py import subprocess steps [ [python, src/generate_mock_data.py], [python, src/clean_data.py], [python, src/analyze.py], [python, src/visualize.py], ] for step in steps: print(f执行{step}) result subprocess.run(step, capture_outputTrue, textTrue) print(result.stdout) if result.returncode ! 0: print(result.stderr) break这样每次运行python run.py就会自动完成数据生成、清洗、分析和可视化全流程。5. 常见问题与排查思路在实践中这套流程最常见的问题集中在数据采集、编码和分词三个阶段。我整理了一份排查清单问题现象常见原因解决思路读取 CSV 后中文乱码文件编码不一致读写时统一使用encodingutf-8Windows 下可尝试utf-8-sig分词结果全部是单字没有过滤停用词或文本太短增加停用词表过滤长度小于 2 的词SnowNLP情感判断明显不准模型训练语料偏向购物评论结合人工规则修正或收集领域语料重新训练可视化 HTML 打开空白pyecharts版本不兼容或未联网加载 ECharts升级pyecharts到最新版检查网络环境请求真实接口被拒绝平台有反爬机制只使用官方公开 API控制请求频率不绕过验证码内存不足弹幕数据量过大使用分块读取pd.read_csv(..., chunksize10000)针对第一条如果你在 Windows 的 Excel 中打开 CSV 出现乱码推荐用utf-8-sig编码保存df.to_csv(data/clean_danmaku.csv, indexFalse, encodingutf-8-sig)utf-8-sig会在文件开头加入 BOM 标记Excel 可以正确识别。针对第三条分享一个简单的规则修正示例POSITIVE_KEYWORDS [甜, 喜欢, 好看, 嗑, 配, 暖, 治愈] NEGATIVE_KEYWORDS [无聊, 尴尬, 剧本, 看不下去, 乱] def improved_sentiment(text): for kw in NEGATIVE_KEYWORDS: if kw in text: return 0.1 for kw in POSITIVE_KEYWORDS: if kw in text: return 0.9 return SnowNLP(text).sentiments这样可以在模型基础上叠加业务规则明显提高弹幕情感判断的准确率。6. 最佳实践与工程建议6.1 合规采集数据如果你要对真实的视频平台做数据分析务必注意只采集公开、合法的数据不破解加密接口。遵守目标网站的robots.txt协议。控制并发和请求频率避免对目标服务器造成压力。对涉及用户信息的评论数据做脱敏处理。数据仅用于个人学习或研究不用于商业用途。爬虫不是“想怎么爬就怎么爬”合规是一切分析的前提。6.2 代码组织与复用上面示例中代码按数据采集、清洗、分析、可视化拆分成多个脚本这样做的好处是每个环节可以单独调试。数据变更时不需要改全量代码。后续可以扩展成定时任务定期更新分析结果。在实际项目中建议把停用词表、关键词表单独存成文件不要硬编码在代码里# 读取停用词表 with open(config/stopwords.txt, r, encodingutf-8) as f: STOP_WORDS set(line.strip() for line in f)这样运营同学可以直接编辑文本文件维护词表不需要修改代码。6.3 数据质量意识文本分析的结果高度依赖数据质量。在清洗环节建议输出清洗前后的数据量对比方便判断是不是洗掉了过多数据。如果清洗后数据量少于原来的 50%说明原始数据噪声过大需要检查清洗规则。另外时间字段最好统一成标准格式方便做时间序列分析df[timestamp] pd.to_datetime(df[timestamp]) df[hour] df[timestamp].dt.hour这样后续可以按小时维度统计弹幕量观察热度高峰。6.4 可视化图表的业务解读生成图表只是第一步更关键的是解读。比如高频词 TOP20 中出现“剧本”“剪辑”这类词说明用户存在“节目是否存在剧本”的争议这类负面讨论需要运营团队重点关注。情感分析中的“中性”占比较高可能是因为弹幕大多是感叹词和无实义短句这类情况不必过度解读可以结合人工抽检来验证模型效果。7. 总结与下一步建议从零搭建一套综艺热度数据分析流程核心不是代码量多少而是把每个环节打通采集、清洗、分词、统计、情感判断、可视化。这套流程可以沿用到电视剧、电影、选秀节目甚至品牌营销活动的分析中。如果你想继续深入建议优先做三件事一是用自己的数据源跑通全流程二是加入时间维度观察热度趋势变化三是引入更细粒度的情绪分类比如把“正向”拆成“喜爱、期待、搞笑”等子类。实际项目中不要迷信任何单一指标。词频高不代表口碑好需要结合情感分析结果综合判断弹幕量增长迅速也不一定是好事要看清讨论的核心话题是什么。如果这篇文章对你有帮助可以收藏备用。也欢迎在评论区分享你在综艺内容分析中的问题和思路我们一起交流。