一个基于 Python 标准库实现的 B 站下载器,支持输入普通视频 BV / 完整视频链接、番剧 ss / ep 链接,或 b23.tv 短链后自动下载。
当前版本支持普通视频和可直接返回媒体流的番剧内容;不会绕过登录、会员、地区或 DRM 限制。对于当前账号不可完整播放的番剧剧集,程序会在列表里自动隐藏。
- 输入
BV号或完整链接后自动解析视频页 - 自动提取页面里的播放信息并下载媒体流
- 默认下载 DASH 视频流和音频流,再调用
ffmpeg合并成单个mp4 - 支持列出并选择当前视频可用画质,不同视频可用画质会不同
- 支持解析多 P 视频,可列出分 P、下载指定 P、按组合选择多个分 P,或一键下载全部分 P
- 支持解析番剧 season / episode 链接,可列出当前账号可下载的剧集并按组合选择
- 大文件默认自动使用分片多线程下载,适合更高码率和更大体积的视频
- 支持断点续传;中途中断后再次执行会尽量继续下载,而不是从零开始
- 支持批量下载多个 BV / 链接,也支持从文本文件批量导入
- 下载过程中会显示实时速度和预计剩余时间
- 如果系统没有
ffmpeg,程序会自动降级为仅下载原始.m4s文件 - 支持保存项目本地 Cookie,命令行和 GUI 共用
- 命令行与图形界面统一从
main.py进入
用浏览器实际打开公开视频页和番剧页后,可以观察到两类关键数据:
- 页面 HTML 中存在
window.__INITIAL_STATE__- 里面能拿到
aid、bvid、cid、标题、分 P 信息等元数据。
- 里面能拿到
- 页面 HTML 中存在
window.__playinfo__- 里面的
data.dash.video和data.dash.audio提供临时媒体地址。 - 浏览器实际播放时,会继续访问
https://api.bilibili.com/x/player/wbi/v2?...获取或刷新播放信息。
- 里面的
- 媒体文件本身通常是 DASH 形式
- 视频和音频分开下载,扩展名一般是
.m4s。 - 最终需要借助
ffmpeg无损封装成mp4。
- 视频和音频分开下载,扩展名一般是
普通视频主要复用页面中直接下发的播放信息;番剧则直接调用公开的 PGC 接口获取剧集列表和播放信息。
这份下载器不会去逆向 DRM,也不会绕过会员/付费限制;它只是复用当前账号真实可访问的播放信息。
bilibili_downloader.py:下载核心和命令行实现gui.py:图形界面实现main.py:统一入口,按参数分发到命令行或 GUI
- Python 3.10+
- 可选:
ffmpeg,用于自动合并音视频为单个mp4
程序会按下面顺序查找 ffmpeg:
- 环境变量:
FFMPEG、FFMPEG_PATH、FFMPEG_HOME、IMAGEIO_FFMPEG_EXE - 系统
PATH - 常见 Windows 安装目录,例如:
C:\ffmpegC:\ffmpeg\binC:\Program Files\ffmpegC:\Program Files\ffmpeg\binC:\Program Files (x86)\ffmpegC:\ProgramData\chocolatey\binScoop/WinGet常见安装位置
只有在这些位置都找不到时,才会自动降级为保留原始 .m4s 音视频流。
确认 ffmpeg 是否可用:
ffmpeg -versionpython main.py BV1E8fmB5EvW
python main.py "https://www.bilibili.com/video/BV1rKzPBGESv/"
python main.py "https://www.bilibili.com/video/BV1xxxxxxx/?p=2"
python main.py "https://www.bilibili.com/bangumi/play/ss68627"
python main.py "https://www.bilibili.com/bangumi/play/ep1193810"输出目录默认是当前目录下的 downloads/。
python main.py BV1E8fmB5EvW -o output
python main.py BV1E8fmB5EvW --info
python main.py BV1E8fmB5EvW --list-qualities
python main.py BV1E8fmB5EvW --quality 64
python main.py BV1E8fmB5EvW --quality lowest
python main.py BV1E8fmB5EvW --threads 16
python main.py BV1Zs411478q --list-pages
python main.py BV1Zs411478q -p 3 --quality 32
python main.py BV1Zs411478q --all-pages --quality 16
python main.py BV1Zs411478q --items 1,3,5
python main.py BV1E8fmB5EvW BV1rKzPBGESv
python main.py --input-file .\links.txt --quality best --threads 16
python main.py BV1E8fmB5EvW --no-merge
python main.py BV1E8fmB5EvW --cookie "SESSDATA=...; bili_jct=..."
python main.py BV1E8fmB5EvW --cookie-file .\cookie.txt
python main.py --cookie "SESSDATA=...; bili_jct=..." --save-cookie
python main.py --clear-saved-cookie
python main.py "https://www.bilibili.com/bangumi/play/ss68627" --list-items
python main.py "https://www.bilibili.com/bangumi/play/ss68627" --items 1,2--info:只解析,不下载--list-pages/--list-items:列出当前链接可下载的分 P 或剧集--list-qualities:列出当前视频或剧集可用画质--page:选择指定分P,例如-p 3--items:按序号选择多个分P或剧集,例如1,3,5-7--all-pages:下载该视频全部分P--quality:选择画质,支持best、lowest或具体 ID(如80、64、32)--threads:设置下载线程数,默认8,大文件会自动走分片并发下载--input-file:从文本文件批量读取链接或 BV,每行一个--no-merge:不调用ffmpeg合并--keep-temp:合并成功后保留原始.m4s--cookie/--cookie-file:临时使用指定 Cookie--save-cookie:把本次 Cookie 保存到项目本地.bilibili_downloader/cookie.txt--clear-saved-cookie:删除项目本地保存的 Cookie
links.txt:
BV1E8fmB5EvW
https://www.bilibili.com/video/BV1rKzPBGESv/
python main.py BV1Zs411478q --list-pages
python main.py "https://www.bilibili.com/video/BV1Zs411478q?p=3" --info
python main.py BV1Zs411478q -p 3 --quality 32
python main.py BV1Zs411478q --items 1,3,5
python main.py BV1Zs411478q --all-pages --threads 8python main.py "https://www.bilibili.com/bangumi/play/ss68627" --list-items
python main.py "https://www.bilibili.com/bangumi/play/ss68627" --info
python main.py "https://www.bilibili.com/bangumi/play/ss68627" --items 1,2
python main.py "https://www.bilibili.com/bangumi/play/ep1193810" --list-qualitiespython main.py --cookie "SESSDATA=...; bili_jct=..." --save-cookie
python main.py "https://www.bilibili.com/bangumi/play/ss68627" --list-items
python main.py --clear-saved-cookiepython main.py -gui打开后可在输入框中每行填一个 BV、完整视频链接,或番剧 ss/ep 链接实现批量下载;单个链接时可先点“解析画质”查看当前支持的画质和分 P / 剧集,再多选需要的项目,或勾选“下载全部项目”;Cookie 也可以直接在界面里保存和清空。
- 不支持 DRM 内容
- 不保证兼容未来页面结构变更
- 播放地址是临时地址,解析后应尽快下载
- 高画质、会员内容、地区限制内容可能需要你自己的登录态,当前版本不做绕过;对当前账号不可完整播放的番剧剧集会自动隐藏
我实际查看过以下公开页面,二者都能在页面中直接拿到 __INITIAL_STATE__ 和 __playinfo__:
对应播放阶段还能看到对下面接口的访问: