尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

用Python分析泡泡玛特热搜评论:从爬虫到可视化大屏

用Python分析泡泡玛特热搜评论:从爬虫到可视化大屏 今天要聊的这个 Python 数据分析项目不是又一个“爬豆瓣电影”的换皮教程。它选的是一个非常有话题性的对象泡泡玛特。热搜评论里的语气五花八门——有人喊“端盒真香”有人吐槽“潜伏款又没抽中”还有人认真分析 IP 的商业逻辑。这些短文本天然带着情绪和态度正好是练习爬虫采集、中文分词、情感分析和数据可视化的绝佳素材。很多人学 Python 数据分析时有一个共同的困惑书本上的案例太干净了df.head()一敲数据整整齐齐根本没有真实项目的“脏乱差”。但实际工作里你遇到的数据大部分都需要自己采集、清洗、去重、分词才能进入分析环节。这篇文章就用“泡泡玛特热搜评论”作为完整案例从数据获取到可视化大屏把整条链路走一遍。文章的核心判断是这个项目真正锻炼的不是某一个 Python 库的用法而是“数据获取 → 数据清洗 → 文本挖掘 → 可视化呈现”的完整工程能力。这正是简历项目和毕业设计最需要展示的能力——你知道一个问题从原始数据到最终结论中间要经过哪些环节并且在每个环节都能落地。全文会给出可运行的 Python 代码、关键模块讲解、常见坑点以及如何把它包装成一个有价值的项目经历。1. 为什么选“泡泡玛特热搜评论”做数据分析项目先回答一个实际问题市面上 Python 项目案例那么多为什么选泡泡玛特第一个理由是数据门槛低获取路径公开。泡泡玛特作为热门消费品牌它的热搜评论在公开平台上能看到大量样本。评论属于用户公开表达的内容不需要任何账号权限就能读取——这一点对初学者非常重要。你可以把精力放在数据处理和分析上而不是纠结怎么绕过多层登录验证。如果你对爬虫的数据来源有顾虑这里强调一个原则本文只演示公开数据的采集与分析不涉及任何绕过访问控制、批量抓取个人隐私或违反平台规则的行为。爬虫代码仅用于学习建议控制请求频率优先优先优先确认目标平台的服务条款。第二个理由是数据的“分析价值密度”高。泡泡玛特的评论不是千篇一律的“好评/差评”它包含多个维度IP 热度维度哪些 IPMolly、SKULLPANDA、DIMOO 等被讨论最多情感维度用户是正向种草、中性吐槽还是负向脱粉消费行为维度端盒、抽盒、二手交易、改娃等关键词时间趋势维度新品发布、事件发酵前后的评论量变化。这意味着你可以做的不只是画两张饼图而是围绕一个完整的业务问题输出分析结论。这远比“爬 1000 条微博然后生成词云”更有含金量。第三个理由是技术栈覆盖全面。一个完整的热搜评论分析项目至少要用到环节核心技术产出数据采集requests、BeautifulSoup、正则原始评论 DataFrame数据清洗pandas、re、json干净的结构化文本中文分词jieba分词结果与词频统计情感分析SnowNLP 或简单规则策略情感分布与维度对比可视化matplotlib、pyecharts、wordcloud图表与数据大屏工程化模块化函数、异常处理、日志可扩展的完整项目所以无论你是准备毕业设计还是想在简历里增加一个有说服力的 Python 项目这个案例都能很好地展示你的数据工程意识和分析思维。2. 项目技术选型与环境准备建议使用 Python 3.8 及以上版本。本文代码基于 Python 3 语法不依赖某个特定小版本如果你本地是 3.9 或 3.10 都可以直接运行。推荐使用虚拟环境隔离项目依赖避免不同项目之间的包冲突。以venv为例mkdir popmart-analysis cd popmart-analysis python3 -m venv venv source venv/bin/activate # Windows 上执行 venv\Scripts\activate接下来安装依赖库。本项目需要的第三方库如下pip install requests beautifulsoup4 pandas jieba wordcloud matplotlib pyecharts各库的作用requests发送 HTTP 请求获取网页或接口数据beautifulsoup4解析 HTML 结构提取目标内容pandas处理表格数据做去重、过滤、聚合jieba中文分词这是中文文本分析最常用的工具wordcloud生成词云图matplotlib基础图表绘制pyecharts生成交互式可视化图表适合做数据大屏。如果你不需要搭建大屏只想快速看结果pyecharts可以换成seaborn但本文后续会演示pyecharts的写法因为它更适合做简历展示。安装完成后可以顺手验证一下环境import requests import pandas as pd import jieba print(requests:, requests.__version__) print(pandas:, pd.__version__) print(jieba:, jieba.__version__)如果你在运行wordcloud时遇到“中文乱码”问题通常是因为缺少中文字体文件这个问题会在后面的“常见问题”部分专门说明。3. 数据获取评论爬虫的底层逻辑与实现3.1 爬虫的类型与本文定位在动手之前先明确一个概念爬虫按抓取策略一般分为批量型、增量型和垂直型。批量型爬虫一次性把目标数据全部采集下来适合做离线分析增量型爬虫定期检测新增数据并更新存储适合做持续监控垂直型爬虫只针对特定网站、特定主题做定向抓取比如只抓“泡泡玛特”相关评论。本文定位是垂直型 批量型一次采集足够多的公开评论然后做离线分析。这样最符合“数据分析案例”的定位也不需要维护复杂的调度系统。3.2 数据源分析从材料来看我们要分析的是“泡泡玛特热搜评论”。这里的“热搜评论”可以理解为某公开平台热搜话题下的用户评论内容。为了保持教程的通用性我们以公开网页或公开接口为例。一个核心经验是不要一上来就对着 HTML 硬写正则。先打开浏览器的“开发者工具” → Network 面板看看数据是通过 HTML 直接渲染还是通过 JSON 接口异步加载。大多数现代网站采用异步接口直接解析 JSON 比解析 HTML 更稳定。3.3 最小可运行的爬虫代码下面给出一段核心爬虫代码模拟从公开评论接口拉取数据的过程。真实场景下你需要根据目标平台调整 URL 和参数但整体结构是一致的# 文件路径spider/comment_spider.py import requests import json import time import pandas as pd def fetch_comments(page: int, page_size: int 20) - list: 获取指定页码的公开评论数据。 注意这里的 URL 仅为演示结构请替换为目标平台合法的公开接口。 url https://api.example.com/popmart/comments params { keyword: 泡泡玛特, page: page, page_size: page_size, sort: hot } headers { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 } try: resp requests.get(url, paramsparams, headersheaders, timeout10) resp.raise_for_status() data resp.json() # 假设接口返回结构为 {comments: [{content: ..., time: ..., likes: 10}, ...]} return data.get(comments, []) except requests.exceptions.RequestException as e: print(f[错误] 第 {page} 页请求失败: {e}) return [] def collect_comments(max_pages: int 50) - pd.DataFrame: all_comments [] for page in range(1, max_pages 1): comments fetch_comments(page) if not comments: print(f第 {page} 页没有数据停止抓取。) break for item in comments: all_comments.append({ content: item.get(content, ).strip(), create_time: item.get(time, ), likes: item.get(likes, 0) }) print(f已完成第 {page} 页累计 {len(all_comments)} 条。) time.sleep(0.5) # 控制频率避免给对方服务器造成压力 return pd.DataFrame(all_comments) if __name__ __main__: df collect_comments(max_pages3) print(df.head()) df.to_csv(data/raw_comments.csv, indexFalse, encodingutf-8)这段代码有三个关键设计异常处理try...except捕获网络异常避免单页失败导致整个程序退出时间间隔time.sleep(0.5)控制请求频率这是最基本的“礼貌爬虫”做法结构化存储把抓到的数据转成 DataFrame并保存为 CSV方便后续分析。这里要特别提醒任何爬虫都要尊重目标网站的 robots 协议和服务条款。如果你发现页面返回“安全验证”或“访问频繁”不要尝试绕过而是应该降低频率或改用官方开放接口。这篇文章讲的是一种通用的数据获取思路而不是教你怎么突破反爬机制。3.4 数据字段设计抓取下来的原始字段可能比较杂。建议至少保留以下几个核心字段字段说明示例content评论文本“端盒终于抽到隐藏款了”create_time发布时间2024-05-20 12:00:00likes点赞数128region发布地区可选北京user_type用户类型可选普通用户、KOC有了这几个字段你就可以做“评论数量趋势”、“高赞评论内容”、“地区分布”等分析。字段越多后续可视化维度越丰富。4. 数据清洗从原始评论到干净文本4.1 为什么清洗是数据分析最花时间的环节很多初学者抓完数据就想直接画图这一步是最大的误区。真实数据往往存在重复评论同一句话被多次转发或复制空内容只有表情包或图片没有文字噪声文本URL、用户、HTML 标签、无关数字短文本只有一个“哈”字对分析没有意义。判断一个数据分析师是否专业就看他是否愿意在清洗阶段下功夫。清洗不是“做苦力”而是在理解业务后做有目的的筛选。4.2 清洗代码示例# 文件路径data_clean/clean_comments.py import pandas as pd import re def load_raw_data(path: str data/raw_comments.csv) - pd.DataFrame: df pd.read_csv(path, encodingutf-8) print(f原始数据行数: {len(df)}) return df def clean_comment_text(text: str) - str: 清洗单条评论文本。 主要工作去 HTML 标签、去 URL、去 用户、去多余空白。 if not isinstance(text, str): return # 去 HTML 标签 text re.sub(r[^], , text) # 去 URL text re.sub(rhttp[s]?://\S, , text) # 去 用户 text re.sub(r\S, , text) # 去空白字符 text text.strip() return text def clean_dataframe(df: pd.DataFrame) - pd.DataFrame: df df.copy() # 1. 剔除空值 df df.dropna(subset[content]) # 2. 清洗评论文本 df[content_clean] df[content].apply(clean_comment_text) # 3. 去重基于清洗后的文本 df df.drop_duplicates(subset[content_clean]) # 4. 剔除清洗后仍为空的文本 df df[df[content_clean] ! ] # 5. 剔除过短文本少于 2 个字符 df df[df[content_clean].str.len() 2] return df if __name__ __main__: raw_df load_raw_data() clean_df clean_dataframe(raw_df) print(f清洗后数据行数: {len(clean_df)}) clean_df.to_csv(data/clean_comments.csv, indexFalse, encodingutf-8)为什么去重要基于content_clean而不是原始content因为两条评论可能原始文本中一条带空格、一条不带实际内容相同。清洗后再去重才能更准。过短文本剔除也值得解释单字评论如“好”“赞”“强”在词频统计中没有任何区分度反而会稀释关键词的权重。保留 2 字符以上是经验值你可以根据实际数据分布调整。4.3 清洗结果检查清洗完成后建议用describe()和sample()做一次人工检查clean_df pd.read_csv(data/clean_comments.csv) print(clean_df[content_clean].str.len().describe()) print(clean_df[content_clean].sample(10).tolist())这一步虽然简单但很重要。它保证你进入分词和可视化阶段时数据是“干净到可以信任”的。5. 中文分词与词频统计5.1 jieba 分词的基本用法中文文本不像英文那样天然以空格分词所以必须借助分词工具。jieba是目前最常用的 Python 中文分词库支持精确模式、全模式和搜索引擎模式。数据分析场景下默认使用精确模式即可。import jieba text 泡泡玛特的 SKULLPANDA 端盒手感很好 words jieba.lcut(text) print(words) # 输出大致为[泡泡, 玛特, 的, , SKULLPANDA, , 端, 盒, 手感, 很, 好]你会注意到默认分词结果里有“的”“很”“好”这类停用词后面需要过滤同时“泡泡玛特”被切成“泡泡/玛特”不符合业务表达。解决方法是添加自定义词典。5.2 添加自定义词典在项目目录下新建data/userdict.txt写入品牌词和行业词泡泡玛特 10 n 端盒 5 n 抽盒 5 n 隐藏款 5 n SKULLPANDA 10 n Molly 10 n DIMOO 10 n 改娃 5 v然后在分词前加载jieba.load_userdict(data/userdict.txt)这一步的效果非常明显。“泡泡玛特”会作为一个整体出现而不是被拆开“隐藏款”也会保留完整含义。5.3 停用词过滤加载停用词表后基本的分词流程如下# 文件路径analyze/word_freq.py import jieba import pandas as pd from collections import Counter STOP_WORDS set() with open(data/stopwords.txt, r, encodingutf-8) as f: for line in f: word line.strip() if word: STOP_WORDS.add(word) def tokenize(text: str) - list: words jieba.lcut(text) # 过滤停用词、单字词、纯数字、纯空白 result [] for w in words: w w.strip() if w and w not in STOP_WORDS and len(w) 1 and not w.isdigit(): result.append(w) return result def get_word_frequency(df: pd.DataFrame) - pd.DataFrame: word_list [] for text in df[content_clean].tolist(): word_list.extend(tokenize(text)) counter Counter(word_list) freq_df pd.DataFrame(counter.most_common(100), columns[word, count]) return freq_df if __name__ __main__: clean_df pd.read_csv(data/clean_comments.csv) freq_df get_word_frequency(clean_df) print(freq_df.head(20)) freq_df.to_csv(output/word_freq.csv, indexFalse, encodingutf-8)sentence可以通过一个简单的正则按标点符号切分import re sentences re.split(r[。!?;,\n], text)6.3 可视化pyecharts 大屏如果你的目标是简历展示pyecharts生成的交互式 HTML 大屏远比静态 matplotlib 图有视觉冲击力。它基于 ECharts天然适合做数据分析可视化项目。# 文件路径visual/analysis_chart.py from pyecharts.charts import Bar, Pie, Line, Grid from pyecharts import options as opts import pandas as pd def create_bar_chart(freq_df: pd.DataFrame) - Bar: top20 freq_df.head(20) bar ( Bar() .add_xaxis(top20[word].tolist()) .add_yaxis(词频, top20[count].tolist()) .set_global_opts( title_optsopts.TitleOpts(title泡泡玛特热搜评论 Top20 关键词), xaxis_optsopts.AxisOpts(axislabel_optsopts.LabelOpts(rotate45)) ) ) return bar def create_pie_chart(sentiment_df: pd.DataFrame) - Pie: pie ( Pie() .add( series_name情感倾向, data_pairlist(zip(sentiment_df[label], sentiment_df[count])), radius[35%, 70%], ) .set_global_opts( title_optsopts.TitleOpts(title评论情感倾向占比), legend_optsopts.LegendOpts(orientvertical, pos_top15%, pos_left80%) ) ) return pie if __name__ __main__: freq_df pd.read_csv(output/word_freq.csv) sentiment_df pd.read_csv(output/sentiment_distribution.csv) bar_chart create_bar_chart(freq_df) pie_chart create_pie_chart(sentiment_df) bar_chart.render(output/top20_keywords.html) pie_chart.render(output/sentiment_pie.html) print(图表已生成到 output/ 目录使用浏览器打开 HTML 文件即可查看。)把Bar和Pie组合到一个Grid就是最简单的大屏雏形。实际项目里你还可以加上地图、折线图、表格形成完整的业务看板。7. 完整项目结构与运行验证7.1 代码工程化一个优秀的项目不应该把所有代码堆在一个文件里。推荐的项目结构如下popmart-analysis/ ├── spider/ │ └── comment_spider.py ├── data_clean/ │ └── clean_comments.py ├── analyze/ │ ├── word_freq.py │ └── sentiment_analysis.py ├── visual/ │ └── analysis_chart.py ├── data/ │ ├── userdict.txt │ ├── stopwords.txt │ ├── raw_comments.csv │ └── clean_comments.csv ├── output/ │ ├── word_freq.csv │ ├── sentiment_distribution.csv │ └── *.html └── README.md这种分层的模块化设计有明显的好处每一层可以独立调试后续新增爬虫来源只需改spider/目录后续新增可视化图表只需在visual/目录添加文件让面试官一眼看出你有工程化意识。7.2 运行验证顺序按下面的顺序执行每跑完一步都确认输出是否符合预期# 第 1 步采集数据 python spider/comment_spider.py # 第 2 步清洗数据 python data_clean/clean_comments.py # 第 3 步分词与词频统计 python analyze/word_freq.py # 第 4 步情感分析 python analyze/sentiment_analysis.py # 第 5 步生成可视化图标pyecharts python visual/analysis_chart.py每一步的预期输出步骤预期输出判断标准爬虫data/raw_comments.csv有数据行数非空清洗data/clean_comments.csv行数少于原始数据文本干净分词output/word_freq.csv词频合理的 Top20 关键词情感分析output/sentiment_distribution.csv正负中性比例分布正常可视化output/*.html浏览器打开可见图表如果某一步与预期不符先检查该步骤的输入文件名和字段名是否一致再检查依赖库是否完整。8. 常见问题与排查方法实际运行这个项目时你大概率会遇到下面这些问题。这里给出一个排查清单问题现象可能原因排查方式解决方案请求返回 403 或安全验证页面请求频率过高或无合法 User-Agent打印响应状态码和响应头降低频率设置合理 User-Agent确认符合平台规则CSV 用 Excel 打开中文乱码写入编码使用了utf-8但 Excel 默认 GBK用记事本或 VS Code 打开验证写入时改用encodingutf-8-sigwordcloud 生成词云中文变方块缺少中文字体检查 matplotlib 字体列表指定中文字体路径如msyh.ttcjieba 分词结果不理想未加载自定义词典打印分词结果样例添加userdict.txt并在代码中加载pyecharts 图表没有中文标题页面编码或主题异常检查 HTML 的 meta 标签更新 pyecharts 到最新版本爬虫运行到一半中断网络波动或某页数据结构异常查看异常堆栈的位置增加重试机制和单页容错SnowNLP 情感判断不准确默认模型偏向电商语料随机抽查 50 条人工标注改用简单规则策略或训练专属模型其中有一个问题值得展开“爬虫返回百度安全验证”。这个词出现频率很高很多初学者一遇到验证页面就慌了。这里要明确态度验证页面的存在说明目标网站有反爬机制。正确做法是停下来检查自己是否请求过频繁或者寻找官方公开接口。安全验证是网站的正常防护措施绕过它并不是一个安全、合规的行为。对学习项目来说控制请求频率、降低同时并发数、选择公开接口才是可持续的方案。另外stopwords.txt可以在网上找常用的中文停用词表也可以根据自己的数据积累。一般建议至少包含这些词的 了 是 我 你 他 她 它 也 都 就 而 及 与 着 或 一个 没有 我们 你们 他们9. 最佳实践与简历项目打造建议9.1 代码层面的最佳实践所有请求必须设置超时requests.get(timeout10)防止程序卡死所有可能失败的 IO 操作要有 try...except尤其是网络请求和文件读写不要硬编码路径用os.path拼接或使用pathlib中间结果及时落盘保存 CSV 或 JSON避免程序中断后还要重新爬日志代替 print 洪流推荐使用logging输出不同级别的信息控制随机请求间隔比如time.sleep(random.uniform(0.5, 1.5))让采集行为更自然也体现专业意识。9.2 不只是画图让你的项目有分析深度很多简历上的 Python 项目写到“用 matplotlib 画了词云”就结束了。如果想加分你需要多走两步第一步多维度交叉分析。例如情感倾向 × 时间趋势看看品牌正面声量是否随时间变化高赞评论 × 关键词找出最能引起共鸣的内容主题。这能体现业务分析能力。第二步输出结论而不是只输出图。比如通过数据发现“端盒”和“抽盒”的讨论热度远高于“改娃”意味着用户的消费决策集中在“购买方式”相关话题进一步可以把“隐藏款”“雷款”“中奖概率”等词的高频出现作为洞察点。在图表的下面写一段不超过 200 字的解读说明“从数据中看到了什么这对业务意味着什么”。这背后的方法论是数据分析的最终交付物不是图表而是决策建议。哪怕只是“建议运营在推新品时重点强调抽盒体验”也比单纯一张饼图有用得多。9.3 如何把项目写进简历简历上的项目描述建议采用以下格式泡泡玛特热搜评论数据分析Python 爬虫 数据清洗 可视化基于 Python3 开发垂直型爬虫采集公开平台“泡泡玛特”话题下评论数据 3000 条包含文本、时间、点赞数等字段利用 pandas 完成数据清洗与去重结合 jieba 自定义词典完成中文分词和停用词过滤统计高频关键词基于 SnowNLP 完成评论情感分析输出正负向情绪占比使用 pyecharts 制作 Top20 关键词和情感分布的可视化大屏。注意三个要点量化数据3000 条、技术栈清晰Python3、pandas、jieba、pyecharts、输出结果可视化大屏。不要只写“熟悉 Python”要写“用 Python 完成了什么”。10. 总结与后续学习方向这篇教程完整走了一遍“Python3 爬虫 数据分析 可视化”的泡泡玛特热搜评论分析项目。核心收获有三点第一学会了从公开网页或接口中批量获取评论数据并用 pandas 完成结构化存储 第二掌握了对中文评论做清洗、去重和 jieba 分词的标准流程 第三能够用 pyecharts 和 wordcloud 做出能展示在简历上的可视化成果。如果你想继续深入有几个明确的方向可以选补充增量型爬虫模块每天定时抓取新增评论用 SQLite 或 MySQL 做持久化分析评论量的时间趋势训练更精准的情感模型基于人工标注数据微调一个分类器替代默认的 SnowNLP做多品牌对比分析把泡泡玛特和同类潮玩品牌放在一起对比分析品牌讨论热度差异部署成 Web 服务用 Flask 或 FastAPI 包装你的分析结果做一个简单的关键词趋势查询接口。项目源码建议按“爬虫采集 → 数据清洗 → 分词分析 → 可视化”四个模块保存每个模块配一个 README 说明。这样无论是自己复盘还是面试官查看都能快速理解你的完整思路。代码跑通只是第一步能解释清楚每一步“为什么这么做”才是这个项目真正的价值所在。
返回列表