Bilibili.com(B站)视频下载工具
Project description
BiliUtil
Bilibili.com(B站)视频下载工具包,Github源码地址:https://github.com/wolfbolin/BiliUtil
若您在使用过程中发现BUG,请及时提交Issue或邮件(mailto@wolfbolin.com)与我联系。
声明:该内容仅供学习参 考,请勿用于商业目的
[TOC]
一、安装方式
- 请使用pip安装该包:
pip install BiliUtil
- 若使用视频下载功能,请自行安装配置
aria2
。 - 若使用视频合并功能,请自行安装配置
ffmpeg
。
工具包将自动检查aria2和ffmpeg环境,若任一环境不存在,所涉及的类与函数将不会被引入
二、使用方式
包中封装了始终对象,“UP主”(User)、“频道”(Channel)、“专辑”(Album)和“视频”(User),前三个对象是可以声明的,但是“视频”对象(Video)不可独立声明。
1、用户类(User)
该类表示了一个UP主,当需要获取某位UP主信息或UP的视频时,可以选择创建该类的实例。
1.1、成员变量
成员变量 | 变量含义 | 默认值 |
---|---|---|
cookie | 设置的cookie信息 | None |
uid | 用户uid | None |
name | 用户昵称 | None |
birthday | 用户生日 | None |
coin | 用户硬币量 | None |
face | 用户头像 | None |
time | 创号时间(可能为0) | None |
level | 用户级别 | None |
sex | 用户昵称 | None |
sign | 用户签名 | None |
album_list | 用户视频对象列表 | list() |
channel_list | 用户频道对象列表 | list() |
1.2、声明实例
你可以引入包并创建一个空的用户实例,空的用户实例不设置用户uid。
import BiliUtil
if __name__ == '__main__':
ua = BiliUtil.User()
1.3、设定用户uid
你可以通过多种方式设定用户uid,详见下方案例。
import BiliUtil
if __name__ == '__main__':
# 方案一
ua = BiliUtil.User(uid='4093899')
# 方案二
ua = BiliUtil.User()
ua.set_user(uid='4093899')
# 方案三
ua = BiliUtil.User()
ua.set_by_url(url='https://space.bilibili.com/4093899')
三种函数声明方式如下:
def __init__(self, uid=None)
def set_user(self, uid)
def set_by_url(self, url)
注:使用URL设定用户时,类似于https://space.bilibili.com/4093899/channel/index
的URL也可以被识别。
1.4、设定Cookie
设定的cookie信息会影响到该实例及其包含的所有自动创建的对象。
ua.set_cookie('SESSDATA=abcd68fd%2C1123761144%2C38d97xyz')
注:cookie设置的方式与意义详见第三章的解释。
1.5、获取用户信息
在设定用户uid信息后,即可通过该函数获取用户的基础信息。
对返回值(副本)进行的修改不会影响User对象内的数据。
返回值:字典数据(副本),用户基本信息
import BiliUtil
if __name__ == '__main__':
ua = BiliUtil.User(uid='4093899')
user_info = ua.get_user_info()
print(user_info)
1.6、获取所有视频列表
你可以仅获取视频列表而不下载视频,该操作将自动帮你完成用户信息的获取。
对返回值(副本)进行的修改不会影响User对象内的数据。
返回值:Album对象列表(副本),用户发布的所有视频。
import BiliUtil
if __name__ == '__main__':
ua = BiliUtil.User(uid='4093899')
all_video = ua.get_all_video_info()
1.7、获取所有视频数据
你可以直接下载UP主的全部视频,该操作将自动帮你完成用户信息的获取与视频列表的获取。该操作支持设定路径、命名方式、视频时长,当设置了适合的cookie时,下载的画质将会自动提升。
import BiliUtil
if __name__ == '__main__':
ua = BiliUtil.User(uid='4093899')
ua.get_all_video_data(base_path='Download', name_path=True, max_length=None)
注:参数设置的方式与意义详见第三章的解释。
1.8、获取已下载的视频
你可以通过该函数获取通过get_all_video_data()
下载的视频的AV号列表,由于该函数的工作方式与缓存目录的结构息息相关,因此函数的参数应与get_all_video_data函数参数保持一致。
返回值:AV号列表,用户发布的所有视频的AV号(不包含前缀av
)。
import BiliUtil
if __name__ == '__main__':
ua = BiliUtil.User()
ua.set_by_url('https://space.bilibili.com/6799052/')
exist_list = ua.get_channel_exist_list(base_path='Download', name_path=True)
print(exist_list)
注:参数设置的方式与意义详见第三章的解释。
1.9、获取所有视频AV号
你可以获取用户发布的所有视频的AV号,该操作将自动帮你完成所有视频列表的获取。
返回值:AV号列表,用户发布的所有视频的AV号(不包含前缀av
)。
import BiliUtil
if __name__ == '__main__':
ua = BiliUtil.User()
ua.set_by_url('https://space.bilibili.com/6799052/')
av_list = ua.get_all_video_av_list()
print(av_list)
1.10、获取用户频道列表
你可以仅获取频道列表而不下载视频,该操作将自动帮你完成用户信息的获取。
对返回值(副本)进行的修改不会影响User对象内的数据。
返回值:Channel对象列表(副本),用户的所有频道。
import BiliUtil
if __name__ == '__main__':
ua = BiliUtil.User(uid='4093899')
channel_list = ua.get_channel_video_info()
1.11、获取频道视频数据
你可以直接下载UP主的全部视频,该操作将自动帮你完成用户信息的获取与频道列表的获取。该操作支持设定路径、命名方式、视频时长,当设置了适合的cookie时,下载的画质将会自动提升。
import BiliUtil
if __name__ == '__main__':
ua = BiliUtil.User(uid='4093899')
ua.get_channel_video_data(base_path='Download', name_path=True, max_length=None)
注:参数设置的方式与意义详见第三章的解释。
1.12、获取已下载的视频
你可以通过该函数获取通过get_channel_video_data()
下载的视频的AV号列表,由于该函数的工作方式与缓存目录的结构息息相关,因此函数的参数应与get_channel_video_data函数参数保持一致。
返回值:AV号列表,用户发布的所有视频的AV号(不包含前缀av
)。
import BiliUtil
if __name__ == '__main__':
ua = BiliUtil.User()
ua.set_by_url('https://space.bilibili.com/6799052/')
exist_list = ua.get_channel_exist_list(base_path='Download', name_path=True)
print(exist_list)
注:参数设置的方式与意义详见第三章的解释。
1.13、获取对象信息字典
你可以将当前对象中保存的所有信息转换为字典格式保存,修改该字典时并不会影响实例。
import BiliUtil
if __name__ == '__main__':
ua = BiliUtil.User(uid='4093899')
ua.get_user_info() # 修改对象
print(ua.get_dict_info()) # 输出对象内部信息
ua.get_all_video_info() # 修改对象
print(ua.get_dict_info()) # 输出对象内部信息
ua.get_channel_video_info() # 修改对象
print(ua.get_dict_info()) # 输出对象内部信息
1.14、下载高清视频样例
import BiliUtil
if __name__ == '__main__':
cookie = input('请提供登录后的cookie信息,以升级下载画质:')
ua = BiliUtil.User()
ua.set_by_url('https://space.bilibili.com/6799052/')
ua.set_cookie(cookie)
ua.get_all_video_data(base_path='Download', name_path=True)
2、频道类(Channel)
该类表示了一个用户所属的频道,当需要获取频道内所有视频信息时,可以选择创建该类的实例。
2.1、成员变量
成员变量 | 变量含义 | 默认值 |
---|---|---|
cookie | 设置的cookie信息 | None |
uid | 用户uid | None |
cid | 频道cid | None |
name | 频道名称 | None |
cover | 频道封面 | None |
count | 频道内专辑数量 | None |
album_list | 频道内专辑对象列表 | list() |
2.2、声明实例
你可以引入包并创建一个空的频道实例,空的频道实例不设置用户uid和频道cid。
import BiliUtil
if __name__ == '__main__':
ch = BiliUtil.Channel()
2.3、设定频道cid
你可以通过多种方式设定用户uid与频道cid,详见下方案例。
import BiliUtil
if __name__ == '__main__':
# 方案一
ch = BiliUtil.Channel(uid='4093899', cid='8020')
# 方案二
ch = BiliUtil.Channel()
ch.set_user(uid='4093899', cid='8020')
# 方案三
ch = BiliUtil.Channel()
ch.set_by_url(url='https://space.bilibili.com/4093899/channel/detail?cid=8020')
三种函数声明方式如下:
def __init__(self, uid=None, cid=None)
def set_channel(self, uid, cid)
def set_by_url(self, url)
注:使用URL设定用户时,请使用准确的URL。
2.4、设定Cookie
设定的cookie信息会影响到该实例及其包含的所有自动创建的对象。
ch.set_cookie('SESSDATA=abcd68fd%2C1123761144%2C38d97xyz')
注:cookie设置的方式与意义详见第三章的解释。
2.5、获取频道信息
你可以仅获取频道信息以及视频列表而不下载视频。
对返回值(副本)进行的修改不会影响Channel对象内的数据。
返回值:字典数据(副本),频道基本信息
import BiliUtil
if __name__ == '__main__':
ch = BiliUtil.Channel(uid='4093899', cid='8020')
channel_info = ch.get_channel_info()
print(channel_info)
2.6、获取频道视频数据
你可以直接获取频道内视频数据,该操作将自动帮你完成频道信息的获取。该操作支持设定路径、命名方式、视频时长,当设置了适合的cookie时,下载的画质将会自动提升。
import BiliUtil
if __name__ == '__main__':
ch = BiliUtil.Channel(uid='4093899', cid='8020')
ch.get_channel_data(base_path='Download', name_path=True, max_length=None)
注:参数设置的方式与意义详见第三章的解释。
2.7、获取已下载的视频
你可以通过该函数获取通过get_channel_data()
下载的视频的AV号列表,由于该函数的工作方式与缓存目录的结构息息相关,因此函数的参数应与get_channel_data函数参数保持一致。
返回值:AV号列表,用户发布的所有视频的AV号(不包含前缀av
)。
import BiliUtil
if __name__ == '__main__':
ch = BiliUtil.Channel(uid='4093899', cid='8020')
exist_list = ch.get_channel_data(base_path='Download', name_path=True)
print(exist_list)
注:参数设置的方式与意义详见第三章的解释。
2.8、获取频道视频AV号
你可以获取频道内所有视频的AV号,该操作将自动帮你完成频道信息的获取。
返回值:AV号列表,频道内所有视频的AV号(不包含前缀av
)。
import BiliUtil
if __name__ == '__main__':
ch = BiliUtil.Channel()
ch.set_by_url('https://space.bilibili.com/4282930/channel/detail?cid=48759')
av_list = ch.get_av_list()
print(av_list)
2.9、获取对象信息字典
你可以将当前对象中保存的所有信息转换为字典格式保存,修改该字典时并不会影响实例。
import BiliUtil
if __name__ == '__main__':
ch = BiliUtil.Channel(uid='4093899', cid='8020')
ch.get_channel_info() # 修改对象
print(ch.get_dict_info()) # 输出对象内部信息
2.10、下载高清视频样例
import BiliUtil
if __name__ == '__main__':
cookie = input('请提供登录后的cookie信息,以升级下载画质:')
ch = BiliUtil.Channel()
ch.set_by_url('https://space.bilibili.com/4093899/channel/detail?cid=8020')
ch.set_cookie(cookie)
ch.get_all_video_data(base_path='Download', name_path=True)
3、专辑类(Album)
该类表示了一个专辑,即表示了一个av号对应的视频集合。当需要获取一个av号内所有视频时,可以选择创建该类的实例。
3.1、成员变量
成员变量 | 变量含义 | 默认值 |
---|---|---|
cookie | 设置的cookie信息 | None |
aid | 专辑av号 | None |
name | 专辑名称 | None |
time | 发布时间 | None |
desc | 专辑描述 | None |
zone | 频道内视频对象列表None | None |
num | 视频数量 | None |
cover | 封面链接 | None |
like | 点赞数量 | None |
coin | 投币数量 | None |
favorite | 收藏数量 | None |
share | 分享数量 | None |
view | 观看人次 | None |
danmu | 弹幕数量 | None |
video_list | 专辑内视频对象列表 | list() |
3.2、声明实例
你可以引入包并创建一个空的频道实例,空的频道实例不设置用户uid和频道cid。
import BiliUtil
if __name__ == '__main__':
av = BiliUtil.Album()
3.3、设定专辑aid
你可以通过多种方式设定av号,详见下方案例。
import BiliUtil
if __name__ == '__main__':
# 方案一
av = BiliUtil.Album(aid='31483746')
# 方案二
av = BiliUtil.Album()
av.set_user(aid='31483746')
# 方案三
av = BiliUtil.Album()
av.set_by_url(url='https://www.bilibili.com/video/av31483746')
三种函数声明方式如下:
def __init__(self, aid=None)
def set_album(self, aid=None)
def set_by_url(self, url)
注:使用URL设定用户时,请使用准确的URL。
3.4、设定Cookie
设定的cookie信息会影响到该实例及其包含的所有自动创建的对象。
av.set_cookie('SESSDATA=abcd68fd%2C1123761144%2C38d97xyz')
注:cookie设置的方式与意义详见第三章的解释。
3.5、获取专辑信息
你可以仅获取专辑信息以及视频列表而不下载视频。
对返回值(副本)进行的修改不会影响Album对象内的数据。
返回值:字典数据(副本),频道基本信息
import BiliUtil
if __name__ == '__main__':
av = BiliUtil.Album(aid='31483746')
album_info = av.get_album_info()
print(album_info)
3.6、获取频道视频数据
你可以直接获取专辑内视频数据,该操作将自动帮你完成专辑信息的获取。该操作支持设定路径、命名方式、视频时长,当设置了适合的cookie时,下载的画质将会自动提升。
import BiliUtil
if __name__ == '__main__':
av = BiliUtil.Album(aid='31483746')
av.get_album_data(base_path='Download', name_path=True, max_length=None)
注:参数设置的方式与意义详见第三章的解释。
3.7、查询视频是否已下载
你可以判断视频是否已经通过get_album_data()
函数下载。由于该函数的工作方式与缓存目录的结构息息相关,因此函数的参数应与get_album_data函数参数保持一致。
返回值:AV号列表,用户发布的所有视频的AV号(不包含前缀av
)。
import BiliUtil
if __name__ == '__main__':
av = BiliUtil.Album(aid='31483746')
exist = av.is_exist(base_path='Download', name_path=True)
print(exist)
注:参数设置的方式与意义详见第三章的解释。
3.7、获取对象信息字典
你可以将当前对象中保存的所有信息转换为字典格式保存,修改该字典时并不会影响实例。
import BiliUtil
if __name__ == '__main__':
av = BiliUtil.Album(uid='4093899', cid='8020')
av.get_channel_info() # 修改对象
print(ch.get_dict_info()) # 输出对象内部信息
3.8、下载高清视频样例
import BiliUtil
if __name__ == '__main__':
cookie = input('请提供登录后的cookie信息,以升级下载画质:')
av = BiliUtil.Album()
av.set_by_url('https://www.bilibili.com/video/av31483746')
av.set_cookie(cookie)
av.get_album_data(base_path='Download', name_path=True)
4、视频类(Video)
该类的实例不可手动创建,只能通过专辑类生成视频类的实例。
4.1、成员变量
成员变量 | 变量含义 | 默认值 |
---|---|---|
cookie | 设置的cookie信息 | None |
aid | 专辑av号 | None |
cid | 视频cid | None |
index | 分P编号 | None |
name | 分P名称 | None |
quality | 视频质量 | None |
quality_des | 视频质量描述 | None |
length | 视频时长 | None |
video | 视频下载链接 | None |
audio | 音频下载链接 | None |
4.2、获取对象信息字典
你可以将当前对象中保存的所有信息转换为字典格式保存,修改该字典时并不会影响实例。
import BiliUtil
if __name__ == '__main__':
av = BiliUtil.Album(uid='4093899', cid='8020')
av.get_channel_info() # 获取数据并生成Video实例
av.video_list[0].get_dict_info() # 输出对象内部信息
5、静态函数
5.1、视频合并函数
众所周知,视频由画面和声音组成。B站自从某个不知道的时间点以后将用户上传的视频分离为独立的视频与音频。因此,我们需要将下载好的视频与音频合并为一个文件,这样才方便观看。该函数将帮助你完成这一过程。
使用该函数需要您自行在计算机中配置ffmpeg渲染环境,若检查不到该环境存在,音视频合并函数将不会被引入。
函数声明:
merge_video_file(path, delete=False)
path:视频所在的文件夹
delete:是否在视频合并后删除源文件
import BiliUtil
if __name__ == '__main__':
print('合并文件夹内视频')
BiliUtil.merge_video_file('./Download', True)
三、帮助信息
1、cookie信息
- cookie信息不影响除视频画质外其他信息的获取。
- 通过cookie信息,你可以在下载视频的时候获取到更高清的视频数据,程序会根据你的身份(未登录、已登录、大会员),自动尝试并下载画质最好的视频(手动设置画质的功能写了一半没写完)。
- 当对象设置了cookie信息后,程序会将该信息分发至该实例所包含的所有Album和Video对象中。声明新的对象以及对象的其他实例不受该操作的影响。
- 设定cookie信息时,类似于
_uuid=B45CF1AB-xxx; LIVE_BUVID=AUTO76154xxx; SESSDATA=abcd68fd%2C1123761144%2C38d97xyz
的cookie信息也是可以被识别的。也可以传入字典类型的cookie信息,但是cookie信息中必须包含SESSDATA
字段,该字段是提升视频质量的关键点。 - 不同的身份信息可下载视频的映射表:
- 未登录--->480P
- 已登录--->1080P
- 大会员--->1080P60FPS / 1080P+
2、下载参数
在下载视频时,你可以传入三个参数来调节下载的过程。base_path='Download', name_path=True, max_length=None
- base_path:基础路径,该路径为程序缓存视频的基础路径,程序将在该路径下创建分级的文件夹。
- name_path:命名方式,该参数为True时,将使用各级实例的名称作为生成文件夹的名称(非法字符将被替换为'_')
- max_length:下载长度,该参数将限定视频下载的长度,单位为毫秒。当视频长度大于该值时,视频将不被下载。若您不需要该设置,请将该值设置为None。
3、视频下载流程
在生成了正确的对象后,我们就可以开始批量下载视频了。我需要向你解释一下下载的过程发生了什么。
- 您需要传入三个参数"缓存路径"、"命名方式"、“限制长度”
- 例将会自动获取实例的相关信息。
- 程序将按照指定的命名方式生成文件夹。
- 程序将按照"User>Channel>Album>Video"四级目录遍历,该操作将递归调用每个实例的
get_xxxxx_data
函数,并将三个参数传入,以此完成数据的遍历下载。 - 数据将综合采用
aria2c
与requests
进行下载,请确保您的环境中有aria2c
与requests
可供调用。 - 对于下载完成的数据,程序将会做简单的验证(仅验证文件是否存在)
- 下载结束后,程序将逐级将该对象下载时使用的数据,以json格式保存在同级目录中。
- 当您重启了相同的下载过程时,aria2将帮助你完成断点续传,下载过的视频将不会重复下载。
以下代码将演示如何下载频道视频
import BiliUtil
if __name__ == '__main__':
cookie = input('请提供登录后的cookie信息,以升级下载画质:')
# 创建频道对象
ch = BiliUtil.Channel()
# 设置频道参数
ch.set_by_url('https://space.bilibili.com/4282930/channel/detail?cid=48758')
# 传入cookie参数
ch.set_cookie(cookie)
# 开始批量下载视频
ch.get_channel_data(base_path='Download', name_path=False, max_length=None)
4、使用效果
5、关于BuilUtil
这个包中还有很多未完成的细节,还有一些想实现的功能未完成。 欢迎有兴趣的小伙伴一次参与,反馈BUG,更新代码,提供方案,我们共同完善它。
你可以联系我:mailto@wolfbolin.com
声明:该博客内容仅供学习参考,请勿用于商业目的
四、更新日志
v0.1.9
修复
- 修复了在Linux平台上相对路径错误导致的无法下载问题
- 添加了批量下载Up主的代码实例,在examples文件夹中。
v0.1.8
修复
- 修复了严重的翻页BUG(之前版本get_all_video_info获取用户视频最多30个,程序出现了一些偏差)
v0.1.7
修复
- get_xxx_info函数中vars函数运行异常
- 修改数据拷贝方式,防止数据被篡改
- 修改对象初始化方式,防止二次创建对象时异常
- 修正若干数据获取逻辑BUG
v0.1.6
修复
- 修复exclude_list列表使用BUG
新增
- 为频道与用户对象添加获取已下载视频的AV号列表。
- 为专辑对象添加判断视频是否已下载的访问接口
v0.1.5
新增
- 为频道与用户对象添加获取AV号列表函数。
- 允许在批量下载视频时,通过添加排除列表,过滤部分视频的下载。
- 为多个函数添加合适的响应值。
v0.1.4
解决ffmpeg合成阶段程序卡死。由于pipe size的大小限制,导致程序在收到超过64kb的输出时,程序会卡死不动。修改process.wait()为process.communicate()以解决该问题。
v0.1.3
操作失误导致pip中v0.1.2版本被删除,将以v0.1.3版本发布。建议更新至最新版本后再使用。
v0.1.2
修改:
-
修复了
ffmpeg
环境检测不通过的BUG,因为使用了错误的语法。 -
移除了对powershell的支持,未来将在linux环境中测试。
-
修复了使用
aria2c
时的错误语法,解决自定义输出路径报错。 -
修改路径获取方案,相对路径传入后,将以绝对路径进行计算。
v0.1.1
新增:
- 音视频合并函数
- 音视频批量合并代码示例
修改:
- 删除部分无意义的
(=・ω・=)
输出 - 调整aria2与ffmpeg环境检测机制
v0.0.1
BiliUtil已经过基础测试,正式发布第一个版本,若要直接使用,请使用pip进行安装。
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.