Python自动化实战:200行代码打造B站UP主数据监控助手 1. 项目概述与核心价值最近在和一些做B站内容的朋友聊天发现他们每天都要手动打开B站创作中心好几次就为了看那几个关键数据视频播放量涨了多少粉丝数有没有变化互动数据怎么样。这事儿听起来简单但日复一日地重复不仅浪费时间还容易打断创作时的“心流”状态。作为一个喜欢用代码解决重复劳动的程序员我就在想能不能写个小工具把这些数据直接“搬”到桌面上一目了然于是就有了这个“B站UP主小助手”的想法。它的核心功能很简单用Python写一个脚本定期自动获取并显示指定UP主的视频播放数、粉丝数等关键数据。你别看功能简单背后涉及到的技术点可不少从网络请求、数据解析到本地存储、定时任务再到最后打包成一个谁都能用的exe文件每一步都有值得琢磨的地方。我花了点时间用大约200行代码实现了核心功能今天就把整个思路、踩过的坑和最终方案完整地分享出来。无论你是刚学Python想找个实战项目练手还是本身就是UP主想解放双手这篇文章都能给你提供一条清晰的实现路径。2. 整体设计与技术选型在动手写代码之前得先把整个项目的骨架搭好。我们的目标是做一个能稳定运行、数据准确、并且对使用者友好的小工具。这意味着我们不能只写一个一次性运行的脚本而是要考虑到持续运行、错误处理以及最终交付的便利性。2.1 核心需求拆解首先我们把“显示视频播放数、粉丝数”这个模糊的需求具体化数据获取必须能从B站公开的接口或页面稳定地获取到指定UP主的粉丝数、最新视频的播放/点赞/投币/收藏数。数据展示获取到的数据需要以一种直观的方式呈现出来比如在命令行窗口显示或者更友好一点在系统托盘显示一个实时数字。自动更新数据不能只获取一次需要能按照设定的时间间隔比如每10分钟自动刷新确保看到的是最新数据。配置简化对于最终使用者可能是不懂编程的UP主最好只需要输入自己的B站UID然后双击一个exe文件就能运行。稳定与容错网络可能不稳定B站的接口也可能变化程序需要有基本的错误处理和重试机制不能动不动就崩溃。2.2 技术栈选择与理由基于以上需求我选择了以下技术组合并解释一下为什么这么选Python 3.8这是我们的主力语言。选择Python是因为它在数据处理、网络请求和快速原型开发上效率极高有丰富的第三方库支持非常适合这种小型自动化工具。3.8是一个比较稳定且普及的版本能兼顾库的兼容性和新特性。Requests库用于发送HTTP请求到B站接口。这是Python生态中处理网络请求的“事实标准”简单易用且功能强大。相比于Python自带的urllibRequests的API更加人性化。BeautifulSoup4 或 直接解析JSON用于解析从B站获取到的数据。B站的数据接口通常返回JSON格式直接用json库解析即可。但如果某些数据需要从HTML页面中抓取虽然不推荐作为备选BeautifulSoup4是解析HTML/XML的利器。Schedule库用于实现定时任务。我们需要程序每隔一段时间自动执行数据获取函数。虽然可以用time.sleep()加循环来实现但schedule库提供了更优雅、更易读的定时任务声明方式例如schedule.every(10).minutes.do(job)。PyInstaller用于将Python脚本打包成独立的Windows可执行文件.exe。这是让工具能交付给非技术用户的关键一步。它能把Python解释器、脚本以及所有依赖库打包在一起生成一个“开箱即用”的程序。Tkinter 或 PyQt5 (可选)如果我们希望做一个有图形界面GUI的小窗口来显示数据而不是只用命令行就需要用到GUI库。Tkinter是Python自带的无需额外安装但界面比较简陋。PyQt5功能强大、界面美观但打包后的体积会大很多。为了保持“200行代码”的简洁性和核心目标是“显示数据”我首选命令行输出并会介绍如何用系统托盘图标这种更轻量、更不打扰人的方式作为进阶方案。注意在数据获取方式上务必遵守网站规则。我们的目标是获取公开的、非敏感的数据如UP主主页的公开信息并且要控制请求频率避免对B站服务器造成压力这既是道德要求也能保证我们工具的长期稳定运行。绝对不要尝试破解或高频请求需要登录才能访问的接口。3. 核心实现步骤详解接下来我们进入实操环节。我会把整个开发过程拆解成几个关键步骤并附上详细的代码和解释。3.1 第一步环境准备与依赖安装工欲善其事必先利其器。首先确保你的电脑上安装了Python。打开命令行CMD或PowerShell输入python --version检查版本确保是3.8或以上。然后我们创建一个新的项目文件夹比如叫bilibili_up_assistant并在里面创建一个requirements.txt文件列出我们需要的库requests2.28.0 schedule1.2.0 # 如果计划用BeautifulSoup解析HTML可以加上 # beautifulsoup44.11.0 # 如果计划打包可以暂时不安装打包时会自动处理接着在命令行中进入项目目录使用pip安装这些依赖cd path/to/bilibili_up_assistant pip install -r requirements.txt如果你习惯使用虚拟环境强烈推荐可以避免不同项目间的库版本冲突可以这样操作# 创建虚拟环境 python -m venv venv # 激活虚拟环境 (Windows) venv\Scripts\activate # 激活虚拟环境 (macOS/Linux) # source venv/bin/activate # 然后在激活的虚拟环境中安装依赖 pip install -r requirements.txt3.2 第二步探索与获取B站数据接口这是最关键也最具挑战性的一步。我们需要找到B站提供UP主公开数据的接口。最直接的方式是分析B站网页的请求。打开开发者工具用Chrome或Edge浏览器打开一位UP主的主页例如https://space.bilibili.com/123456123456是UID。按F12打开开发者工具切换到“网络”(Network)标签页。寻找数据请求刷新页面在网络请求列表中筛选XHR或Fetch类型的请求。你会看到很多请求我们需要寻找那些返回了粉丝数、视频信息等数据的请求。分析接口经过查找B站通常有一个接口格式类似https://api.bilibili.com/x/space/acc/info?mid123456这个接口返回了UP主的基本信息其中就包含follower粉丝数。另一个接口类似https://api.bilibili.com/x/space/arc/search?mid123456ps30这个接口返回了UP主的视频列表里面包含了每个视频的播放量(play)、点赞(like)、投币(coin)、收藏(favorite)等数据。验证接口你可以直接把这个接口地址复制到浏览器地址栏访问看看返回的JSON数据是否包含你需要的信息。实操代码示例获取UP主粉丝数我们创建一个名为bilibili_api.py的文件编写数据获取函数import requests import json import time def get_up_info(uid): 根据B站UID获取UP主基本信息含粉丝数 :param uid: B站用户UID字符串或数字 :return: 包含粉丝数等信息的字典出错时返回None # 构造请求头模拟浏览器访问降低被拒绝的风险 headers { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36, Referer: fhttps://space.bilibili.com/{uid} # 添加来源页更符合正常访问行为 } # 粉丝数等信息接口 info_url fhttps://api.bilibili.com/x/space/acc/info?mid{uid} try: # 发送GET请求设置超时时间 response requests.get(info_url, headersheaders, timeout10) response.raise_for_status() # 如果状态码不是200抛出HTTPError异常 data_json response.json() # 检查B站接口返回的code0表示成功 if data_json.get(code) 0: data data_json.get(data, {}) # 提取我们需要的信息 up_info { name: data.get(name, N/A), uid: uid, follower: data.get(follower, 0), # 粉丝数 face: data.get(face, ), # 头像 level: data.get(level, 0), # 等级 } return up_info else: print(f接口返回错误: {data_json.get(message)}) return None except requests.exceptions.RequestException as e: print(f网络请求失败: {e}) return None except json.JSONDecodeError as e: print(fJSON解析失败: {e}) return None # 测试函数 if __name__ __main__: # 替换成你想查询的UP主UID例如“老师好我叫何同学”的UID是“20165629” test_uid 20165629 info get_up_info(test_uid) if info: print(fUP主: {info[name]}) print(fUID: {info[uid]}) print(f粉丝数: {info[follower]}) print(f等级: {info[level]}) else: print(获取信息失败)关键点解析User-Agent这是告诉服务器我们是什么客户端在访问。使用一个常见的浏览器UA可以避免被一些简单的反爬机制拦截。Referer表示请求是从哪个页面发起的。添加这个头信息让请求看起来更像是由用户点击触发的正常行为。异常处理网络请求充满了不确定性必须用try...except包裹。我们捕获了请求异常和JSON解析异常这样即使网络波动或接口格式变化程序也不会直接崩溃而是给出错误提示。超时设置timeout10表示如果10秒内没有收到响应就认为请求失败。这可以防止程序在糟糕的网络环境下无限期等待。3.3 第三步获取视频播放数据获取了UP主基本信息我们还需要其视频的播放数据。我们修改bilibili_api.py增加获取视频列表的函数。def get_video_list(uid, page_size5): 获取UP主最新的视频列表及播放数据 :param uid: B站用户UID :param page_size: 获取最新的几条视频默认5条 :return: 视频信息列表出错返回空列表 headers { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36, Referer: fhttps://space.bilibili.com/{uid} } # 视频列表接口pn是页码ps是每页数量 video_url fhttps://api.bilibili.com/x/space/arc/search?mid{uid}pn1ps{page_size} try: response requests.get(video_url, headersheaders, timeout10) response.raise_for_status() data_json response.json() if data_json.get(code) 0: vlist data_json.get(data, {}).get(list, {}).get(vlist, []) video_info_list [] for video in vlist: video_info { aid: video.get(aid), # 视频AV号 bvid: video.get(bvid), # 视频BV号 title: video.get(title), play: video.get(play), # 播放量 like: video.get(like), # 点赞 coin: video.get(coin), # 投币 favorite: video.get(favorite), # 收藏 created: video.get(created), # 发布时间戳 } video_info_list.append(video_info) return video_info_list else: print(f获取视频列表失败: {data_json.get(message)}) return [] except requests.exceptions.RequestException as e: print(f获取视频列表请求失败: {e}) return [] except json.JSONDecodeError as e: print(f视频列表JSON解析失败: {e}) return [] # 整合测试 if __name__ __main__: test_uid 20165629 print( UP主基本信息 ) info get_up_info(test_uid) if info: print(f名称: {info[name]}) print(f粉丝数: {info[follower]}) print(\n 最新视频数据 ) videos get_video_list(test_uid, 3) # 获取最新3条 for idx, video in enumerate(videos, 1): print(f视频{idx}: {video[title][:30]}...) # 只显示前30个字符 print(f 播放: {video[play]} | 点赞: {video[like]} | 投币: {video[coin]} | 收藏: {video[favorite]})现在我们已经有了两个核心函数可以分别获取UP主的粉丝数和最新视频的播放数据了。3.4 第四步构建主程序与定时任务数据获取功能有了接下来我们要让程序“活”起来能够定时执行这些任务并把结果清晰地展示出来。我们创建一个新的主程序文件main.py。import schedule import time from datetime import datetime from bilibili_api import get_up_info, get_video_list # 全局配置 TARGET_UID 20165629 # 替换为你要监控的UP主UID UPDATE_INTERVAL_MINUTES 10 # 更新间隔分钟 def fetch_and_display_data(): 核心任务获取数据并打印到控制台 current_time datetime.now().strftime(%Y-%m-%d %H:%M:%S) print(f\n[{current_time}] 开始获取数据...) # 1. 获取UP主信息 up_info get_up_info(TARGET_UID) if not up_info: print( 获取UP主信息失败跳过本次更新。) return # 2. 获取视频列表 video_list get_video_list(TARGET_UID, 3) # 获取最新3条 # 3. 格式化输出 print(f UP主: {up_info[name]} (UID: {TARGET_UID})) print(f 粉丝数: {up_info[follower]}) print(f 等级: Lv{up_info[level]}) if video_list: latest_video video_list[0] # 最新的视频 print(f 最新视频: 《{latest_video[title][:40]}...》) print(f 播放: {latest_video[play]} | 点赞: {latest_video[like]} | 投币: {latest_video[coin]} | 收藏: {latest_video[favorite]}) # 计算最近3条视频的总播放量可选 total_play sum(v[play] for v in video_list if v[play]) print(f 近3条视频总播放量: {total_play}) else: print( 未获取到视频数据。) print(f[{current_time}] 数据获取完成。) def main(): 主函数设置定时任务并运行 print( B站UP主小助手启动 ) print(f监控UID: {TARGET_UID}) print(f更新间隔: 每 {UPDATE_INTERVAL_MINUTES} 分钟) print( * 30) # 立即执行一次 fetch_and_display_data() # 设置定时任务每 UPDATE_INTERVAL_MINUTES 分钟执行一次 schedule.every(UPDATE_INTERVAL_MINUTES).minutes.do(fetch_and_display_data) print(f\n程序已启动将每{UPDATE_INTERVAL_MINUTES}分钟自动更新。按 CtrlC 终止程序。\n) # 保持程序运行并检查定时任务 try: while True: schedule.run_pending() time.sleep(1) # 每秒检查一次避免CPU空转 except KeyboardInterrupt: print(\n\n程序被用户中断。再见) if __name__ __main__: main()运行与效果 在命令行中运行python main.py你会看到程序立即获取一次数据并打印出来然后每隔10分钟根据UPDATE_INTERVAL_MINUTES设置自动执行一次。输出格式清晰包含了时间戳、UP主信息和最新视频数据。实操心得schedule库的run_pending()需要在一个循环中不断调用time.sleep(1)让循环每秒检查一次这是一个非常经典且低耗能的模式。千万不要用time.sleep(60 * UPDATE_INTERVAL_MINUTES)来代替因为那样会阻塞进程无法响应其他事件比如未来的GUI事件。4. 进阶优化与功能扩展基础功能已经实现但要让这个小工具更实用、更健壮我们还需要做一些优化。4.1 增加数据持久化与简单分析目前数据只在控制台显示关掉就没了。我们可以增加一个简单的日志功能把每次获取的数据记录到CSV文件里方便后续查看趋势。在main.py中增加一个函数和修改fetch_and_display_dataimport csv import os LOG_FILE up_data_log.csv def log_to_csv(up_info, video_list): 将数据记录到CSV文件 file_exists os.path.isfile(LOG_FILE) current_time datetime.now().strftime(%Y-%m-%d %H:%M:%S) # 准备要记录的数据行 latest_video video_list[0] if video_list else {} row_data [ current_time, up_info.get(uid, ), up_info.get(name, ), up_info.get(follower, 0), latest_video.get(title, N/A)[:50], # 记录标题前50字符 latest_video.get(play, 0), latest_video.get(like, 0), latest_video.get(coin, 0), latest_video.get(favorite, 0), ] try: with open(LOG_FILE, a, newline, encodingutf-8-sig) as f: # utf-8-sig方便Excel直接打开 writer csv.writer(f) # 如果是新文件写入表头 if not file_exists: header [时间, UID, UP主, 粉丝数, 最新视频标题, 播放量, 点赞, 投币, 收藏] writer.writerow(header) writer.writerow(row_data) # print(f 数据已记录到 {LOG_FILE}) # 可选打印日志成功信息 except Exception as e: print(f 写入日志文件失败: {e}) # 然后在 fetch_and_display_data 函数的最后成功获取数据后调用日志函数 def fetch_and_display_data(): # ... [前面的获取数据代码不变] ... if up_info and video_list: # ... [前面的打印输出代码不变] ... # 记录到日志文件 log_to_csv(up_info, video_list)这样每次数据更新都会在up_data_log.csv文件中追加一行你可以用Excel打开轻松地绘制粉丝增长曲线或播放量变化图。4.2 实现系统托盘图标显示Windows对于希望工具更“隐形”、不占用任务栏或命令行窗口的用户系统托盘图标是一个完美的解决方案。我们可以使用pystray和Pillow库来实现。这会让代码量增加但用户体验提升巨大。首先安装额外依赖pip install pystray pillow然后创建一个新的文件tray_app.pyimport threading import time from datetime import datetime import pystray from PIL import Image, ImageDraw import schedule from bilibili_api import get_up_info, get_video_list # 配置 TARGET_UID 20165629 UPDATE_INTERVAL 10 # 分钟 class UpMonitorTray: def __init__(self): self.latest_data { name: 加载中..., follower: --, latest_play: --, update_time: -- } self.icon self.create_icon() self.running True def create_icon(self): 创建一个简单的托盘图标带字母‘B’ image Image.new(RGB, (64, 64), color#FB7299) # B站主题色 draw ImageDraw.Draw(image) # 在图标中央画一个白色的‘B’ draw.text((22, 16), B, fillwhite, fontNone) # 简单绘制 return image def update_data(self): 更新数据的线程函数 while self.running: try: info get_up_info(TARGET_UID) videos get_video_list(TARGET_UID, 1) if info and videos: self.latest_data[name] info.get(name, N/A) self.latest_data[follower] str(info.get(follower, 0)) self.latest_data[latest_play] str(videos[0].get(play, 0)) self.latest_data[update_time] datetime.now().strftime(%H:%M) # 更新托盘图标提示文本鼠标悬停时显示 self.update_tray_tooltip() else: self.latest_data[update_time] f{datetime.now().strftime(%H:%M)} (更新失败) except Exception as e: print(f数据更新出错: {e}) # 每隔指定分钟更新一次 time.sleep(UPDATE_INTERVAL * 60) def update_tray_tooltip(self): 更新鼠标悬停提示 tooltip_text ( fUP主: {self.latest_data[name]}\n f粉丝: {self.latest_data[follower]}\n f最新视频播放: {self.latest_data[latest_play]}\n f更新于: {self.latest_data[update_time]} ) # 注意pystray的icon对象需要在主线程更新这里需要一些线程同步处理 # 为了简化我们可以通过重新设置菜单项来间接更新见下文 pass def on_quit(self, icon, item): 退出菜单项的回调函数 self.running False icon.stop() def run(self): 运行托盘应用 # 创建菜单 menu ( pystray.MenuItem(fUP主: {self.latest_data[name]}, lambda: None, enabledFalse), pystray.MenuItem(f粉丝数: {self.latest_data[follower]}, lambda: None, enabledFalse), pystray.MenuItem(f最新播放: {self.latest_data[latest_play]}, lambda: None, enabledFalse), pystray.MenuItem(f更新时间: {self.latest_data[update_time]}, lambda: None, enabledFalse), pystray.Menu.SEPARATOR, pystray.MenuItem(退出, self.on_quit) ) icon pystray.Icon(bilibili_up_monitor, self.icon, B站UP主助手, menu) # 启动数据更新线程 update_thread threading.Thread(targetself.update_data, daemonTrue) update_thread.start() # 运行一个定时任务来刷新菜单显示因为菜单文本创建后是静态的 def refresh_menu(): new_menu ( pystray.MenuItem(fUP主: {self.latest_data[name]}, lambda: None, enabledFalse), pystray.MenuItem(f粉丝数: {self.latest_data[follower]}, lambda: None, enabledFalse), pystray.MenuItem(f最新播放: {self.latest_data[latest_play]}, lambda: None, enabledFalse), pystray.MenuItem(f更新时间: {self.latest_data[update_time]}, lambda: None, enabledFalse), pystray.Menu.SEPARATOR, pystray.MenuItem(退出, self.on_quit) ) icon.menu new_menu def schedule_refresh(): while self.running: schedule.every(1).minutes.do(refresh_menu) schedule.run_pending() time.sleep(1) refresh_thread threading.Thread(targetschedule_refresh, daemonTrue) refresh_thread.start() # 运行托盘图标 icon.run() if __name__ __main__: app UpMonitorTray() app.run()运行python tray_app.py你会在电脑右下角的系统托盘区看到一个粉色的“B”图标。鼠标悬停可以看到基本信息右键点击可以退出。数据会在后台自动更新。注意事项系统托盘程序涉及多线程数据获取、定时刷新、GUI事件循环编写时要特别注意线程安全。上面的示例是一个简化版本在实际使用中你可能需要使用线程锁threading.Lock来保护共享数据如latest_data或者使用queue.Queue在线程间传递数据更新事件以避免潜在的竞态条件。对于初学者如果觉得复杂坚持使用命令行版本是完全可行的。4.3 使用PyInstaller打包成EXE为了让不懂Python的朋友也能用上这个工具我们需要把它打包成一个独立的exe文件。PyInstaller是目前最常用的工具。安装PyInstallerpip install pyinstaller打包命令行版本 在项目根目录下打开命令行执行pyinstaller -F -w -i bilibili.ico main.py-F打包成单个exe文件。-w运行时不显示命令行窗口Windows Only。如果你希望看到打印的日志就不要加这个参数。-i bilibili.ico指定exe的图标文件需要准备一个.ico格式的图标。 执行完毕后会在dist文件夹里找到main.exe。把这个文件发给别人他双击就能运行前提是他的系统有基本的运行库通常Windows 10/11都自带。打包系统托盘版本pyinstaller -F -w -i bilibili.ico tray_app.py注意由于托盘版本依赖pystray和PillowPyInstaller可能会需要一些额外参数来正确打包这些库的依赖如图片文件。如果打包后运行报错可能需要查阅PyInstaller和相应库的文档使用--add-data参数手动添加资源文件。打包常见问题与解决文件体积大这是PyInstaller打包Python程序的通病因为它把Python解释器和所有依赖库都打包进去了。可以使用--exclude-module尝试排除一些不必要的大库但需谨慎。运行报错“Failed to execute script”通常是因为某些动态库或资源文件没有正确打包。可以在打包时去掉-w参数运行exe查看命令行输出的具体错误信息。更高级的调试可以使用--debug模式。防病毒软件误报这是另一个常见问题。PyInstaller打包的程序有时会被一些激进的杀毒软件误报为病毒。解决办法包括1) 使用PyInstaller的--key参数进行加密效果有限2) 向杀毒软件提交误报文件3) 使用代码签名证书对exe进行数字签名成本较高。对于个人小工具提前告知使用者“可能被误报请添加信任”是比较实际的方案。5. 常见问题排查与优化建议在实际开发和运行中你可能会遇到以下问题。这里我整理了一份排查清单和优化思路。5.1 网络请求失败或返回空数据问题现象可能原因排查与解决思路连接超时 (ConnectTimeout)网络不稳定或目标服务器暂时不可用。1. 检查本地网络。2. 在代码中增加重试机制见下文。3. 适当增加timeout参数。返回状态码非200 (如403, 404)接口地址已变更或请求头信息被识别为爬虫。1. 按本文3.2节的方法重新用浏览器开发者工具抓取最新的接口地址。2. 检查并更新headers特别是User-Agent和Referer使其更像真实浏览器。3. 如果接口需要登录才能访问非公开数据则此方法无效请勿尝试绕过。返回的JSON中code不为0B站接口返回的业务逻辑错误。打印出返回的message字段根据提示判断。常见原因UID不存在、请求频率过快被限制。返回数据为空列表或空字典接口正常但该UP主无视频或数据。检查UID是否正确以及UP主是否发布了视频。增加重试机制的代码示例import requests from requests.adapters import HTTPAdapter from urllib3.util.retry import Retry def create_session_with_retry(retries3, backoff_factor0.5): 创建一个带重试机制的requests Session session requests.Session() retry_strategy Retry( totalretries, backoff_factorbackoff_factor, # 重试等待时间{backoff factor} * (2 ** ({retry number} - 1)) status_forcelist[429, 500, 502, 503, 504], # 遇到这些状态码会重试 ) adapter HTTPAdapter(max_retriesretry_strategy) session.mount(http://, adapter) session.mount(https://, adapter) return session # 使用示例 session create_session_with_retry() try: response session.get(url, headersheaders, timeout10) # ... 处理response ... except requests.exceptions.RequestException as e: # 经过重试后仍然失败 print(f请求最终失败: {e})5.2 程序运行一段时间后崩溃或停止更新原因1内存泄漏不常见于小脚本确保在循环中没有不断创建不会被释放的大对象。原因2未捕获的异常导致线程退出特别是在系统托盘的多线程版本中务必用try...except包裹数据获取和处理的代码并将错误日志记录下来。原因3系统休眠/唤醒后定时器紊乱schedule库的定时是基于系统时间的如果电脑进入休眠唤醒后可能错过一些任务。一个更健壮的方法是使用while True循环配合time.sleep()和记录上次执行时间的方式来实现定时这样能保证唤醒后按间隔继续执行。5.3 如何监控多个UP主当前代码只监控一个UP主。要监控多个只需将TARGET_UID从一个字符串改为列表然后循环处理即可。TARGET_UIDS [20165629, 546195, 208259] # 何同学、老番茄、敖厂长 def fetch_all_data(): for uid in TARGET_UIDS: up_info get_up_info(uid) # ... 处理并显示或记录每个UP主的数据 ... # 注意在循环中最好加入短暂的延时避免短时间内对B站服务器发起大量请求。 time.sleep(1)5.4 想获取更多数据如评论数、弹幕数你需要找到对应的接口。例如视频的详细数据包含评论数、弹幕数通常有另一个接口如https://api.bilibili.com/x/web-interface/view?aidxxx或https://api.bilibili.com/x/web-interface/view?bvidxxx。同样通过浏览器开发者工具寻找。获取到数据后仿照get_video_list函数解析新的字段即可。最后一点个人体会这个项目虽然代码量不大但完整地走了一遍从需求分析、技术选型、编码实现、调试优化到最终打包交付的流程是一个非常好的Python综合练习。在实际操作中最大的挑战往往不是写代码而是处理各种边界情况网络错误、数据格式变化和让程序对用户更友好。当你看到自己写的小工具在后台默默工作为你或你的朋友提供便利时那种成就感是单纯学习语法无法比拟的。如果后续你想把它做得更强大可以考虑加入数据可视化用matplotlib画趋势图、设置图形化配置界面用PyQt5、甚至做成一个简单的Web服务路还很长乐趣也很多。