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

资讯详情

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

Python爬虫与数据分析实战:泡泡玛特热搜评论可视化项目

Python爬虫与数据分析实战:泡泡玛特热搜评论可视化项目 最近不少正在准备毕设和简历项目的同学来问我能不能提供一个既练到爬虫、又练到数据分析和可视化的完整案例数据还得有点话题性分析出来也容易讲出亮点。于是我把之前做的一个数据分析小项目整理成了教程——以“泡泡玛特”相关热搜评论为例抓取公开讨论区的评论数据做成词云、情感分布、评论趋势图等可视化结果。整个项目用 Python3 完成涉及requests、pandas、jieba、wordcloud、pyecharts等常用库代码量不大但把爬虫、数据清洗、分析和可视化这条链路完整走了一遍。如果你是刚学完 Python 基础、想找一个能写进简历的实战案例这个项目非常合适。本文会从项目设计讲起逐步拆解爬虫、清洗、可视化的核心代码最后给出常见报错的排查方式和工程化建议。你可以直接复制源码来跑也可以修改数据源做成其它热点话题的分析项目。1. 项目背景与核心概念1.1 这个项目解决什么问题很多同学学习 Python 时语法都会但一提到“做项目”就不知道从哪下手。根本原因是缺少一个能串联多个知识点的完整任务。这个泡泡玛特热搜评论分析项目本质上是一条完整的数据流水线网页/接口数据 → 爬虫采集 → 数据清洗 → 分词统计 → 可视化展示 → 结论分析通过这个项目你可以同时掌握用requests请求公开数据接口或网页。用pandas完成数据加载、去重、过滤。用jieba做中文分词和关键词统计。用pyecharts、wordcloud生成可视化图表。把一个“热点话题”转化成能写进简历的数据分析项目。1.2 为什么选择泡泡玛特作为案例泡泡玛特是潮玩领域的代表性品牌“盲盒”“隐藏款”“端盒”“雷款”等词汇在评论中频繁出现天然适合做文本分析。评论数据通常包含用户昵称、评论内容、点赞数、发布时间等字段信息量足够分析维度也丰富。在技术层面这类评论数据的结构比较规整抓取后很容易转成表格适合作为数据分析的练手数据。另外“热搜评论”是动态更新的内容分析结果能反映一定时间段内的用户情绪和关注点这也是数据可视化项目常见的切入点。1.3 爬虫与数据分析的关系爬虫Web Crawler在这里的作用是“获取数据”数据分析Data Analysis的作用是“从数据中提取价值”。两者经常出现在同一个项目中但侧重点不同爬虫关注请求方法、请求头、页面解析、数据提取、异常重试。数据分析关注数据清洗、字段构建、统计口径、可视化表达。在本文项目里爬虫负责把公开评论保存为 CSV 文件数据分析负责读取 CSV 并进行加工、输出图表。这两部分代码会拆成独立模块方便你后续替换成其它数据源。2. 环境准备与版本说明2.1 运行环境本文示例代码在 Windows 11 Python 3.10 环境下调试通过macOS 和 Linux 同样适用。Python 版本建议使用 3.8 及以上因为部分数据分析库的新版本对旧版 Python 已不再支持。你可以使用 PyCharm 或 VS Code两者都行。命令行工具按自己习惯选择本文统一使用终端执行 Python 脚本。2.2 依赖库安装项目需要以下 Python 库库名用途requests发送 HTTP 请求获取页面或接口数据pandas数据加载、清洗、聚合统计jieba中文分词统计高频词wordcloud生成词云图pyecharts生成交互式图表matplotlib备用绘图配合词云使用安装命令如下pip install requests pandas jieba wordcloud pyecharts matplotlib如果你使用的是国内网络可以加上清华镜像源安装速度会明显更快pip install -i https://pypi.tuna.tsinghua.edu.cn/simple requests pandas jieba wordcloud pyecharts matplotlib2.3 版本兼容提醒pyecharts从 v1.0 开始 API 变化较大本文代码基于pyecharts 2.x编写。如果你之前安装的是 0.5.x 老版本请先升级pip install --upgrade pyecharts如果执行代码时发现from pyecharts.charts import Bar报错基本就是版本过旧导致的。3. 项目整体设计3.1 功能模块划分整个项目按功能拆成 4 个文件职责清晰也便于修改popmart_analysis/ ├── spider.py # 爬虫模块采集评论数据 ├── clean.py # 数据清洗模块去重、去空、文本过滤 ├── analysis.py # 分析与可视化模块分词、统计、绘图 ├── requirements.txt # 项目依赖清单 ├── comments.csv # 爬虫保存的原始数据 └── output/ # 存放可视化图表3.2 数据字段设计评论数据统一保存为 CSV字段设计如下字段名说明nickname用户昵称content评论内容like_count点赞数create_time发布时间source来源标识source字段用于标注数据来源方便以后合并多平台数据时做区分。3.3 流程图1. 爬虫模块 公开接口/页面 - requests请求 - 解析数据 - 保存comments.csv 2. 清洗模块 comments.csv - pandas读取 - 去重去空 - 文本过滤 - clean_comments.csv 3. 分析模块 clean_comments.csv - 时间统计/分词统计 - pyecharts图表 - output目录4. 爬虫模块实战抓取热搜评论数据4.1 合法性与合规说明在做爬虫项目之前先强调三点原则只抓取公开可访问的数据不碰登录后才能查看的私密内容。遵守目标网站的robots.txt协议控制请求频率。数据仅用于个人学习和项目演示不用于商业用途不批量传播。在合法授权和公开数据范围内编写爬虫是技术学习者必须养成的习惯。本文示例以公开接口为主重点讲解请求、解析、保存的通用思路。4.2 基本请求示例下面用requests请求一个公开接口并模拟浏览器请求头避免被服务器直接拒绝# 文件路径spider.py import requests import pandas as pd def fetch_comments(url): 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, Referer: https://example.com/ } resp requests.get(url, headersheaders, timeout10) resp.raise_for_status() # 非200状态直接抛异常 # 如果接口返回的是JSON可以直接解析 data resp.json() return data.get(comments, [])这里需要注意timeout10防止请求长时间卡住。resp.raise_for_status()在请求失败时快速报错方便定位问题。请求头里的Referer需要根据实际目标网站调整。4.3 解析与保存从接口拿到评论列表后我们需要把每条评论转换成字典再转成 DataFrame 保存为 CSVdef save_to_csv(comment_list, file_pathcomments.csv): rows [] for item in comment_list: row { nickname: item.get(user, {}).get(nickname, ), content: item.get(content, ), like_count: item.get(like_count, 0), create_time: item.get(created_at, ), source: demo } rows.append(row) df pd.DataFrame(rows) df.to_csv(file_path, indexFalse, encodingutf-8-sig) print(f已保存 {len(df)} 条评论到 {file_path})使用encodingutf-8-sig是为了防止 Excel 打开 CSV 时出现中文乱码。4.4 翻页与限速真实的热搜评论通常不止一页。假设接口通过cursor参数翻页可以使用循环抓取def fetch_all_comments(base_url, max_pages5): all_comments [] cursor 0 for page in range(max_pages): url f{base_url}?cursor{cursor} print(f正在抓取第 {page 1} 页...) comments fetch_comments(url) if not comments: break all_comments.extend(comments) cursor comments[-1].get(cursor, 0) # 控制请求频率不要给服务器造成压力 time.sleep(1.5) return all_comments这里的time.sleep(1.5)一定要加尤其是连续请求时避免被目标网站封锁 IP。如果是教学项目抓取几百条到几千条公开评论足够用了不要贪多。5. 数据清洗与预处理爬虫抓下来的数据往往含有噪声比如重复评论、空内容、链接、用户、表情符号等。直接对这些文本做词频统计结果会被噪声干扰。因此要先经过数据清洗。5.1 读取数据并查看基本情况# 文件路径clean.py import pandas as pd df pd.read_csv(comments.csv, encodingutf-8-sig) print(df.shape) print(df.head()) print(df.info())df.info()能快速看到每一列是否有缺失值这决定了清洗策略。5.2 去重与去空评论数据里经常出现同一条内容被多次抓取或者用户提交了空白评论。处理方式如下# 删除完全重复的行 df df.drop_duplicates(subset[content]) # 删除评论内容为空的行 df df.dropna(subset[content]) # 去掉纯空白字符的评论 df df[df[content].str.strip() ! ] # 重置索引避免后续操作出现索引错位 df df.reset_index(dropTrue) print(f清洗后剩余 {len(df)} 条评论)5.3 文本噪声过滤中文评论中常见的噪声包括网页链接、邮箱、用户、纯表情符号、多余空格。可以用正则表达式过滤import re def clean_text(text): if not isinstance(text, str): return # 去掉网页链接 text re.sub(rhttp\S|www\.\S, , text) # 去掉用户 text re.sub(r\S, , text) # 去掉邮箱 text re.sub(r\S\S\.\S, , text) # 去掉非中文、非字母、非数字的字符保留中英文和数字 text re.sub(r[^\u4e00-\u9fa5a-zA-Z0-9], , text) return text df[clean_content] df[content].apply(clean_text) # 清洗后可能产生新的空文本再次过滤 df df[df[clean_content] ! ] df df.reset_index(dropTrue)这里的核心逻辑是“保留中英文和数字其余符号全部去掉”。如果你的分析任务需要保留表情符号可以调整正则表达式但通常在做情感分析时表情符号也可以单独作为一个分析维度这里为了方便先统一过滤。5.4 保存清洗结果df.to_csv(clean_comments.csv, indexFalse, encodingutf-8-sig) print(清洗完成结果已保存到 clean_comments.csv)清洗后后续所有分析都基于clean_comments.csv避免重复执行正则过滤。6. 数据分析与可视化6.1 评论数量趋势分析先把create_time字段转成标准时间类型再按天统计评论数量观察话题热度随时间的变化# 文件路径analysis.py import pandas as pd from pyecharts.charts import Bar from pyecharts import options as opts df pd.read_csv(clean_comments.csv, encodingutf-8-sig) df[create_time] pd.to_datetime(df[create_time], errorscoerce) df df.dropna(subset[create_time]) # 按天统计评论数量 df[date] df[create_time].dt.date daily_count df.groupby(date).size().reset_index(namecount) print(daily_count)接着绘制柱状图bar ( Bar() .add_xaxis(daily_count[date].astype(str).tolist()) .add_yaxis(评论数量, daily_count[count].tolist()) .set_global_opts( title_optsopts.TitleOpts(title泡泡玛特热搜评论数量日趋势), xaxis_optsopts.AxisOpts(name日期), yaxis_optsopts.AxisOpts(name评论数), ) ) bar.render(output/daily_trend.html)pyecharts生成的是 HTML 文件浏览器打开即可看到交互式图表方便放大、鼠标悬停查看数值。6.2 高频词统计与词云先使用jieba对评论内容做分词去掉停用词再统计词频import jieba # 停用词表可按需扩展 stop_words set([ 的, 了, 是, 我, 你, 他, 她, 它, 我们, 你们, 他们, 这个, 那个, 一个, 就, 都, 也, 很, 又, 还, 在, 有, 不, 没, 把, 被, 让, 给, 和, 与, 及, 或, 等, 吗, 呢, 吧, 啊, 哦 ]) def cut_words(text): words jieba.lcut(text) return [word for word in words if word not in stop_words and len(word) 1] df[words] df[clean_content].apply(cut_words) # 统计词频 all_words [] for words in df[words]: all_words.extend(words) word_series pd.Series(all_words).value_counts() top20 word_series.head(20) print(top20)如果想可视化高频词可以把前 20 的词频结果保存为条形图bar_words ( Bar() .add_xaxis(top20.index.tolist()) .add_yaxis(出现次数, top20.values.tolist()) .set_global_opts( title_optsopts.TitleOpts(title泡泡玛特热搜评论高频词Top20), xaxis_optsopts.AxisOpts(name关键词, axislabel_optsopts.LabelOpts(rotate30)), yaxis_optsopts.AxisOpts(name词频), ) ) bar_words.render(output/top20_words.html)词云图使用wordcloud库生成需要指定中文字体否则中文会变成方框from wordcloud import WordCloud import matplotlib.pyplot as plt word_freq_dict word_series.to_dict() wc WordCloud( font_pathsimhei.ttf, # Windows 自带黑体Mac 可换成 /System/Library/Fonts/PingFang.ttc width800, height600, background_colorwhite, max_words100 ).generate_from_frequencies(word_freq_dict) plt.figure(figsize(12, 8)) plt.imshow(wc, interpolationbilinear) plt.axis(off) plt.savefig(output/wordcloud.png, dpi300, bbox_inchestight) plt.show()词云图比较依赖字体文件的路径。Windows 常用simhei.ttfmacOS 使用苹方字体路径。如果你的环境里没有对应字体可以到系统字体目录找到具体名字替换。6.3 情感倾向初探情感分析是一个比较大的方向。在入门项目中我们可以先做一个简单的“情感词打分”不引入复杂的模型。实现思路是准备一份正面词和负面词列表统计每条评论里正面词和负面词出现的次数计算情感分。positive_words set([ 好看, 喜欢, 可爱, 划算, 值得, 开心, 漂亮, 惊喜, 强烈推荐, 完美, 高级, 满意 ]) negative_words set([ 难看, 失望, 后悔, 差评, 亏了, 生气, 垃圾, 退款, 太重, 瑕疵, 退货, 无语 ]) def sentiment_score(words): pos sum(1 for w in words if w in positive_words) neg sum(1 for w in words if w in negative_words) if pos neg: return 正面 elif neg pos: return 负面 return 中性 df[sentiment] df[words].apply(sentiment_score) sentiment_count df[sentiment].value_counts() print(sentiment_count)这种基于词典的方法优点是简单可控缺点是词典需要自己根据业务场景扩充。对于课程设计和简历项目来说思路比精度更重要完全可以用。如果你希望情感分析更准确可以尝试SnowNLP库安装后直接调用SnowNLP(text).sentiments即可得到 0 到 1 之间的情感得分。为了控制本文篇幅这里只提供思路不展开大段代码。6.4 点赞数与评论长度的关系这个分析维度可以反映什么样的评论更容易获得高赞。比如是长篇深度评论还是短小精悍的吐槽df[content_length] df[clean_content].str.len() # 按长度段分组 bins [0, 10, 20, 30, 50, 100] labels [0-10, 10-20, 20-30, 30-50, 50-100] df[length_group] pd.cut(df[content_length], binsbins, labelslabels) length_like df.groupby(length_group, observedFalse)[like_count].mean() print(length_like)这里用pd.cut把评论长度分成几个区间再计算每个区间的平均点赞数。你可能会发现中等长度的评论平均点赞更高这一结论可以作为项目分析的亮点之一。7. 完整源码运行说明7.1 requirements.txtrequests2.31.0 pandas2.0.3 jieba0.42.1 wordcloud1.9.3 pyecharts2.0.5 matplotlib3.7.2版本号可以根据本机环境调整如果你已经安装了更新版本只要接口兼容可以不用严格锁定。7.2 按顺序执行# 1. 抓取评论数据 python spider.py # 2. 清洗数据 python clean.py # 3. 生成可视化图表 python analysis.py运行完成后output目录下会生成daily_trend.html评论数量日趋势柱状图。top20_words.html高频词条形图。wordcloud.png词云图。你可以把这些图表整合进课程设计报告或答辩 PPT再配合几段数据结论就是一份完整的 Python 数据分析项目展示。8. 常见问题与排查思路问题现象常见原因解决思路爬虫请求返回 403缺少模拟浏览器请求头或请求频率过高添加User-Agent、Referer等请求头适当增加time.sleep间隔抓取不到数据接口参数变了或页面结构变化打开浏览器开发者工具重新确认请求地址和返回结构CSV 中中文乱码保存时用了utf-8Excel 默认按 GBK 打开保存时使用encodingutf-8-sig词云图中文显示为方框没有指定中文字体使用font_pathsimhei.ttf或换成系统中文字体路径from pyecharts.charts import Bar报错pyecharts 版本过旧升级到 2.x 版本pip install --upgrade pyechartsjieba分词结果不理想缺少自定义词典或停用词表不够全添加自定义词表jieba.add_word(泡泡玛特)扩充停用词表如果遇到requests.exceptions.SSLError通常是因为目标站点证书校验问题。可以在开发调试阶段使用verifyFalse并在代码中忽略InsecureRequestWarning。但请注意这只建议在本地学习环境使用生产环境必须保持证书校验开启。9. 工程化与个人练习建议9.1 代码分层拒绝大杂烩很多初学者喜欢把所有功能写进一个.py文件这样确实省事但不好维护。本文把爬虫、清洗、分析拆成三个文件每个文件职责单一方便你分别调试。后续如果想换数据源只需要改spider.py清洗和分析代码几乎不用动。9.2 使用日志代替 print项目变大后print输出会非常混乱。建议在爬虫类脚本中使用logging模块import logging logging.basicConfig( levellogging.INFO, format%(asctime)s - %(levelname)s - %(message)s, encodingutf-8 ) logging.info(开始抓取第1页数据)这样既能控制日志等级又能把日志输出到文件方便排查问题。9.3 尽量不硬编码爬虫里的 URL、请求头、停用词表都可以放到配置文件或单独的参数区域。比如在文件顶部集中定义常量BASE_URL https://example.com/api/comment HEADERS { User-Agent: ... } MAX_PAGES 5 REQUEST_INTERVAL 1.5这样以后改参数时不需要翻遍全文。9.4 做好请求异常重试网络请求并不总是稳定。一个简单的重试机制就能降低爬虫失败概率for attempt in range(3): try: resp requests.get(url, headersheaders, timeout10) resp.raise_for_status() break except requests.RequestException as e: logging.warning(f请求失败第 {attempt 1} 次重试{e}) time.sleep(2)9.5 可视化文件统一输出把生成的图片和 HTML 文件统一放到output目录既方便整理也方便在写课程设计报告时引用。文件名建议带上时间或内容标识例如wordcloud_20250101.png避免多次运行后相互覆盖。9.6 关于简历和面试的准备如果你打算把这个项目写进简历不要只写“用 Python 爬取了评论数据并做了可视化”。更建议提炼成使用requests实现公开评论数据的多页采集包含请求重试与频率控制。基于pandas完成数据清洗与字段处理清洗后数据量可用比例超过 90%。利用jieba分词与pyecharts、wordcloud生成高频词、情感分布、时间趋势图。面试时如果被问“这个项目有什么难点”建议回答以下方向爬虫被反爬时怎么处理。中文分词和停用词表如何构建。情感分析采用词典方案的原因和局限。如果数据量扩大到百万级当前管道哪些环节需要优化。10. 扩展方向与学习建议把泡泡玛特热搜评论分析跑通之后你已经具备了一个标准的 “Python 爬虫 数据分析 可视化” 项目能力。接下来可以根据自己的兴趣和时间选一个方向深入。如果想加强数据分析深度可以引入 LDA 主题模型从评论中自动提取几个主题比如“抽盒体验”“产品设计”“吐槽与售后”这样分析结论会更有层次感。如果想往 NLP 方向发展可以在情感分析部分换用 SnowNLP、BERT 等模型对比不同方法在评论情感分类上的效果差异。这个对比本身就是很好的毕设素材。如果想加强工程能力可以把整个流程封装成一个定时任务每天自动抓取评论、更新图表再结合 Flask 或者 Streamlit 做成一个简易的数据看板。这样项目的应用价值就更高了不再是“一次性脚本”。最后提醒一句爬虫项目一定要把“合法合规”放在第一位。只采集公开数据控制请求频率数据仅供学习研究不用于商业用途。技术本身是中性的把数据用对地方才是这个项目真正值得写进简历的地方。
返回列表