Python爬虫+Flask+ECharts实现短视频用户画像可视化分析

发布时间:2026/10/19 7:15:38
Python爬虫+Flask+ECharts实现短视频用户画像可视化分析 做数据可视化项目这一两年我发现一个很有意思的现象很多人一提到短视频用户画像就觉得必须上Hadoop、Spark仿佛不搞个集群就不叫大数据。但实际接需求的时候大部分场景根本到不了那个量级——一天几万条评论、几千个热门视频一台普通PC用Python爬虫配合Flask做展示完全能跑得很流畅而且成本低、见效快特别适合个人开发者做练手项目或者小团队快速验证产品想法。我这段时间正好把一个短视频用户兴趣数据可视化分析系统从头到尾做了一遍整个链路包括爬虫采集、数据清洗、兴趣标签提取、Flask后端接口、ECharts可视化大屏。这篇文章不聊虚的直接把我踩过的坑和验证过好用的方案拆开讲从零搭建一套能跑、能看、能扩展的完整系统给正在做类似项目的朋友一个可参考的落地做法。1. 项目背景与整体设计思路1.1 核心需求拆解不只是爬数据画图表很多人在拿到这类题目时容易陷入一个误区先急着写爬虫爬到一堆数据后才发现不知道展示什么。我建议先想清楚两个问题分析的主体是谁分析的指标是什么。拿我这个项目来说名为短视频用户兴趣分析实际上分析的是内容背后透露出的用户偏好。我采集的是某短视频平台的热门视频信息包括视频标题、描述文案、点赞数、评论内容、作者信息等。表面上是分析视频本质上是通过这些内容反推用户的兴趣分布评论里高频出现的词汇就是用户讨论的热点高点赞视频的分类就是用户偏好的内容类型。这个定位非常重要它决定了后续所有模块的选型。如果定位错了比如把目标定成采集用户个人主页数据那就会涉及隐私和合规问题项目根本没法落地。只采集公开的热门内容和公开评论做聚合分析不涉及任何个人身份信息这是整个项目能够安全完成的底线。基于这个定位我整理了系统的功能清单爬虫模块定时采集热门视频信息、评论数据对采集内容做清洗、去重、分词提取兴趣标签设计热度计算公式量化每个兴趣标签的受欢迎程度用Flask提供JSON数据接口将统计结果返回给前端前端用ECharts实现排行榜、词云、趋势图、饼图等可视化展示1.2 技术栈选型为什么用Flask这种轻方案整个项目最核心的技术选型有三个Flask、SQLite或MySQL、ECharts。我把选型逻辑说清楚方便你根据自己的情况做取舍。后端框架Flask而不是Django或FastAPI。Flask最核心的优势是轻、灵活、上手快。这个项目的后端功能本质上就是读数据库→算指标→返回JSON逻辑不复杂用Flask正好。Django自带Admin后台和ORM对这类小项目来说有点重FastAPI性能好但生态相对年轻中文资料少对新手不够友好。Flask有海量的中文教程出问题搜起来很方便。数据库SQLite起步数据量上来后再迁MySQL。我初期用的是SQLite单文件、零配置、Python自带支持非常适合开发和验证阶段。实测数据量在几十万条以内时SQLite的查询性能完全能接受。等采集数据量增长到百万级再平滑迁移到MySQLFlask的SQLAlchemy ORM可以做到切换成本极小。前端可视化ECharts没有第二个选项。短视频用户兴趣分析要展示词云、排行榜、趋势折线、分类饼图这些ECharts都有现成的组件配置项文档齐全做出来的效果也足够美观。这个组合下来依赖环境非常干净Python 3.9、Flask、Requests、Pandas、jieba中文分词、SQLAlchemy外加一个前端ECharts库全部加起来不会超过10个依赖包。一个普通的两核4G云服务器就能扛住部署成本极低。2. 数据采集爬虫模块的搭建与实战细节2.1 设计一个可控、可扩展的爬虫架构爬虫是这个项目的数据源头也是坑最多的地方。我见过太多人一上来就用Selenium无头浏览器整页渲染慢不说还容易被反爬策略识别。短视频平台的数据获取其实有更轻量的做法。我的做法是通过分析Web端接口直接构造HTTP请求获取JSON数据。短视频平台的网页端通常会有一套数据接口返回的数据结构稳定包含视频ID、标题、点赞数、评论数等字段。只需要用Requests库模拟浏览器的请求头就能拿到结构化的数据比解析HTML效率高一个量级。爬虫架构我分成三层请求层管理请求头、Cookie、代理IP负责发送HTTP请求解析层把返回的JSON解析成结构化字典只保留需要的字段存储层清洗去重后写入SQLite每一层独立成模块方便后续维护。比如平台接口升级了只需要改解析层其他部分不受影响。请求层的设计要注意一个细节请求头的顺序和完整度都很重要。有些平台的接口会校验User-Agent、Referer、Origin这些字段一个都不能少。我常用的请求头配置大致如下headers { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36, Referer: https://www.xxx.com/, Origin: https://www.xxx.com, Accept: application/json, text/plain, */*, Accept-Language: zh-CN,zh;q0.9, }用这种方式采集单个视频的信息和评论列表的数据都能拿到。实测接口响应速度很快平均每个视频的采集耗时不超过1秒比Selenium整整快了一个数量级。2.2 数据清洗与存储这部分决定你的分析质量很多人把爬虫写完就开始兴奋地写统计代码结果分析出来的词云全是哈哈哈哈哈666这类无效词根本无法反映真实兴趣。这就是数据清洗没做到位的典型表现。我总结的清洗流程分四步第一步去除ASCII乱码和特殊符号。评论里经常有表情符号、用户名、网页链接这些对兴趣分析没有任何价值。用正则表达式统一剔除import re def clean_text(text): # 去除非中文、非字母、非数字的杂项符号 text re.sub(r[^\u4e00-\u9fa5a-zA-Z0-9], , text) # 去掉多余空格 text re.sub(r\s, , text).strip() return text第二步中文分词与停用词过滤。中文分词我用jieba这是目前中文分词最好用的工具之一。分词后要过滤停用词——那些的了就是真的之类的词没有任何分析价值。停用词表可以自己维护一个也可以直接用社区的中文停用词库我建议自己维护因为平台用户有特定的语言习惯比如哈哈哈绝了学到了这类词通用停用词表未必覆盖。import jieba def tokenize(text): words jieba.lcut(text) stopwords load_stopwords() # 加载自定义停用词表 return [w for w in words if w.strip() and len(w) 1 and w not in stopwords]第三步多表关联存储。我设计了三张核心表视频表、评论表、兴趣标签表。视频表存储视频的标题、点赞数、评论数、分类评论表存储评论内容、评论时间、所属视频ID兴趣标签表存储从评论里提取出来的词汇和词频。三张表通过外键关联查询起来非常方便。第四步增量去重。爬虫定时运行时可能会重复采集同一个视频。我在视频表里给视频ID加了唯一索引用INSERT OR IGNORE的方式写入重复数据自动被过滤。这个看似不起眼的细节能避免后期数据膨胀导致统计失真。2.3 爬虫模块的避坑指南这部分我踩过不少坑总结三条最值的经验。第一条控制采集频率是保命法则。一开始我为了快速积累数据把请求间隔设成了0.1秒结果不到两分钟就被平台封了IP。后来我把请求频率控制到每秒1~2个请求加上随机延时2~5秒稳定运行好几天都没出问题。记住数据采集拼的不是瞬时速度而是稳定性。import time import random # 每个视频采集完成后随机休眠2-5秒 time.sleep(random.uniform(2, 5))第二条一定要做异常捕获和断点续采。网络抖动、接口变动、反爬触发都可能让爬虫中断。我的做法是爬虫的主循环里捕获所有异常记录当前采集进度到日志文件重启时从上次进度继续。否则采集到一半挂了前功尽弃。第三条数据合法性要有意识。我只采集平台公开的热门内容和公开评论不采集用户个人资料、不采集私密信息展示时也只做聚合统计不展示任何个人身份信息。这一点不仅是合规问题也是项目能长期运行的前提。3. 数据分析与可视化系统核心环节实现3.1 兴趣标签提取与热度计算逻辑数据清洗完成后要解决一个问题怎么把一堆分词结果变成用户兴趣的可量化指标我的做法分两步先做词频统计再做热度加权。简单的词频统计反映的是讨论量但讨论量高不代表兴趣度高。一个视频如果在评论区被狂喷讨论量也高但它反映的是负面情绪不是真正的兴趣。所以我用了热度计算公式标签热度 词频权重 * 0.4 互动权重 * 0.6 互动权重 该标签出现的视频的平均点赞数 / 全网视频平均点赞数这个公式的逻辑是如果一个标签经常出现在高点赞视频的评论区说明用户对这个话题是真感兴趣而不只是路过吐槽。词频权重保证高频标签能浮现互动权重保证高热度标签能排到前面。标签分类也值得一提。我用两种方式建立标签体系一种是基于视频自带的分类字段如美食、旅行、游戏、科技另一种是基于分词结果自动聚类。前者是显性兴趣后者是隐性兴趣两者结合才能看到完整的用户偏好图谱。实际运行效果来看这个公式能很好地区分明星的绯闻评论区和教程类视频评论区——前者的标签热度高但互动权重低后者的互动权重普遍更高说明用户是在主动获取感兴趣的内容。3.2 Flask后端接口从数据库到JSON的转化后端模块的核心任务是把统计结果整理成前端ECharts能直接消费的JSON结构。我用Flask写了几组核心接口from flask import Flask, jsonify from sqlalchemy import func, text app Flask(__name__) app.route(/api/hot_tags) def hot_tags(): 返回热门兴趣标签Top20 sql text( SELECT tag_name, SUM(tag_hot_score) as total_score FROM interest_tags GROUP BY tag_name ORDER BY total_score DESC LIMIT 20 ) result db.session.execute(sql).fetchall() data [{name: row[0], value: row[1]} for row in result] return jsonify({code: 0, data: data}) app.route(/api/category_distribution) def category_distribution(): 返回分类视频数量占比用于饼图展示 sql text( SELECT category, COUNT(*) as cnt FROM videos GROUP BY category ORDER BY cnt DESC ) result db.session.execute(sql).fetchall() data [{name: row[0], value: row[1]} for row in result] return jsonify({code: 0, data: data})接口返回的JSON格式要保持统一前端才好处理。我最常用的是{code: 0, data: [...]}这种结构code表示业务状态data放实际数据。注意接口要做跨域处理否则前端页面独立端口访问时会被浏览器拦截Flask有现成的flask-cors库安装后两行代码就能解决这个细节很容易被忽略。3.3 ECharts可视化大屏把数据变成能看懂的图前端我做了单页面的大屏布局左侧放分类饼图和兴趣标签排行榜中间放关键词词云右侧放趋势折线图和Top视频列表。每一块对应一组接口页面加载时统一请求拿到数据后填充到ECharts组件里。词云是用户兴趣最直观的展示方式。ECharts没有官方的词云组件需要用echarts-wordcloud插件配置起来也很简单// 基于准备好的dom初始化echarts实例 var chart echarts.init(document.getElementById(wordCloud)); // 从后端接口获取标签热度数据 fetch(/api/hot_tags) .then(res res.json()) .then(result { var data result.data.map(item { return { name: item.name, value: item.value }; }); var option { series: [{ type: wordCloud, shape: circle, sizeRange: [12, 60], rotationRange: [-45, 45], textStyle: { color: function() { return rgb( Math.round(Math.random() * 255) , Math.round(Math.random() * 255) , Math.round(Math.random() * 255) ); } }, data: data }] }; chart.setOption(option); });词云里字号越大、颜色越亮的词代表热度越高。从视觉上一眼就能看出用户最集中的兴趣方向这是纯数据表格做不到的。折线图做的是不同分类话题的热度随时间的变化趋势可以看到用户兴趣的迁移。比如科技类话题在某个时间段突然走高对应可能是某款新手机发布美食类话题节假日期间明显上涨。这种时间维度上的洞察是这个项目最有价值的部分也让分析不再局限于某一刻的静态画像。排行榜和饼图相对简单设置好xAxis、yAxis或series的data属性就能出图。整个前端页面我控制得比较克制颜色不超过五个主色卡片式布局留白充足观感要胜过那些塞满各种图表却毫无重点的大屏。4. 部署与常见问题排查实录4.1 部署到服务器的完整流程项目在本地跑通之后要部署到云服务器上给别人访问。我踩了三次坑才把流程走顺记录一下最稳的步骤环境准备阶段。服务器装好Python 3.9用virtualenv创建独立的虚拟环境避免污染系统Python。安装依赖时建议用requirements.txt锁定版本防止哪天某个依赖库升级导致代码跑不起来。进程守护阶段。Flask自带的开发服务器app.run()不能用于生产环境性能差、还不稳定。我用gunicorn做生产级WSGI服务器配合systemd做进程守护保证后端服务挂掉后能自动重启。# 安装gunicorn pip install gunicorn # 用4个worker启动Flask应用 gunicorn -w 4 -b 0.0.0.0:5000 app:app注意app:app第一个app是模块名第二个是Flask实例的变量名。很多新手在这里栽跟头报错ModuleNotFoundError检查一下文件名和变量名是否一致。反向代理阶段。服务器的80端口交给NginxNginx再转发到5000端口给gunicorn。静态文件前端页面、JS、CSS直接由Nginx托管请求/api/路径才转发给后端。这样前端资源和后端接口分离性能更好也方便后续扩展HTTPS。4.2 常见问题速查与排查思路这部分我整理成一张速查表把实际开发中高频出现的问题和解决思路放一起方便你对照排查。问题现象可能原因排查方法爬虫采集到一半停止接口请求被限制、网络中断查看日志是否出现HTTP 403/429检查休眠时间是否过短词云出现大量无意义词停用词表不完整手动补充平台特色停用词重新分词统计图表显示空白接口返回的JSON结构不对浏览器开发者工具看/api/返回结果核对字段名页面能打开但接口报跨域错误后端未开启CORS安装flask-cors初始化时配置CORS(app)数据库文件越来越大重复采集数据累积检查唯一索引是否建好清理重复数据部署后页面样式丢失静态文件路径写死确认前端页面的静态资源使用相对路径最让我印象深刻的一个排查案例是接口数据正常但图表始终不显示。我以为是ECharts配置写错了折腾了半天才发现问题出在数据格式上——后端返回的数值是字符串类型ECharts的散点图要求数字类型字符串会导致数据无法映射到坐标轴。解决办法是在前端做一层数据解析把字符串转数字。这个案例说明很多时候问题不在框架本身而是数据类型这类看起来很基础的环节。4.3 性能优化与数据量增长应对当采集数据量从几万条涨到几十万条我遇到了几个新问题SQLite写入变慢、统计查询耗时明显增加。解决思路有三条第一条给常用查询字段建立索引。比如评论表的video_id、视频表的category建索引后查询速度能提升几十倍。第二条把统计计算从实时改为定时。不再让每个用户请求时实时跑聚合计算而是用定时任务每隔半小时算一次统计结果存到独立的统计表里前端直接读统计表。这样接口响应时间从秒级降到毫秒级体验提升明显。第三条架构上预留迁移路径。如果数据量继续增长把SQLite换成MySQLORM层级不用改代码只需要改连接字符串这是SQLAlchemy带来的最大红利。5. 项目复盘与进阶扩展方向这套系统做完之后我复盘了一下整个项目最有价值的部分其实不是那些图表而是数据采集到分析之间的加工链条。爬虫只是起点数据清洗的质量决定分析的天花板而这个从原始数据到结构化洞察的能力是各类数据岗位都通用的核心技能。关于扩展方向基于我目前的实践和观察有三条值得尝试的路第一丰富数据维度。目前的系统主要分析视频内容和评论实际上还可以接入话题标签Hashtag、视频配乐、发布时间等维度。比如分析用户活跃时间段和热门音乐趋势会让兴趣画像更立体。第二尝试更精细的算法模型。我现在用的热度加权公式属于可解释性强但相对简单的方案。如果对推荐算法感兴趣可以在现有标签体系上尝试更精细的建模比如根据用户的历史行为序列建立兴趣衰减模型或者引入基于内容的推荐逻辑。这里我想强调一点不要迷信复杂的模型先把你手上的数据吃透用简单的统计方法做出可解释的结论再逐步升级方法这是最务实的路径。第三做定时报告推送。服务器上可以配置定时任务每天凌晨计算前一天的热点标签变化生成日报并推送。这样一来系统从被动展示变成主动洞察实用性会提升几个台阶。我在实际操作中还有个很深的体会做这类项目最大的瓶颈往往不是技术而是需求定义。如果没有想清楚我要分析谁、分析什么指标、指标怎么算出来的代码写得再漂亮也只是花架子。建议大家动手写代码前先花一个晚上想清楚这三件事后面能少走很多弯路。最后再分享一个小技巧开发时可配置app.debug True开启Flask调试模式这样改完后端代码不需要手动重启服务能明显提升开发效率。等部署到生产环境时记得把这个开关关掉同时把调试信息隐藏起来省得暴露不必要的系统细节。做这类偏应用的项目安全和稳定的优先级永远高于炫技。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询