使用 python 下载 bilibili 视频

本文想要达成的目标为:运行 python 代码之后,在终端输入视频链接,可自动下载高清 1080P 视频并保存到相应文件夹。

具体可分为两大步:首先,使用浏览器开发者工具 F12 获取请求链接相关信息(根据 api 接口下载?加密参数信息?是从 html 文件获取到具体的链接?链接在 html 文件中位置?);然后,确定使用的 python 库,并写出代码。

最后代码运行结果如图所示:

1. 确定请求链接信息

打开一个视频,对整个过程中的请求进行分析,确定视频链接和音频链接;(下图 1)

首先从 html 源码进行查找,找到了对应的音视频链接;(下图 2)

经过分析,可使用 beautifulsoup 库定位元素位置,标题定位为 bs.find('div', id='viewbox_report').find('div', class_='video-info-title').div.h1.string,视频链接定位为 bs.head.find_all('script', limit=4)[-1].string.lstrip('window.__playinfo__=')['data']['dash']['video'][2]['baseUrl'],音频链接定位为 bs.head.find_all('script', limit=4)[-1].string.lstrip('window.__playinfo__=')['data']['dash']['audio'][0]['baseUrl']。

2. 使用 requests 库下载音视频文件

2.1. 获取 html 源代码

可使用以下函数获取 html 文档:(注:经测试,下载 1080p 视频需要在请求头中加入 登陆帐号cookie)

复制代码
def _request_html(url: str):
    '''获取 html 文档源代码并返回'''
    response = get(url, headers={})
    response.encoding = response.apparent_encoding
    return response.text

2.2. 下载音视频文件并保存

然后,可根据上一步得到的链接位置,通过 bs 库对 html 文档进行解析,得到所需的 视频标题、视频链接、音频链接,使用 requests 库发送请求下载文件,并存储到本地。

注:因为音视频分离,所以可使用 aiohttp 进行异步下载,稍微提高效率;

注:为美观以及方便查看进度,可使用 rich 库添加进度条;

注:视频文件有时可能比较大,因此可使用流数据分块下载方式进行;

以下代码为提取所需信息代码,可进行参考:(注:首选视频链接有时会失效,因此需提取备用链接)

复制代码
@staticmethod
def _extract_title_url(html: str):
    bs = BeautifulSoup(html, 'lxml')
    # 提取视频标题,并去除非法字符
    title = bs.find('div', id='viewbox_report').find('div', class_='video-info-title').div.h1.string
    for i in {'/', '\\', '|', '<', '>', '\'', '\"', '?', ':', '*', '\x00'}:
        title = title.replace(i, ' ')
    # 提取音视频链接
    info = bs.head.find_all('script', limit=4)[-1].string.lstrip('window.__playinfo__=')
    info_dict = loads(info)
    video_urls = (
        info_dict['data']['dash']['video'][2]['baseUrl'],
        info_dict['data']['dash']['video'][2]['backupUrl'][0]
    )
    audio_urls = (
        info_dict['data']['dash']['audio'][0]['baseUrl'],
        info_dict['data']['dash']['audio'][0]['backupUrl'][0],
    )

    return (title, video_urls, audio_urls)

3. 使用 ffmpeg 合并音视频

可使用 ffmpeg 进行音视频的合并,合并完毕后删除音视频文件。

注:使用 pip 安装时命令为:pip install ffmpeg-python

注:可使用 rich 库添加进度条

代码如下,可参考:

复制代码
def _merge(video_path: str, audio_path: str, filepath: str):
    '''合并音视频'''
    with _progress_object_merge() as progress:
        progress.add_task('正在合并音视频', total=None)
        input_video = ffmpeg_input(video_path)
        input_audio = ffmpeg_input(audio_path)
        output = ffmpeg_output(input_video, input_audio, filepath, vcodec='copy', acodec='aac')
        ffmpeg_run(output, quiet=True)
        print(f'{filepath} 合并完成')
        remove(video_path)
        remove(audio_path)

def _progress_object_merge():
    '''合并音视频的进度条设置'''
    return Progress(
        TextColumn('[progress.description]{task.description}', style=CYAN, justify='left'),
        '•',
        BarColumn(bar_width=20),
        '•',
        TimeElapsedColumn(),
        transient=True,
    )
相关推荐
卷无止境5 小时前
RAGFlow 项目全景报告:从文档解析引擎到 Agent 原生数据库
后端·python
灿飞屋7 小时前
Kotlin与Java虚拟机三:控制流
android·java·开发语言·后端·python·kotlin·安卓
benchmark_cc7 小时前
单只股票五档盘口接入个人研究仓库:QuantDash 读取、校验与易错点
python·数据分析·pandas·量化交易·股票数据·quantdash
青少儿编程课堂8 小时前
蓝桥杯·全国青少年信息素养大赛·电子学会Python/C++考级:中缀表达式求值解析
c++·python·算法·bfs·信息学竞赛
灿飞屋10 小时前
Kotlin与Java虚拟机四:函数
java·python·kotlin·安卓·android jetpack
一晌小贪欢12 小时前
Python基础:第 09 篇 · while 循环:重复直到不满足
开发语言·c++·python·数据可视化·面向对象·python办公
一条大祥脚12 小时前
CuTe 与 CuTe DSL:从 C++ 模板元编程到 Python DSL 的 GPU 编程演进
开发语言·c++·python·cutlass·cute·cute dsl
10年前端老司机13 小时前
Milvus 8种检索能力实践
数据库·python·agent
Sakura_j_h_14 小时前
从零写一个 MCP stdio Server:用 Python 校验博客文章格式
开发语言·python·自动化·ai工具·mcp·json-rpc
大草原的小灰灰14 小时前
LLM应用的标准开发框架LangChain(八)- 中间件
python·中间件·langchain