众所周知B站是一个学习网站,当我们在B站学习时,遇到喜欢的视频,下载到本地,方便日后反复观看学习岂不美哉。在网上查找很多方法都已经失效,故自己手写一份下载B站学习视频代码,代码记录如下:
1.获取要下载视频的地址
首先分析要下载的B站视频的网页源码,提取视频和音频的地址。视频和音频在页面中源码的位置如下图所示:
格式化后,音频地址所在位置如下:
格式化后,视频地址所在位置如下:
2.提取视频和音频地址,并下载到本地
import requests
import re
import json
class Download:
def __init__(self):
self.headers = {
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 11_2_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36',
'referer': 'https://www.bilibili.com'
}
def get_va_url(self, url):
'''
获取视频和音频地址
:param url: B站视频地址
:return: 要下载视频和音频的地址
'''
# 获取网页源代码
html_data = requests.get(url, headers=self.headers).text
# 正则解析视频和音频数据,并转化为json格式
video_data = json.loads(re.findall('<script>window\.__playinfo__=(.*?)</script>', html_data)[0])
# 从为json格式数据中获取视频和音频地址
video_url = video_data['data']['dash']['video'][0]['backupUrl'][0]
audio_url = video_data['data']['dash']['audio'][0]['backupUrl'][0]
return {'video_url': video_url, 'audio_url': audio_url}
def generate_va(self, va):
'''
根据视频和音频地址下载视频和音频
:param va:
:return: 视频是否下载成功
'''
try:
video_url = va['video_url']
audio_url = va['audio_url']
# 根据视频和音频地址,请求视频和音频二进制流数据
video_file = requests.get(video_url, headers=self.headers).content
audio_file = requests.get(audio_url, headers=self.headers).content
# 将视频和音频二进制流数据,写入本地
with open('./files/video.mp4', 'wb') as fp:
fp.write(video_file)
with open('./files/audio.mp3', 'wb') as fp:
fp.write(audio_file)
print('视频和音频下载成功')
return True
except Exception as e:
return False
3.使用ffmpeg合成视频和音频
import os
import subprocess
def composite_video(video, audio, to):
cmd = 'ffmpeg -y -i %s -i %s -c:v copy -c:a aac -strict experimental %s' % (
os.path.abspath(video), os.path.abspath(audio), os.path.abspath(to))
subprocess.Popen(cmd, shell=True).communicate()
print('视频合成成功')