Python下载B站视频

422 阅读2分钟

众所周知B站是一个学习网站,当我们在B站学习时,遇到喜欢的视频,下载到本地,方便日后反复观看学习岂不美哉。在网上查找很多方法都已经失效,故自己手写一份下载B站学习视频代码,代码记录如下:

1.获取要下载视频的地址

首先分析要下载的B站视频的网页源码,提取视频和音频的地址。视频和音频在页面中源码的位置如下图所示:

71616773934_.pic_hd.jpg 格式化后,音频地址所在位置如下:

81616774737_.pic_hd.jpg 格式化后,视频地址所在位置如下:

91616774796_.pic_hd.jpg

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('视频合成成功')

git地址