ARTICLE DETAIL

资讯详情

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

Python+MySQL评论数据实战:从批量入库到Streamlit可视化看板

Python+MySQL评论数据实战:从批量入库到Streamlit可视化看板 这次我们不做零散的 Python 小练习直接用 Python MySQL 把一套完整的评论数据链路跑通数据准备 → 入库存储 → 清洗统计 → 可视化看板。业务场景拿“泡泡玛特热评”来演示但代码本身是通用的以后换成手机、美妆、游戏评论区改一下字段名就能复用。先说清楚一个前提如果要获取真实公开评论优先用官方开放接口、授权数据集或你自己的账号数据不要用非官方手段大批量抓取。本文用一份脱敏样例数据完成全流程重点放在 MySQL 建模、Python 批量导入、pandas 清洗、Streamlit 可视化看板这一套可写进简历的实战能力上。如果你正在学 Python、MySQL或者想找一个“数据分析 存储展示”完整闭环的项目这篇文章可以直接收藏。跟着做完整条链路后你会得到这样几个结果MySQL 里有一张结构清晰的评论表Python 能批量导入 CSV数据查询和清洗脚本能复用最后浏览器里能打开一个带指标的交互看板。1. 项目概述与核心能力速览这个项目不是单纯的爬虫也不是单纯的画图而是一条完整的数据处理链路。先把评论数据整理成 CSV 格式再用 PyMySQL 批量写入 MySQL之后通过 SQL 做统计最后用 Streamlit 展示成 Web 看板。先看核心能力速览能力项说明项目类型Python 数据分析与可视化实战目标业务泡泡玛特热评数据的入库、清洗、统计、展示核心语言Python 3.10数据库MySQL 8.x主要依赖PyMySQL、pandas、streamlit可视化方式Streamlit Web 看板浏览器访问数据来源脱敏样例数据 / 官方开放接口 / 授权数据运行硬件普通 CPU 电脑即可无需 GPU启动方式控制台运行 Streamlit 命令批量能力支持多个 CSV 文件顺序入库适合人群Python 初学者、数据分析学习者、简历项目开发者不适合的场景非授权批量抓取、商用水印素材、隐私数据展示这个项目的优势在于“闭环”不是单独写一条SELECT也不是单独画一张图而是把评论数据从文件一路处理到可视化页面。面试的时候你可以完整讲出自己设计了什么表、为什么用utf8mb4、怎么处理脏数据、怎么做分组统计、怎么把统计结果渲染到看板。2. 适用场景与使用边界这类项目比较适合两类人第一类是 Python 数据分析学习者。很多教程只讲到matplotlib画图并没有把 MySQL 加进来。这里补上了数据库存储环节学完以后对“表结构设计”会有真实体感。第二类是准备简历项目的人。一个带数据库、批量脚本、Web 看板的项目会比单纯爬虫更多展示工程化思维。面试官问你数据存哪里、怎么查询、怎么解决重复数据你都可以用本文的实际操作来回答。使用边界也要说清楚评论内容如果涉及真实用户昵称和评论项目演示需要脱敏。品牌名称、商品图片、官方宣传材料不能随便商用。批量抓取公开评论可能违反平台服务条款不建议用于正式项目。如果要做泡泡玛特相关的正式数据分析优先联系数据方确认授权或者只使用你合法拥有的数据。我建议本地练习时直接用“模拟评论 模拟昵称”的方式跑通整体流程。关键是掌握代码能力和数据链路而不是拿到多少真实评论。3. 环境准备与安装依赖开始写代码之前先把本地环境准备好。3.1 安装 Python建议使用 Python 3.10 及以上版本。打开终端输入python --version如果提示找不到命令需要先安装 Python并勾选“Add Python to PATH”。Windows 用户也可以在 PowerShell 里执行python --version确认版本没问题后创建一个项目目录并在目录里创建虚拟环境mkdir popmart_project cd popmart_project python -m venv venv激活虚拟环境Windows 下执行venv\Scripts\activatemacOS / Linux 下执行source venv/bin/activate激活成功后命令前会出现(venv)标识。3.2 安装 Python 依赖在项目目录下创建requirements.txtpymysql1.0.2 pandas2.0.0 streamlit1.30.0然后执行安装pip install -r requirements.txt如果下载速度慢可以临时换镜像源pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple3.3 准备 MySQL本地需要有一个可用的 MySQL 服务。可以用官方安装包也可以用 Docker 快速启动docker run -d \ --name mysql8 \ -p 3306:3306 \ -e MYSQL_ROOT_PASSWORD123456 \ -e MYSQL_DATABASEpopmart_db \ mysql:8.0这里给的是示例密码实际项目不要用这么简单的密码。如果用本机安装的 MySQL确认服务已经启动并且 3306 端口没有被占用netstat -ano | findstr 33064. 数据库设计与建表数据库设计是整条链路的基础。如果表结构设计得不对后面 SQL 查询和可视化都会很别扭。4.1 字段设计思路一条热评数据至少包含这些字段字段名类型含义idINT主键自增item_nameVARCHAR(100)商品或款名nicknameVARCHAR(100)评论用户昵称contentTEXT评论内容starTINYINT评分星级范围 1-5liked_countINT评论点赞数comment_timeDATETIME评论时间created_atTIMESTAMP数据入库时间评论内容建议使用TEXT不要用VARCHAR(255)硬扛。用户评论长度波动很大用TEXT可以避免数据超长报错。4.2 建表 SQL在 MySQL 中执行CREATE DATABASE IF NOT EXISTS popmart_db DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; USE popmart_db; DROP TABLE IF EXISTS hot_comments; CREATE TABLE hot_comments ( id INT AUTO_INCREMENT PRIMARY KEY, item_name VARCHAR(100) NOT NULL COMMENT 商品名, nickname VARCHAR(100) NOT NULL COMMENT 昵称, content TEXT NOT NULL COMMENT 评论内容, star TINYINT NOT NULL COMMENT 评分 1-5, liked_count INT NOT NULL DEFAULT 0 COMMENT 点赞数, comment_time DATETIME NOT NULL COMMENT 评论时间, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 入库时间, KEY idx_item_name (item_name), KEY idx_liked_count (liked_count), KEY idx_comment_time (comment_time) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COLLATEutf8mb4_unicode_ci COMMENT热评数据表;这里要给item_name、liked_count、comment_time加上普通索引。数据量小的时候看不出区别但评论数据一旦到几十万条全表扫描会明显变慢。执行完以后验证表结构SHOW TABLES; DESC hot_comments;看到id自增、字段类型正确、默认值正确就说明建表成功。5. 准备样例数据与批量入库这条链路里最关键的一步是把 CSV 数据写进 MySQL。我们准备一份脱敏样例数据数据内容是虚构的只用来验证流程。5.1 准备 CSV 样例文件在项目目录下创建data/mock_comments.csv内容可以这样写item_name,nickname,content,star,liked_count,comment_time LABUBU心动马卡龙,Momo玩家_01,手感很轻没想到直接出隐藏,5,231,2025-01-15 20:11:00 LABUBU心动马卡龙,Momo玩家_02,品控比想象中好 颜色很治愈,5,120,2025-01-15 21:03:00 SKULLPANDA温度,Momo玩家_03,这系列设计感很强 可惜没有抽到想要的,4,88,2025-01-15 22:30:00 SKULLPANDA温度,Momo玩家_04,实物比图片有质感,5,67,2025-01-16 09:12:00 DIMOO太空系列,Momo玩家_05,躺盒抽居然重复了 心态崩了,2,45,2025-01-16 10:05:00 DIMOO太空系列,Momo玩家_06,手感差距明显 建议多看测评,3,19,2025-01-16 11:40:00 MOLLY每一天,Momo玩家_07,造型戳中我了 大小刚好适合桌面,5,240,2025-01-16 13:22:00 MOLLY每一天,Momo玩家_08,这次配色比上一代好看很多,4,136,2025-01-16 14:18:00 太空旅行系列,Momo玩家_09,放在包里带出门非常出片,5,72,2025-01-16 15:30:00 太空旅行系列,Momo玩家_10,运输包装不错 没有磕碰,4,33,2025-01-16 16:20:00写文件时建议使用 UTF-8 编码。后面入库时也统一用utf8mb4避免中文乱码。5.2 编写批量导入脚本创建import_csv.pyimport csv import pymysql DB_CONFIG { host: 127.0.0.1, port: 3306, user: root, password: 123456, database: popmart_db, charset: utf8mb4, } CSV_PATH data/mock_comments.csv def load_csv(csv_path): rows [] seen set() with open(csv_path, r, encodingutf-8) as f: reader csv.DictReader(f) for item in reader: key (item[item_name], item[nickname], item[content]) # 简单去重避免同一份CSV重复导入 if key in seen: continue seen.add(key) rows.append(( item[item_name], item[nickname], item[content], int(item[star]), int(item[liked_count]), item[comment_time], )) return rows def save_to_mysql(rows): conn pymysql.connect(**DB_CONFIG) try: with conn.cursor() as cursor: sql INSERT INTO hot_comments (item_name, nickname, content, star, liked_count, comment_time) VALUES (%s, %s, %s, %s, %s, %s) cursor.executemany(sql, rows) conn.commit() print(f成功导入 {len(rows)} 条评论) finally: conn.close() if __name__ __main__: data load_csv(CSV_PATH) save_to_mysql(data)执行脚本python import_csv.py看到成功导入 10 条评论就说明入库成功。然后回 MySQL 里检查SELECT COUNT(*) FROM hot_comments; SELECT item_name, COUNT(*) AS cnt FROM hot_comments GROUP BY item_name;如果统计结果与 CSV 数据一致说明批量导入没问题。这里的save_to_mysql使用了executemany比一条条execute快很多。后续拿到更大的 CSV 文件只需修改读取路径不需要改入库逻辑。6. MySQL 查询统计与 pandas 清洗数据入库只是第一步。可视化之前通常要先在数据库层做聚合再用 pandas 做字段清洗和校验。6.1 常用 SQL 统计评论数据最常见的统计口径有几种按商品统计评论量、平均星星数、总点赞数按点赞数排序找热门评论。按商品统计SELECT item_name, COUNT(*) AS comment_cnt, ROUND(AVG(star), 2) AS avg_star, SUM(liked_count) AS total_likes FROM hot_comments GROUP BY item_name ORDER BY comment_cnt DESC;查看点赞最高的 10 条评论SELECT item_name, nickname, content, liked_count, comment_time FROM hot_comments ORDER BY liked_count DESC LIMIT 10;查看星级分布SELECT star, COUNT(*) AS cnt FROM hot_comments GROUP BY star ORDER BY star ASC;6.2 用 pandas 做进一步清洗SQL 能完成大部分统计但有些字段需要到 Python 层清洗。比如去掉评论内容两端的空格、把时间字符串转成时间类型、处理重复数据。创建query_data.pyimport pandas as pd import pymysql DB_CONFIG { host: 127.0.0.1, port: 3306, user: root, password: 123456, database: popmart_db, charset: utf8mb4, } def load_dataframe(): conn pymysql.connect(**DB_CONFIG) try: sql SELECT item_name, nickname, content, star, liked_count, comment_time FROM hot_comments df pd.read_sql(sql, conn) return df finally: conn.close() def clean_dataframe(df): # 去掉首尾空格 df[content] df[content].str.strip() df[nickname] df[nickname].str.strip() # 时间字段转换 df[comment_time] pd.to_datetime(df[comment_time]) # 同一商品下同一昵称和评论内容视为重复 df df.drop_duplicates(subset[item_name, nickname, content]) # 过滤无内容的脏数据 df df[df[content].notna() (df[content] ! )] return df if __name__ __main__: raw_df load_dataframe() clean_df clean_dataframe(raw_df) print(clean_df.info()) print(clean_df.head())这段代码建议保留成工具函数。后面做 Streamlit 看板时可以直接复用不需要在界面脚本里重新写一遍清洗逻辑。实际项目如果数据量大清洗逻辑尽量放到入库前完成查询时只做聚合。评论数据如果是上百万条全量SELECT回 pandas 会占用大量内存需要按时间分区或按商品维度分页处理。7. 可视化实战从聚合数据到 Web 看板评论数据存进 MySQL 后可以用多种方式展示。这里重点演示 Streamlit 交互看板因为它的开发成本低最终效果也直观适合做简历项目展示。7.1 创建 Streamlit 看板脚本在项目目录下创建dashboard.pyimport pandas as pd import pymysql import streamlit as st DB_CONFIG { host: 127.0.0.1, port: 3306, user: root, password: 123456, database: popmart_db, charset: utf8mb4, } st.cache_data(ttl300) def load_data(): conn pymysql.connect(**DB_CONFIG) try: sql SELECT item_name, nickname, content, star, liked_count, comment_time FROM hot_comments df pd.read_sql(sql, conn) df[comment_time] pd.to_datetime(df[comment_time]) return df finally: conn.close() st.set_page_config( page_title泡泡玛特热评可视化, page_icon, layoutwide, ) st.title(泡泡玛特热评数据分析看板) st.caption(本地脱敏样例数据仅用于技术演示) df load_data() if df.empty: st.warning(数据库中暂无评论数据请先运行 import_csv.py 导入数据。) st.stop() col1, col2, col3, col4 st.columns(4) col1.metric(评论总数, len(df)) col2.metric(参与商品数, df[item_name].nunique()) col3.metric(平均星级, round(df[star].mean(), 2)) col4.metric(总点赞数, int(df[liked_count].sum())) st.subheader(各款商品评论量 Top10) df_item ( df.groupby(item_name) .agg(comment_cnt(content, count), total_likes(liked_count, sum)) .reset_index() .sort_values(comment_cnt, ascendingFalse) .head(10) ) st.bar_chart(df_item.set_index(item_name)[comment_cnt]) st.subheader(评论星级分布) df_star df[star].value_counts().sort_index() st.bar_chart(df_star) st.subheader(点赞数 Top10 热评) top_comments ( df.sort_values(liked_count, ascendingFalse) .head(10)[[item_name, nickname, content, liked_count]] .reset_index(dropTrue) ) st.dataframe(top_comments, use_container_widthTrue)注意脚本里的密码123456是本地开发用的示例如果要放到服务器或 GitHub一定要改成环境变量读取不能硬编码。7.2 启动看板终端执行streamlit run dashboard.py默认会在浏览器打开http://localhost:8501。打开后你会看到四个指标卡片评论总数、参与商品数、平均星级、总点赞数下方还有各款商品评论量 Top10 和星级分布。判断运行是否成功的标准很简单页面能正常打开。指标数字和 MySQL 里的查询结果一致。切换页面尺寸时图表能自适应。修改数据库里的数据后等待缓存过期刷新页面数据能更新。如果端口 8501 被占用可以指定端口streamlit run dashboard.py --server.port 85027.3 交互看板与静态 HTML 的区别Streamlit 适合本地演示和数据探索。它的优点是不用自己写前端刷新后自动重跑脚本适合面试前反复调试。如果你需要交付一个独立的 HTML 文件不依赖 Python 环境运行可以改用 pyecharts 生成静态页面。思路是先查询 MySQL再调用Bar、Pie、WordCloud生成图表最后render()输出 HTML。下面给一个 pyecharts 生成柱状图的示例from pyecharts import options as opts from pyecharts.charts import Bar items [LABUBU, SKULLPANDA, DIMOO] counts [10, 8, 6] bar ( Bar() .add_xaxis(items) .add_yaxis(评论量, counts) .set_global_opts(title_optsopts.TitleOpts(title各商品评论量)) ) bar.render(item_comment_count.html)这里用的是硬编码数据真实项目可以直接把 pandas 聚合结果转成列表再传进去。静态 HTML 更适合邮件报告和定时任务输出交互看板更适合日常分析。8. 批量任务多 CSV 自动导入与后续扩展真实项目中评论数据不可能只有一份文件更常见的情况是每天收到一个 CSV或者定期从数据源同步一次。这时候可以写一个目录扫描脚本把data文件夹下所有 CSV 都入库。创建batch_import.pyfrom pathlib import Path from import_csv import load_csv, save_to_mysql DATA_DIR Path(data) def main(): csv_files list(DATA_DIR.glob(*.csv)) if not csv_files: print(目录中未找到 CSV 文件) return for csv_file in csv_files: print(f正在处理: {csv_file.name}) rows load_csv(str(csv_file)) if rows: save_to_mysql(rows) else: print(f{csv_file.name} 中没有新数据) print(批量导入完成) if __name__ __main__: main()这个脚本里复用import_csv.py的load_csv和save_to_mysql整体逻辑非常清晰。需要注意本文的脚本是“直接插入”如果重复执行同一份 CSV会产生重复评论。更严谨的做法是在数据库表中加唯一索引比如对nickname和content建立唯一索引然后使用INSERT ... ON DUPLICATE KEY UPDATE。评论内容可能比较长建唯一索引时要控制字段长度或者改用 MD5 字段保存评论内容哈希值。更进一步如果你想做“每天自动更新”可以配合操作系统的定时任务。Windows 使用任务计划程序macOS / Linux 使用crontab定时执行cd /path/to/popmart_project source venv/bin/activate python batch_import.py本项目只演示了 CSV 批量导入如果你后面接的是 API 数据源逻辑也是类似的请求数据 → 转换为统一字段结构 → 执行清洗 → 写入 MySQL。9. 资源占用与性能观察这个项目属于轻量级 Web 数据分析应用对资源要求很低普通笔记本即可运行。运行时主要关注三个指标9.1 Python 进程内存pandas 会把数据读入内存所以如果hot_comments表里有几百万条评论dashboard.py每次访问都会占用较多内存。解决办法是不要全表SELECT而是先把统计逻辑放到 SQL 里SELECT item_name, COUNT(*) AS comment_cnt, AVG(star) AS avg_star, SUM(liked_count) AS total_likes FROM hot_comments GROUP BY item_name;让 MySQL 完成聚合Python 只接收最终统计结果。9.2 MySQL 连接Streamlit 的st.cache_data(ttl300)可以把查询结果缓存 5 分钟。这样每次页面刷新不会重复请求数据库能显著降低 MySQL 压力。观察 MySQL 运行状态时可以在 MySQL 命令行执行SHOW PROCESSLIST;如果看到大量来自 Web 应用的连接堆积需要检查数据库连接池配置和查询语句是否走了索引。9.3 索引优化评论表的item_name、liked_count、comment_time都加了普通索引。评论量大的时候按点赞数排序会使用idx_liked_count按时间范围筛选会使用idx_comment_time。确认 SQL 是否走索引EXPLAIN SELECT * FROM hot_comments WHERE liked_count 100 ORDER BY liked_count DESC;观察possible_keys和key字段如果显示NULL说明 SQL 没有使用索引需要改写查询条件。如果只是本地练习几千条到几万条数据基本不会有性能问题。重点关注代码结构的规范和后续扩展能力。10. 常见问题与排查方法实际动手时新手最容易遇到下面这些问题问题现象可能原因排查方式解决方案导入时报 Access denied数据库密码错误检查 DB_CONFIG 中的密码改为正确密码连接 MySQL 报 1130当前用户只允许 localhost 登录查看用户 host 权限使用 127.0.0.1 连接或者授权远程访问中文乱码连接字符集不是 utf8mb4检查连接配置和建表字符集连接参数加 charsetutf8mb4CSV 导入报 Data too long字段长度不够查看报错字段content 使用 TEXT 类型Streamlit 页面空白依赖未安装或服务未启动终端看报错信息执行 pip install -r requirements.txt端口被占用8501 或 3306 被其他程序占用netstat 查看端口换端口启动或结束占用进程重复导入数据翻倍同一条评论没有去重执行 SELECT COUNT(*)添加唯一索引或 Python 层去重页面指标为 0数据库表为空查询数据库中的记录数执行 import_csv.py 重新导入时间字段报错CSV 时间格式不标准打印原始值确认统一改为 YYYY-MM-DD HH:MM:SS遇到问题不要直接重装环境先看终端报错。PyMySQL 报错信息一般会指出密码、主机、连接数、SQL 语法等问题把报错关键词复制到搜索框基本都能定位。11. 最佳实践与合规建议最后整理几条对这个项目最重要、也能直接提升简历质量的经验。11.1 数据必须脱敏和合规真实评论数据可能包含用户昵称、头像、账号信息。正式项目里未经授权处理用户个人信息有法律风险。如果要在简历项目里展示建议使用脱敏后的模拟数据并明确标注“仅用于技术演示”。如果公司需要分析真实商品评论应该使用业务方自己拥有的数据或者官方提供的开放接口。不要用非官方工具突破平台限制。品牌名、商品图片尤其是商业化使用需要先确认版权和授权范围。11.2 保持“小步快跑”的验证方式第一次跑通项目时不要一次性导入十万条数据。先用 10 条左右的样例数据验证全流程确认入库、查询、可视化都正常后再扩大数据量。同理首次启动 Streamlit 时先用小数据集验证页面再逐步增加图表。这样可以把“数据有问题”和“代码有问题”分开排查。11.3 把配置和代码分开数据库密码、主机地址、端口不要写死在业务脚本里。更好的做法是读取环境变量import os DB_CONFIG { host: os.getenv(MYSQL_HOST, 127.0.0.1), port: int(os.getenv(MYSQL_PORT, 3306)), user: os.getenv(MYSQL_USER, root), password: os.getenv(MYSQL_PASSWORD, ), database: os.getenv(MYSQL_DATABASE, popmart_db), charset: utf8mb4, }这样脚本在别人电脑上也能运行不至于把自己的密码提交到 GitHub。11.4 简历面试要讲清楚业务价值这个项目写进简历时不要只写“用 Python 爬虫抓了泡泡玛特评论”。更完整的表达是使用 Python 对评论数据进行清洗、去重、入库构建评论数据表。通过 MySQL 完成商品维度的聚合统计和高赞评论筛选。使用 pandas 和 Streamlit 开发交互式数据看板支持评论量、星级分布、热门评论展示。设计了可复用的 CSV 批量导入脚本支持定时更新。面试官大概率会追问“为什么用 MySQL 不用 Excel”你可以回答MySQL 适合结构化存储、支持索引、能处理更大数据量也方便后续对接定时任务和接口服务。11.5 后续扩展方向项目本身还有很大的扩展空间对评论内容做中文分词和情感判断统计正面、负面评价比例。按日期维度做趋势图观察评论量和点赞量变化。扩展移动端适配做评论关键词搜索和筛选。加入定时任务每天自动同步新数据。把 Streamlit 看板部署到服务器多人远程访问。从项目完整度来说建议先完善“数据更新频率”和“评论质量统计”这两块能让面试官感受到你不只是会调库而是在思考业务指标。总结Python MySQL Streamlit 的组合非常适合作为第一个“有存储、有统计、有展示”的完整数据项目。泡泡玛特热评只是演示场景换成其他品牌或品类只需要改数据字段和图表标题即可。最初的验证路径建议这样走先建库建表再用 10 条样例数据完成批量导入接着运行 SQL 聚合统计最后启动 Streamlit 看板。全流程跑通后再按自己的需求增加情感分析、定时同步、多条件筛选等功能。最容易踩的坑是中文乱码和重复导入这两点在建表和入库脚本阶段处理好后面会少很多麻烦。整个项目做完后记得把代码整理到 GitHub并把数据库表设计放到 README 里方便复盘和二次扩展。
返回列表