ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

基于Flask+ECharts的Python数据分析实战:泡泡玛特热搜评论可视化项目

基于Flask+ECharts的Python数据分析实战:泡泡玛特热搜评论可视化项目 最近看到一个很适合做毕设、写进简历的 Python 实战项目基于 Flask ECharts 的泡泡玛特热搜评论数据分析。整个项目不复杂但链路很完整覆盖了数据采集、数据清洗、后端接口、前端可视化还自带接口化和批量处理的思路。对于想拿 Python 做数据分析方向作品、又不想只停留在“读 CSV 画图”这种 demo 层的同学来说这个案例比纯教程更接近真实工作流。先给结论这个项目可以在普通笔记本上跑不需要 GPU不用装 CUDA数据量控制在几万条以内时 Flask 开发服务器就能撑住。技术栈是 Python3 Flask ECharts前端通过 ECharts 展示柱状图、饼图、趋势图和词云后端用 Flask 提供 JSON 接口数据分析部分用 pandas 清洗聚合爬虫部分只负责把公开数据落到本地存储。本文会带你从环境准备、项目结构、数据准备到 Flask 接口开发、ECharts 页面渲染、批量处理思路全部走一遍并给出可直接运行的示例代码。无论你是准备毕业设计、想找数据分析实战经验还是想在简历里加一个有完整前后端链路的 Python 项目这个案例都值得仔细过一遍。建议先收藏再按文章顺序动手。1. 核心能力速览能力项说明项目类型Python3 数据分析 Flask Web 应用 ECharts 可视化核心功能热搜评论数据采集、清洗、关键词统计、情感分布、趋势分析、可视化展示后端框架Flask前端可视化ECharts数据分析pandas 清洗聚合jieba 分词提取关键词数据存储JSON / CSV / SQLite 均可示例项目使用本地 JSON启动方式python app.py命令启动硬件要求普通笔记本即可无需 GPU适合本地演示接口能力提供/api/overview、/api/trend、/api/sentiment、/api/keywords等 JSON 接口批量任务可扩展目录扫描批量处理也可接入队列服务适合场景毕业设计、简历项目、Python 数据分析学习、可视化入门从材料看这个项目的重点不是算法多深而是把“数据获取 → 数据清洗 → 数据存储 → 后端接口 → 前端可视化”完整串起来。对初学者来说最难的不是某个环节而是整个链路的打通恰好这个案例把链路补全了。2. 适用场景与使用边界这项目最适合三类人第一类是准备毕业设计的学生。Flask ECharts 的组合足够展示 Web 开发能力数据分析部分又能体现数据处理思维再加一个数据采集模块整个项目的功能和工程量都很完整。第二类是写简历的求职者。大多数数据分析岗位都要求“会用 Python 做数据清洗能独立完成可视化”这个项目正好是这些要求的落地体现。面试时可以从数据怎么来、怎么清洗、为什么选 Flask、ECharts 如何与 Flask 联动这几个角度展开。第三类是 Python 数据分析初学者。如果只跟着教程画 pyplot 图很难理解真实项目里的数据流转。这个案例把数据交给 Flask 接口再让 ECharts 去拉接口页面上的图表是动态渲染的这和平时写死的 matplotlib 图完全不同。使用边界也要说清楚。数据采集环节必须遵守目标平台的 Robots 协议和服务条款只采集公开页面数据不抓取用户隐私不绕过登录权限不进行高频请求造成平台压力。示例代码使用的是本地模拟数据如果要应用到真实业务请先确认数据授权。3. 环境准备与项目结构3.1 基础环境建议使用 Python 3.9 或更高版本。本机没有 Python3 的话先去官网下载对应安装包安装时勾选“Add Python to PATH”。创建虚拟环境并安装依赖mkdir popmart-analysis cd popmart-analysis python3 -m venv venv source venv/bin/activate # Windows 使用 venv\Scripts\activate新建requirements.txtflask3.0.3 pandas2.2.2 jieba0.42.1 requests2.32.3安装依赖pip install -r requirements.txt3.2 推荐项目结构popmart-analysis/ ├── app.py ├── requirements.txt ├── data/ │ └── hot_comments.json ├── analysis/ │ └── analyze.py ├── templates/ │ └── index.html ├── static/ │ └── echarts.min.js └── outputs/目录说明app.pyFlask 主程序负责页面渲染和接口路由。data/存放原始数据文件本示例使用hot_comments.json。analysis/数据分析模块负责数据加载、分词、聚合。templates/Jinja2 模板目录index.html是可视化页面。static/静态资源目录ECharts 的 JS 文件放在这里。outputs/批量处理结果输出目录未处理时不生成。4. 数据准备热搜评论示例数据为了不依赖真实平台接口也方便你直接跑通项目示例项目使用一份本地 JSON 数据。数据包含字段评论内容、情感标签、点赞数、发布时间、所属话题。我在data/hot_comments.json里构造一批模拟数据[ { id: 1, text: 这个隐藏款真的太好看了手感也一级棒, sentiment: positive, like_count: 328, created_at: 2026-01-04 21:15:00, topic: 泡泡玛特新盲盒 }, { id: 2, text: 排队两小时结果想要的款早就没了, sentiment: negative, like_count: 189, created_at: 2026-01-04 19:40:00, topic: 线下门店 }, { id: 3, text: 这个系列设计一般没有上一代惊艳, sentiment: neutral, like_count: 76, created_at: 2026-01-03 22:05:00, topic: 泡泡玛特新盲盒 } ]实际项目中这份数据可以由爬虫定时写入。但要注意不要把“抓取真实用户评论”作为默认代码直接用于生产环境。更稳妥的做法是先用公开数据集或自己构造的脱敏数据跑通流程确认代码正确后再在符合平台规则的前提下采集小批量数据测试。如果你有配套源码包数据文件可能更完整字段也可能不同以配套数据为准。关键点是“数据文件的字段要和后端代码的读取逻辑保持一致”。5. Flask 后端接口开发5.1 主程序 app.py创建app.pyimport json from flask import Flask, render_template, jsonify from analysis.analyze import load_data, get_overview, get_trend, get_sentiment, get_keywords app Flask(__name__) DATA_PATH data/hot_comments.json app.route(/) def index(): return render_template(index.html) app.route(/api/overview) def api_overview(): df load_data(DATA_PATH) result get_overview(df) return jsonify(result) app.route(/api/trend) def api_trend(): df load_data(DATA_PATH) result get_trend(df) return jsonify(result) app.route(/api/sentiment) def api_sentiment(): df load_data(DATA_PATH) result get_sentiment(df) return jsonify(result) app.route(/api/keywords) def api_keywords(): df load_data(DATA_PATH) result get_keywords(df) return jsonify(result) if __name__ __main__: app.run(host127.0.0.1, port5000, debugTrue)说明load_data负责读取 JSON 并返回 DataFrame。每个接口只做一件事职责清晰。debugTrue适合本地开发正式部署要关闭。5.2 数据分析模块 analysis/analyze.py创建analysis/analyze.pyimport json import pandas as pd import jieba from collections import Counter def load_data(path): with open(path, r, encodingutf-8) as f: data json.load(f) df pd.DataFrame(data) df[created_at] pd.to_datetime(df[created_at]) return df def get_overview(df): return { total_comments: len(df), total_likes: int(df[like_count].sum()), avg_likes: round(float(df[like_count].mean()), 2), top_topic: df[topic].value_counts().idxmax(), } def get_trend(df): trend df.set_index(created_at).resample(D)[id].count() return { dates: [d.strftime(%Y-%m-%d) for d in trend.index], counts: trend.tolist(), } def get_sentiment(df): sent df[sentiment].value_counts().to_dict() return { positive: sent.get(positive, 0), neutral: sent.get(neutral, 0), negative: sent.get(negative, 0), } def get_keywords(df, top_n10): word_list [] for text in df[text]: words jieba.lcut(text) word_list.extend([w for w in words if len(w) 1]) counter Counter(word_list) top_words counter.most_common(top_n) return { keywords: [w for w, _ in top_words], counts: [c for _, c in top_words], }这段代码把数据分析和 Web 层分离了后期想换数据库、想加新的统计指标不需要改动接口路由。5.3 启动后端服务在项目根目录运行python app.py看到类似输出* Running on http://127.0.0.1:5000浏览器访问http://127.0.0.1:5000/api/overview如果返回 JSON 数据说明后端已经跑通。接口路径可以先通过浏览器验证再接前端页面。6. ECharts 可视化页面6.1 准备 ECharts把echarts.min.js文件放到static/目录。如果本机没下载可以从 ECharts 官方发布页获取合适的版本也可以先接 CDN 联调最终部署时再替换成离线文件。6.2 前端模板创建templates/index.html!DOCTYPE html html langzh-CN head meta charsetUTF-8 title泡泡玛特热搜评论数据分析/title script srchttps://cdn.jsdelivr.net/npm/echarts5/dist/echarts.min.js/script style .container { width: 1200px; margin: 30px auto; } .chart { width: 100%; height: 400px; margin-bottom: 30px; border: 1px solid #eee; border-radius: 8px; } /style /head body div classcontainer h2泡泡玛特热搜评论数据分析/h2 div idtrendChart classchart/div div idsentimentChart classchart/div div idkeywordChart classchart/div /div script function fetchData(url) { return fetch(url).then(res res.json()); } async function initCharts() { const trendData await fetchData(/api/trend); const sentimentData await fetchData(/api/sentiment); const keywordData await fetchData(/api/keywords); const trendChart echarts.init(document.getElementById(trendChart)); trendChart.setOption({ title: { text: 评论数量趋势 }, tooltip: {}, xAxis: { type: category, data: trendData.dates }, yAxis: { type: value }, series: [{ type: line, data: trendData.counts, smooth: true }] }); const sentimentChart echarts.init(document.getElementById(sentimentChart)); sentimentChart.setOption({ title: { text: 情感分布 }, tooltip: {}, series: [{ type: pie, radius: 60%, data: [ { name: 正面, value: sentimentData.positive }, { name: 中性, value: sentimentData.neutral }, { name: 负面, value: sentimentData.negative } ] }] }); const keywordChart echarts.init(document.getElementById(keywordChart)); keywordChart.setOption({ title: { text: 关键词 TOP10 }, tooltip: {}, xAxis: { type: value }, yAxis: { type: category, data: keywordData.keywords }, series: [{ type: bar, data: keywordData.counts }] }); } initCharts(); /script /body /html这里用了 CDN 的 ECharts页面刷新时会去请求外部的 JS 文件。如果不希望依赖外部 CDN建议把echarts.min.js下载到本地static/目录并把script改为script src/static/echarts.min.js/script浏览器打开http://127.0.0.1:5000后正常情况会看到三个图表评论趋势折线图、情感分布饼图、关键词柱状图。如果图表没有渲染打开浏览器开发者工具的 Network 面板看/api/trend等接口是否返回 200再看 Console 有没有报错。6.3 引入总览卡片可以顺带把overview接口的数据用在页面顶部做成几个指标卡片让页面更完整div idoverviewCards styledisplay:flex; gap:20px; margin-bottom:20px;/div在initCharts()中补充const overviewData await fetchData(/api/overview); const cardsHtml div stylepadding:16px; border:1px solid #eee; border-radius:8px; flex:1; h3总评论数/h3 p stylefont-size:24px;${overviewData.total_comments}/p /div div stylepadding:16px; border:1px solid #eee; border-radius:8px; flex:1; h3总点赞数/h3 p stylefont-size:24px;${overviewData.total_likes}/p /div div stylepadding:16px; border:1px solid #eee; border-radius:8px; flex:1; h3平均点赞/h3 p stylefont-size:24px;${overviewData.avg_likes}/p /div div stylepadding:16px; border:1px solid #eee; border-radius:8px; flex:1; h3讨论最多话题/h3 p stylefont-size:24px;${overviewData.top_topic}/p /div; document.getElementById(overviewCards).innerHTML cardsHtml;7. 数据分析模块关键词、情感、趋势7.1 关键词分析示例代码用的是 jieba 分词。jieba 对中文评论的分词效果整体不错但有两个问题需要处理第一是过滤无意义词。评论里经常出现“这个”“那个”“真的”“还是”等词需要在get_keywords中加入停用词表。修改前word_list.extend([w for w in words if len(w) 1])修改后stopwords {这个, 那个, 真的, 还是, 没有, 什么, 一个} word_list.extend([ w for w in words if len(w) 1 and w not in stopwords ])停用词表可以根据实际数据不断完善。数据量变大后也可以把停用词维护成一个独立文件。第二是自定义词典。泡泡玛特相关词比如品牌名、IP 名、系列名jieba 可能没法准确切分。可以把这些词加入自定义词典jieba.add_word(泡泡玛特) jieba.add_word(盲盒) jieba.add_word(隐藏款)如果数据里有“Labubu”“Molly”这类英文词也要按实际大小写加入词典保证分词稳定。7.2 情感分布这里的情感标签是在数据准备阶段就标记好的。真实场景下可以先用规则或模型打标再存到数据文件里。示例代码通过value_counts()统计三类情感数量逻辑简单清晰。这种做法的好处是分析模块不依赖具体模型数据结构稳定缺点是准确度取决于打标质量。如果后续想提升准确度可以替换为情感分类模型但接口返回结构不需要变。7.3 趋势分析resample(D)表示按天聚合。如果数据跨月可以改成resample(W)按周聚合或者resample(M)按月聚合。趋势图是面试时最容易展开讲的部分因为可以补充说明数据为什么会波动可能受到新品发布、节假日、营销活动影响。这个分析思路比单纯画一条线更有价值。8. 接口 API 与批量处理思路8.1 已有接口参数当前项目提供 4 个 JSON 接口接口返回内容/api/overview评论总数、总点赞数、平均点赞数、讨论最多话题/api/trend按天统计的评论数量日期和数量数组/api/sentiment正面、中性、负面评论数量/api/keywords关键词 Top10 及其数量这些接口可以被前端页面调用也可以被其他系统调用。比如把/api/overview接到企业微信机器人每天定时推送数据摘要。8.2 扩展批量处理任务真实生产环境里数据不会只有一份 JSON而是会持续产生。可以设计一个简单的批量处理脚本扫描整个目录下的数据文件逐一处理并输出结果创建analysis/batch_process.pyimport os import json import pandas as pd from analyze import load_data, get_overview, get_sentiment, get_trend, get_keywords def process_file(file_path, output_dir): df load_data(file_path) result { file: os.path.basename(file_path), overview: get_overview(df), sentiment: get_sentiment(df), trend: get_trend(df), keywords: get_keywords(df), } output_name os.path.splitext(os.path.basename(file_path))[0] _result.json output_path os.path.join(output_dir, output_name) with open(output_path, w, encodingutf-8) as f: json.dump(result, f, ensure_asciiFalse, indent2) print(f处理完成: {file_path} - {output_path}) def batch_process(input_dir, output_dir): os.makedirs(output_dir, exist_okTrue) for file_name in os.listdir(input_dir): if file_name.endswith(.json): file_path os.path.join(input_dir, file_name) process_file(file_path, output_dir) if __name__ __main__: batch_process(data, outputs)运行批量脚本cd popmart-analysis python analysis/batch_process.py批量任务要注意三点第一是日志。每个文件处理成功或失败都要记录否则文件多的时候很难排查。第二是失败重试。如果数据文件格式有问题示例代码会直接抛出异常导致整个任务中断。稳妥的做法是捕获异常后跳过当前文件并记录错误信息try: process_file(file_path, output_dir) except Exception as e: print(f处理失败: {file_path}, 错误: {e})第三是输出文件要打上时间戳避免同名覆盖import time timestamp time.strftime(%Y%m%d_%H%M%S) output_name f{base_name}_{timestamp}_result.json8.3 数据采集调用建议如果把数据采集环节也加入到项目里建议设计成一个独立模块和数据分析解耦。采集模块只负责把数据写入data/目录分析模块固定读取目录下的数据文件。这样即使采集接口变化也不会影响分析链路。再次强调采集模块必须使用合法合规的方式。严格遵守robots.txt控制请求频率不对同一地址发高频请求不采集非公开内容。仅用于学习技术流程时优先使用本地模拟数据。9. 资源占用与性能观察这个项目是纯 CPU 和内存任务不涉及 GPU 显存普通笔记本就能跑。启动 Flask 后可以打开系统任务管理器观察 Python 进程的内存占用。项目初期数据量小内存占用通常很低。当数据量增长到几十万条时内存占用会明显上升因为load_data每次接口请求都会重新读取并加载完整 JSON 文件到内存。如果数据量继续变大建议做三件事第一是缓存。把第一次读取的 DataFrame 缓存在内存里避免每次请求都重新读文件。简单实现_cache None def load_data_cached(path): global _cache if _cache is None: _cache load_data(path) return _cache.copy()注意返回_cache.copy()是防止下游把原始缓存数据改掉。第二是换数据库。把 JSON 换成 SQLite分析层使用 SQL 聚合而不是把所有数据 read 进内存。Flask SQLite 的组合非常适合本地项目。如果还要继续扩展再考虑 PostgreSQL 或 MySQL。第三是加任务队列。处理耗时任务时不要放在 Flask 请求线程里同步执行。可以用 Celery 或 Redis 队列异步处理前端轮询获取任务状态。这一步属于生产环境增强项毕设项目一般不需要做到这里但可以作为简历里的扩展点提一句。接口响应时间也要关注。数据量小的时候无所谓数据量大之后/api/keywords的 jieba 分词会变成主要耗时点。最简单的优化方式是把分析结果做成定时预计算页面访问时直接读缓存结果不走实时分词。10. 常见问题与排查方法问题现象可能原因排查方式解决方案运行python app.py报 ModuleNotFoundError依赖包未安装或虚拟环境未激活执行pip list检查包是否存在执行pip install -r requirements.txt浏览器访问 5000 端口打不开Flask 启动失败或端口被占用查看终端报错信息执行lsof -i:5000查看端口占用杀掉占用进程或修改port5001/api/trend返回结果为空数组数据时间字段格式错误用 Python 打印df[created_at]的 dtype统一把时间字符串转成pd.to_datetime图表不显示接口 404 或 ECharts 资源加载失败打开 Network 面板看请求状态修改路由路径或把 ECharts 改为本地静态文件关键词出现大量无意义词未配置停用词表查看后端打印的分词结果维护停用词表并过滤单字JSON 文件编码错误读取时用了系统默认编码检查报错信息里是否包含 UnicodeDecodeErroropen时指定encodingutf-8批量任务处理到一半中断单个文件格式错误导致异常打印异常信息和当前文件名用try...except包裹单文件处理逻辑接口响应很慢每次请求都重新读取大文件查看内存和 CPU 使用率加缓存、换 SQLite 或预计算结果11. 最佳实践与合规提醒11.1 项目开发建议第一次动手先不要改代码按文章顺序把项目跑通。跑通之后再逐个调整接口参数、图表样式和数据分析逻辑。保留一套最小可运行配置建议把requirements.txt和示例数据单独保存。后续如果改坏了可以直接回退到稳定版本继续开发。目录结构要清晰。数据、模板、静态资源、分析逻辑各归各目录不要全部堆在app.py里。接口返回要保持 JSON 结构稳定。前端只负责渲染结构不要把数据处理逻辑写进模板。日志要留。启动日志、数据加载日志、批量任务日志、采集模块日志都单独输出。日志文件能帮你在出现问题时快速定位。11.2 数据合规与隐私保护这部分必须重点强调。本项目涉及评论数据和用户信息只允许处理你拥有合法来源的数据或者已经公开、允许分析使用的数据。不要采集任何账号私信、非公开页面、需要登录才能访问的内容。不要抓取用户的头像、昵称、ID 等个人敏感信息除非已获得明确授权。不要试图绕过网站的风控或反爬策略不要模拟登录不要破解验证码。学习技术时使用本地模拟数据完全够用。发布或商用前要注意版权合规。如果数据分析结果要公开展示建议对文本内容做脱敏处理。涉及具体品牌和商品的讨论时保持客观不编造数据。11.3 毕设与面试中的加分点如果想把这个项目用在毕设或简历里建议在 README 里写清楚三件事一是数据来源。说明数据是公开数据还是模拟数据采集过程是否合规。二是技术架构。画出 Flask 如何加载数据、分析模块如何聚合、ECharts 如何调用接口渲染让面试官快速理解整体链路。三是优化空间。比如“当前使用 JSON 存储数据量扩大后计划迁移到 SQLite 并增加缓存机制”。面试时除了讲功能还应该讲清楚“为什么这么设计”。例如为什么把分析逻辑放到独立模块因为接口层只负责返回 JSON分析层可以复用和单测。为什么接口格式统一因为前端和第三方系统可以共用一套数据接口。为什么批量任务要做失败重试因为真实数据文件格式可能不稳定单点失败会导致整体任务中断。12. 总结与下一步Flask ECharts Python3 这个组合特别适合做数据分析类的实战练习和毕设项目。整个流程没有复杂的分布式概念也没有难懂的算法模型重点在于把“数据采集、清洗、接口、可视化、批量处理”串成一条完整链路。跑通之后你对 Python Web 项目的数据流转就会有直观的理解这对后续学习 Django、FastAPI、爬虫框架或者数据仓库都有帮助。建议你拿到项目后先不要改代码把默认的示例数据跑起来确认图表能正常展示再泡杯茶慢慢看代码。先看app.py的路由和接口再看analyze.py的统计逻辑最后把index.html的 ECharts 配置和接口对应起来。最容易踩的坑有三个一是虚拟环境没有激活导致flask模块找不到二是data/hot_comments.json路径写错接口返回空数据三是前端 ECharts 用了 CDN但本地网络无法访问外部资源页面会自动变成空白。前两个多注意目录和路径就行第三个建议直接把echarts.min.js下载到本地static/目录一劳永逸。下一步可以尝试的方向把数据存储从 JSON 换成 SQLite用Flask Gunicorn把服务部署到云服务器给前端增加筛选时间范围的功能把情感标签从手工标注改成模型推理。每一步改动都不大但对项目的完整性提升非常明显。这个项目的真正价值不是单纯做一个“可视化大屏”而是让你掌握一套可以复用的数据分析项目骨架。后续拿到任何 CSV、JSON、数据库数据都可以用同样的方式快速搭建一个 Web 分析页面。建议收藏备用后面做课程设计或写简历项目时直接拿来改。
返回列表