尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
Python毕设实战:B站用户行为分析全链路系统
简介这是一份面向计算机专业本科生的毕业设计实战项目资源聚焦B站用户行为数据挖掘与可视化分析适用于课程设计、毕设选题及Python数据分析能力提升场景。资源包含完整可运行系统涵盖用户注册登录模块、UP主多维分析视频类型分布、发布时间规律、全站综合统计按小时/周/月维度的发布量与标签热度排名辅以柱状图、折线图等前端可视化呈现。压缩包共582个文件含40个HTML页面、35个Python核心脚本、166张PNG/JPG界面截图、107个JS交互逻辑及26个CSS样式文件另有SQL数据库脚本、演示视频MP4、PDF文档与Excel数据样例整体46.95MB。目前已有142人学习下载提供从环境部署、数据库初始化、前后端联调到结果展示的全流程支持代码结构清晰、注释完整适合作为PythonWeb数据分析技术栈的综合性实践范例。1. 毕业设计-基于Python的B站用户行为分析系统不是爬虫玩具而是能跑通「数据采集→清洗→建模→可视化」全链路的可交付工程你手头这份毕业设计资源不是网上随手搜到的“Python爬B站弹幕”小脚本也不是只跑出几张图表就收工的PPT式Demo。它是一套完整闭环的、带真实数据库结构、含可复现演示视频、源码已通过本地环境验证的教学级生产化原型系统——从B站公开接口非逆向、不触碰登录态抓取用户主页、视频互动、UP主粉丝画像等结构化行为数据存入MySQL再用Pandas做会话识别与行为路径聚类最后用FlaskPyEcharts搭出带筛选控件的交互式仪表盘。适合计算机/信管/数科专业本科生直接开箱即用答辩前3天部署成功、答辩时现场切换UID查活跃度热力图、导师问“怎么定义用户流失”你能指着user_churn.py里基于7日无互动订阅降级的复合判定逻辑回答。它不解决高并发或千万级ID调度但把毕业设计最卡脖子的环节——数据链路断点、SQL表关联错乱、时间序列对齐失败、前端图表渲染空白——全踩过一遍并留了注释。如果你正被“毕设只剩两周但数据还没落库”压得睡不着这份资源就是你今晚能跑起来的第一份可信基线。2. 系统架构与技术选型为什么用RequestsMySQLFlask而不是ScrapyMongoDB这套系统没堆炫技组件所有技术栈选择都指向一个目标让答辩老师在5分钟内看懂数据从哪来、怎么算、结果在哪。我拆包后逐行比对过源码和数据库schema它的技术决策背后有明确的教学合理性不是随便抄来的组合。2.1 数据采集层Requests 官方API 反爬绕过策略非Selenium系统没用Scrapy——因为Scrapy的中间件、Pipeline、ItemLoader对本科生调试太黑盒。它用纯Requests调用B站公开可用的Web端API如https://api.bilibili.com/x/space/acc/info?midxxx获取UP主基础信息https://api.bilibili.com/x/v2/reply?oidxxxpn1拉评论并通过以下三步规避基础反爬User-Agent轮换config.py里预置了12个主流浏览器UA字符串每次请求随机选取Referer伪造强制设置Referer: https://www.bilibili.com/模拟真实页面跳转请求间隔控制crawler/utils.py中sleep(1.2 random.uniform(0,0.5))避免触发IP限频。提示B站2024年已对未登录态API增加X-Requested-With头校验原包中headers字典已补全该字段实测有效。若你遇到412错误请检查headers是否含X-Requested-With: XMLHttpRequest。2.2 数据存储层MySQL关系型建模而非NoSQL文档存储数据库用MySQL而非MongoDB是为强制建立清晰的数据契约。bilibili_user_behavior.sql建表脚本共7张表核心三张如下表名主要字段设计意图关键约束usersuid,name,face,sign,level,regtime用户基础档案uid为主键regtime为INT类型时间戳videosbvid,title,author_uid,pubdate,view,danmaku,reply视频元数据及播放指标bvid为主键author_uid外键关联users.uiduser_interactionsid,uid,bvid,interaction_type,timestamp,duration用户行为原子事件interaction_type枚举值like,coin,share,watchtimestamp为DATETIME这种设计让“查某UP主最近30天被投币最多的10个视频”这类问题能用单条SQL解决避免MongoDB里嵌套查询导致的聚合性能黑洞。且MySQL的事务特性保障了users和videos表插入的原子性——当UP主信息入库失败时关联视频不会孤悬。2.3 分析与服务层Pandas轻量计算 Flask最小化API没上Spark或Dask因毕设数据量级在万级用户、十万级行为记录。analysis/behavior_cluster.py用Pandas实现基于user_interactions.timestamp生成用户会话session规则同一用户相邻行为间隔≤15分钟视为同一次会话对每个会话提取行为序列如[watch,like,coin]用Levenshtein距离做序列相似度聚类输出session_cluster_result.csv供前端调用。Flask服务仅暴露3个API端点/api/user/{uid}返回用户基础信息最近5条互动记录/api/video/{bvid}返回视频详情弹幕情感倾向调用analysis/sentiment.py的SnowNLP简易模型/api/dashboard返回按日期聚合的总播放量、互动率、新用户增长曲线。注意Flask未启用debug模式app.py中debugFalse且host0.0.0.0部署时需配合nginx反向代理避免直接暴露开发端口。3. 核心功能实现从UID抓取到行为热力图的6步落地流程这套系统真正的价值不在代码量而在它把教科书概念转化成了可调试的模块。下面以“分析UID为223333的UP主粉丝行为特征”为例带你走完从数据落地到图表渲染的完整路径。所有命令均在项目根目录执行。3.1 初始化数据库并导入初始数据# 1. 创建数据库需提前安装MySQL 8.0 mysql -u root -p -e CREATE DATABASE bilibili_behavior CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; # 2. 执行建表脚本注意路径 mysql -u root -p bilibili_behavior database/bilibili_user_behavior.sql # 3. 导入示例数据含100个测试UID的用户档案和500条互动记录 mysql -u root -p bilibili_behavior database/sample_data.sql参数说明utf8mb4字符集支持B站昵称中的emoji如“小破站✨”sample_data.sql中users表的regtime字段为UNIX时间戳如1577808000对应2020-01-01user_interactions.timestamp为DATETIME格式如2024-03-15 14:22:33确保时区统一为Asia/Shanghai若导入报错ERROR 1067 (42000): Invalid default value for xxx请先执行SET GLOBAL sql_mode(SELECT REPLACE(sql_mode,NO_ZERO_DATE,));。3.2 配置采集参数并启动用户数据抓取修改config.py中的关键参数# config.py BILIBILI_API_BASE https://api.bilibili.com # 抓取目标指定UID列表支持单个或批量 TARGET_UIDS [223333, 123456, 987654] # 此处填你要分析的UP主UID # 抓取深度每个UID获取其粉丝列表最多1000人 最近20个视频 FANS_PAGE_SIZE 50 # 每页粉丝数B站API限制最大50 VIDEO_PAGE_SIZE 20 # 代理设置国内直连可留空 PROXY None # 如需走公司代理设为{http: http://192.168.1.100:8080}运行采集主程序python crawler/main_crawler.py执行逻辑说明程序先调用/x/space/acc/info获取UP主223333的基础信息存入users表再调用/x/relation/followers分页拉取其粉丝UID最多1000个存入临时表temp_fans对每个粉丝UID调用/x/space/arc/search获取其最近20个视频的BV号存入videos表最后调用/x/v2/reply拉取这些视频的前3页评论每页20条解析用户UID并写入user_interactions表interaction_type设为comment。3.3 运行行为分析脚本生成聚类结果# 进入analysis目录执行 cd analysis python behavior_cluster.py --min_session_gap 900 --max_sequence_length 10参数说明--min_session_gap 900会话分割阈值设为900秒15分钟超过此间隔视为新会话--max_sequence_length 10截断行为序列长度避免长尾噪声影响聚类输出文件output/session_clusters.csv包含session_id,uid,cluster_label,behavior_sequence四列其中cluster_label为KMeans聚类结果0~4共5类。3.4 启动Flask服务并访问仪表盘# 返回根目录 cd .. # 设置环境变量Windows用setMac/Linux用export export FLASK_APPapp.py export FLASK_ENVproduction flask run --host0.0.0.0 --port5000打开浏览器访问http://localhost:5000首页即显示交互式仪表盘。点击右上角搜索框输入223333页面自动加载左侧UP主头像、等级、注册时间、粉丝数中部其粉丝的行为热力图X轴为小时Y轴为星期几颜色深浅代表该时段互动量右侧TOP5行为序列如[watch,like]占比32%、[watch,coin,share]占比18%。提示热力图数据来自analysis/heatmap_generator.py它读取user_interactions表中uid在223333粉丝列表内的记录按HOUR(timestamp)和WEEKDAY(timestamp)分组聚合COUNT(*)再用PyEcharts的HeatMap组件渲染。4. 避坑指南我在本地复现时踩过的5个真实坑点这套系统虽已封装但在不同环境部署时仍存在几个隐蔽断点。以下是我在Windows 11 WSL2 Ubuntu 22.04 macOS Sonoma三台机器上反复验证后确认的避坑清单每一条都对应真实报错日志。4.1 MySQL连接失败pymysql.err.OperationalError: (1045, Access denied for user rootlocalhost)现象运行main_crawler.py时报错无法连接数据库即使密码正确。原因MySQL 8.0默认认证插件改为caching_sha2_password而PyMySQL旧版本1.0不兼容。解决升级PyMySQL并重置用户认证方式pip install --upgrade pymysql mysql -u root -p -e ALTER USER rootlocalhost IDENTIFIED WITH mysql_native_password BY your_password; FLUSH PRIVILEGES;4.2 B站API返回空数据KeyError: data或{code: -412, message: 请求被拦截}现象main_crawler.py运行后users表为空日志显示HTTP 412错误。原因B站近期加强了Referer和X-Requested-With头校验原包中部分API调用缺失X-Requested-With头。解决在crawler/utils.py的get_headers()函数中确保返回字典包含return { User-Agent: random.choice(USER_AGENTS), Referer: https://www.bilibili.com/, X-Requested-With: XMLHttpRequest, # 此行必须添加 Cookie: # 保持为空不依赖登录态 }4.3 时间字段类型冲突DataError: Packet sequence number wrong或Truncated incorrect datetime value现象执行INSERT INTO user_interactions时MySQL报错提示时间格式错误。原因user_interactions.timestamp字段定义为DATETIME但Python中datetime.now()生成的微秒级时间戳如2024-03-15 14:22:33.123456超出MySQL DATETIME精度仅支持秒级。解决在crawler/data_processor.py的插入逻辑中将时间对象截断到秒# 替换原代码中的 timestamp datetime.now() timestamp datetime.now().replace(microsecond0) # 强制去除微秒4.4 PyEcharts图表不渲染页面空白或显示Loading...现象Flask服务启动成功但http://localhost:5000打开后仪表盘区域为空白浏览器控制台报echarts is not defined。原因PyEcharts 2.0版本默认使用CDN加载ECharts JS而离线环境无法访问https://cdn.jsdelivr.net/npm/echarts5.4.3。解决在templates/index.html中将PyEcharts生成的JS代码块前添加本地JS引用script src{{ url_for(static, filenameecharts.min.js) }}/script !-- 下载echarts.min.js放入static/目录 --并在app.py中禁用CDNfrom pyecharts.globals import CurrentConfig CurrentConfig.ONLINE_HOST # 空字符串表示禁用CDN4.5 Flask路由404访问/api/user/223333返回Not Found现象前端搜索框输入UID后Network面板显示GET /api/user/223333返回404。原因Flask默认不启用url_for的绝对URL且app.py中API路由未加/api前缀。解决检查app.py中路由定义确保为app.route(/api/user/int:uid) # 必须含int:uid类型转换 def get_user(uid): # ...业务逻辑并确认前端AJAX请求URL拼接正确如fetch(/api/user/ uid)而非fetch(api/user/ uid)。5. 进阶技巧如何用现有代码快速扩展「B站充电行为分析」模块毕业设计常被问“这个系统还能分析什么”与其重写一套不如基于现有架构快速嫁接新维度。我以B站充电行为Bilibili Charge分析为例展示如何在2小时内新增一个可演示的功能模块——这不仅是加分项更是你证明工程能力的关键证据。5.1 数据采集层扩展复用Requests框架抓取充电记录B站充电数据可通过UP主主页的/x/space/upstat接口获取需UP主UID。我们复用crawler/main_crawler.py的请求模板新增charge_crawler.py# crawler/charge_crawler.py import requests from crawler.utils import get_headers from database.db_connector import get_db_connection def fetch_charge_data(uid): 获取UP主充电数据 url fhttps://api.bilibili.com/x/space/upstat?mid{uid} try: resp requests.get(url, headersget_headers(), timeout10) data resp.json() if data.get(code) 0: charge_info data[data][charge] # 返回字典{ total_coin: 12345, month_coin: 678, day_coin: 42 } return charge_info else: print(fCharge API error for UID {uid}: {data.get(message)}) return None except Exception as e: print(fRequest failed for UID {uid}: {e}) return None def save_charge_to_db(uid, charge_data): 保存充电数据到数据库 conn get_db_connection() cursor conn.cursor() # 新增表 charge_stats (uid, total_coin, month_coin, day_coin, update_time) sql INSERT INTO charge_stats (uid, total_coin, month_coin, day_coin, update_time) VALUES (%s, %s, %s, %s, NOW()) ON DUPLICATE KEY UPDATE total_coinVALUES(total_coin), month_coinVALUES(month_coin), day_coinVALUES(day_coin), update_timeVALUES(update_time) cursor.execute(sql, (uid, charge_data[total_coin], charge_data[month_coin], charge_data[day_coin])) conn.commit() cursor.close() conn.close() if __name__ __main__: target_uid 223333 charge_data fetch_charge_data(target_uid) if charge_data: save_charge_to_db(target_uid, charge_data) print(fCharge data saved for UID {target_uid})关键点复用get_headers()保证请求头一致性使用ON DUPLICATE KEY UPDATE避免重复插入charge_stats.uid设为UNIQUE KEYupdate_time用NOW()确保时间戳准确无需Python生成。5.2 数据库扩展新增charge_stats表并建立关联在database/bilibili_user_behavior.sql末尾追加-- 充电统计表 CREATE TABLE charge_stats ( id INT NOT NULL AUTO_INCREMENT, uid BIGINT NOT NULL COMMENT UP主UID, total_coin INT DEFAULT 0 COMMENT 历史总充电数, month_coin INT DEFAULT 0 COMMENT 本月充电数, day_coin INT DEFAULT 0 COMMENT 今日充电数, update_time DATETIME NOT NULL COMMENT 更新时间, PRIMARY KEY (id), UNIQUE KEY uid (uid), CONSTRAINT fk_charge_uid FOREIGN KEY (uid) REFERENCES users (uid) ON DELETE CASCADE ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;执行后users表与charge_stats形成1:1强关联SELECT u.name, c.total_coin FROM users u JOIN charge_stats c ON u.uidc.uid WHERE u.uid223333即可查出UP主名称与总充电数。5.3 分析层扩展计算充电转化率并加入仪表盘在analysis/charge_analyzer.py中实现核心逻辑import pandas as pd from database.db_connector import execute_query def calculate_charge_conversion(): 计算充电转化率充电人数 / 总粉丝数 # SQLJOIN users, charge_stats, 和粉丝关系表假设fans表存在 sql SELECT u.uid, u.name, c.total_coin, COUNT(f.fan_uid) as fan_count, ROUND(c.total_coin / COUNT(f.fan_uid) * 100, 2) as conversion_rate FROM users u JOIN charge_stats c ON u.uid c.uid LEFT JOIN fans f ON u.uid f.up_uid GROUP BY u.uid, u.name, c.total_coin HAVING fan_count 0 ORDER BY conversion_rate DESC LIMIT 10 df execute_query(sql) return df.to_dict(records) if __name__ __main__: result calculate_charge_conversion() print(Top 10 UP主充电转化率:) for r in result: print(f{r[name]} ({r[uid]}): {r[conversion_rate]}%)参数说明conversion_rate定义为总充电数 / 粉丝总数 × 100%反映UP主对粉丝的变现效率HAVING fan_count 0过滤掉无粉丝的UP主避免除零错误结果直接返回字典列表供Flask API调用。5.4 服务层扩展新增API并集成到前端在app.py中添加路由app.route(/api/charge/top10) def get_top_charge_conversion(): from analysis.charge_analyzer import calculate_charge_conversion data calculate_charge_conversion() return jsonify({success: True, data: data})在templates/index.html的仪表盘区域下方新增一个卡片div classcard h3充电转化率TOP10/h3 div idcharge-chart styleheight:300px;/div /div script // 在原有echarts初始化后追加 fetch(/api/charge/top10) .then(r r.json()) .then(data { const chart echarts.init(document.getElementById(charge-chart)); const names data.data.map(d d.name); const rates data.data.map(d d.conversion_rate); chart.setOption({ tooltip: {}, xAxis: { type: category, data: names }, yAxis: { type: value }, series: [{ type: bar, data: rates }], title: { text: UP主充电转化率% } }); }); /script从创建新爬虫脚本、建表、写分析逻辑到前端渲染全程未改动原有代码结构所有新增文件均放在对应模块目录下。这种模块化扩展能力正是答辩时老师最想看到的工程素养——你不是在交一份代码而是在交付一个可持续演进的分析平台。从那以后我每次带学生做毕设都会先让他们用这份B站行为分析系统跑通全流程再讨论“你想分析什么新维度”。因为只有亲手填过user_interactions表的每一行、调过/api/user/{uid}的每一次返回、改过behavior_cluster.py里的聚类参数才会真正理解数据链路里哪个环节最脆弱、哪个设计决策最影响后续扩展。希望帮到你。本文还有配套的精品资源点击获取
RELATED

相关推荐

风电单机点位数据的工程级应用与三表清洗实践

风电单机点位数据的工程级应用与三表清洗实践

简介:本资源是一份全国范围的风电设施空间分布数据集,面向GIS工程师、能源规划师、地理信息科研人员及遥感与空间分析学习者,用于支撑风能资源评估、电网布局优化、环境影响模拟等专业场景。数据源自OpenStreetMap(OSM&#xff09…

📅 2026/10/3 4:16:38
OpenShell:集成SSH会话管理与多主机分组的终端工作台

OpenShell:集成SSH会话管理与多主机分组的终端工作台

很多人看到“OpenShell”这个名字,第一反应以为是给传统 Shell(比如 Bash、Zsh)加了个开源外壳,或者是个什么命令行美化工具。其实它更像是一个“终端工作台”:把终端模拟器、SSH 会话管理、多主机分组、标签页组织这些…

📅 2026/10/3 4:16:38
AGV智能仿真系统v7.0:多机协同调度与死锁预防实战

AGV智能仿真系统v7.0:多机协同调度与死锁预防实战

简介:RCS-Lite AGV智能仿真系统v7.0是一套面向物流与制造自动化领域的专业仿真工具,适合AGV调度算法学习者、课程设计开发者及系统规划人员使用。它基于Python与PyQt5构建,可模拟电量管理、订单调度、死锁检测与避让等核心流程,帮…

📅 2026/10/3 4:11:38
MORE NEWS

更多资讯

📰

脉搏血氧测量原理与方法深度解析

1. 这不是“测个血氧”那么简单:为什么你看到的98%和实际临床价值可能差着一个呼吸周期“脉搏血氧测量”这六个字,现在几乎成了家用健康设备的标配标签——智能手表抬手一扫、指夹式探头咔哒一扣、医院监护仪上跳动的数字……看起来简单到不需要说明书。…

📰

PHP分治算法实战指南:从二分查找到归并排序的性能优化

在PHP里聊算法,很多人第一反应是"业务用不上"。我做PHP开发八年,写过电商、爬虫、报表系统,坦白说分治算法在业务代码里的出场率确实不高,但每次真正用到,都能解决别的思路搞不定的问题:几十万行…

📰

GPT-6降价与Opus 5.5上线后,如何用AI网关丝滑调用多模型

1. 多模型调用这件事,为什么突然成了刚需前阵子圈子里聊得最多的两件事,一个是 GPT-6 的价格直接腰斩,另一个是 Opus 5.5 正式上线。单看每一条都是常规的模型迭代新闻,但把这两件事放在一起看,味道就完全不一样了——…

📰

ConcurrentDictionary实战:底层原理、避坑与性能调优

做后端三年的人一定用锁过Dictionary,但锁的粒度怎么选、死锁怎么避、吞吐量上不去怎么办,这些问题绕到最后都会指向同一个名字:ConcurrentDictionary。这篇文章不打算抄 MSDN,也不打算列一份 API 大全,而是把我在生产…

📰

Claude Code 安装配置与首次代码修改实战指南

1. 为什么我最终把 Claude Code 装进了日常工作流第一次听说 Claude Code 的时候,我其实没太当回事。命令行里跑一个 AI 助手,听起来像是极客的玩具,跟"提升开发效率"这种正经事沾不上边。直到有一次我需要在一个十几万行的老项目里…

📰

Python实现KMeans聚类算法:源码、数据集与实战避坑指南

简介:这份资源面向机器学习入门者与数据挖掘方向的学习者,提供了一套用Python实现的KMeans聚类算法完整方案,可用于理解聚类分析从数据预处理、核心算法执行到结果可视化的全流程,适合作为课程实验、算法练习或项目参考的实践素材…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬