使用 Python 下载 B 站视频

本文的文字及图片来源于网络,仅供学习、交流使用,不具有任何商业用途,,版权归原作者所有,如有问题请及时联系我们以作处理

作者:某某白米饭     来源:Python技术 [公众号ID:pythonall]

链接:https://juejin.cn/post/6913143976895709191

PS:如有需要Python学习资料的小伙伴可以加点击下方链接自行获取

python免费学习资料以及群交流解答点击即可加入

 

使用 Python 下载 B 站视频

B 站,一个月活用户达到 1.72 的视频网站,有时候会因为某些未知的原因导致放入收藏夹的视频失效,会了防止视频被和谐、被失效,身为 Pythonista 来撸一个 B 站的视频下载器

分析页面

首先我们在 B 站点开一个视频(https://www.bilibili.com/video/BV1Vh411Z7j5)用 F12 分析一波,在下图中可以看到有多个 m4s 结尾的链接,并且响应的类型是 video/mp4

把面板打到 Elements 界面,找到一个 window.playinfo 的 javascript 变量,并且内容和上图中的 url 类似,都是 m4s 链接,目标已找到

获取标题和链接

抓取视频页面,并用 BeautifulSoup 模块解析页面,获取视频标题和链接(https://www.bilibili.com/video/BV17K4y1x7gs)

def __init__(self, bv):
    # 视频页地址
    self.url = 'https://www.bilibili.com/video/' + bv
    # 下载开始时间
    self.start_time = time.time()

def get_vedio_info(self):
    try:
        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36'
        }

        response = requests.get(url = self.url, headers = headers)
        if response.status_code == 200:

            bs = BeautifulSoup(response.text, 'html.parser')
            # 取视频标题
            video_title = bs.find('span', class_='tit').get_text()

            # 取视频链接
            pattern = re.compile(r"window\.__playinfo__=(.*?)$", re.MULTILINE | re.DOTALL)
            script = bs.find("script", text=pattern)
            result = pattern.search(script.next).group(1)

            temp = json.loads(result)
            # 取第一个视频链接
            for item in temp['data']['dash']['video']:
                if 'baseUrl' in item.keys():
                    video_url = item['baseUrl']
                    break

            return {
                'title': video_title,
                'url': video_url
            }
    except requests.RequestException:
        print('视频链接错误,请重新更换')
复制代码

示例结果:

{
    'title': '《属于周杰伦的情歌王2.0》安安静静的回忆有杰伦陪伴的20年', 
    'url': 'http://cn-jszj-dx-v-06.bilivideo.com/upgcxcode/34/57/214635734/214635734_nb2-1-30080.m4s?expires=1595538100&platform=pc&ssig=Q5uom_rGdPasJhHBvna8tw&oi=3027480765&trid=347f5dc41e9647e2a6dce48286d0b478u&nfc=1&nfb=maPYqpoel5MI3qOUX6YpRA==&cdnid=2725&mid=0&cip=222.186.35.71&orderid=0,3&logo=80000000'
}

复制代码

下载视频

下载视频使用 urllib 模块的 urlretrieve(url, filename=None, reporthook=None) 方法,它可以将远程数据直接下载到本地

def download_video(self, video):
    title = re.sub(r'[\/:*?"<>|]', '-', video['title'])
    url = video['url']
    filename = title + '.mp4'
    opener = urllib.request.build_opener()
    opener.addheaders = [('Origin', 'https://www.bilibili.com'),
                            ('Referer', self.url),
                            ('User-Agent', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36')]
    urllib.request.install_opener(opener)
    urllib.request.urlretrieve(url = url, filename = filename)
复制代码

示例结果:

一个视频下载完成

进度条

现在还缺一个进度条,没有进度条的下载工具是一个没有灵魂的下载工具

def schedule(self, blocknum, blocksize, totalsize):
    '''
    urllib.urlretrieve 的回调函数
    :param blocknum: 已经下载的数据块
    :param blocksize: 数据块的大小
    :param totalsize: 远程文件的大小
    :return:
    '''
    percent = 100.0 * blocknum * blocksize / totalsize
    if percent > 100:
        percent = 100
    s = ('#' * round(percent)).ljust(100, '-')
    sys.stdout.write("%.2f%%" % percent + '[ ' + s +']' + '\r')
    sys.stdout.flush()
复制代码

示例结果

最后更新一下下载视频的代码,加入 reporthook 参数

urllib.request.urlretrieve(url = url, filename = filename, reporthook = self.schedule)
复制代码

总结

简单的一个 B 站视频下载工具到这就完成了,有兴趣的话大伙可以试试下载 B 站的番剧,似乎和普通的视频不一样

 

 

### 使用Python实现从B下载视频 #### 准备工作 为了能够顺利地使用Python编写程序来下载B上的视频,需要先准备好必要的工具和库。 安装所需的Python包: ```bash pip install requests moviepy ``` `requests` 広用于发送HTTP请求并获取网页内容;而 `moviepy` 可以用来处理音视频文件的合并操作[^2]。 #### 获取视频链接 通常情况下,直接通过浏览器访问目标页面可以找到视频的真实地址。对于一些受保护的内容,则可能需要用到更复杂的技术手段去解析API接口返回的数据,从而提取出实际存储位置的信息。 #### 下载音频与视频流 一旦获得了有效的URL之后就可以调用如下函数分别保存对应的媒体资源: ```python import os import requests def download_media(url, output_path): response = requests.get(url, stream=True) with open(output_path, 'wb') as f: for chunk in response.iter_content(chunk_size=8192): if chunk: f.write(chunk) video_url = "http://example.com/path/to/video" audio_url = "http://example.com/path/to/audio" download_media(video_url, "./temp_video.mp4") download_media(audio_url, "./temp_audio.m4a") ``` 这段代码会创建两个临时文件——一个是视频部分(`./temp_video.mp4`),另一个是音频部分(`./temp_audio.m4a`)。 #### 合并音视频文件 当两份素材都准备完毕后,下一步就是把它们合成为一个完整的多媒体文件了。这里借助于之前提到过的 `moviepy.editor.VideoFileClip()` 方法完成这项任务: ```python from moviepy.editor import VideoFileClip, AudioFileClip video_clip = VideoFileClip("./temp_video.mp4") audio_clip = AudioFileClip("./temp_audio.m4a") final_clip = video_clip.set_audio(audio_clip) output_filename = "combined_output.mp4" final_clip.write_videofile( filename=output_filename, codec="libx264", audio_codec="aac", temp_audiofile="./temp-audio.m4a", remove_temp=True ) os.remove('./temp_video.mp4') os.remove('./temp_audio.m4a') print(f"Video saved to {output_filename}") ``` 上述脚本将会读取本地磁盘中的`.mp4` 和 `.m4a` 文件作为输入源,并最终导出名为 `"combined_output.mp4"` 的成品影片至当前目录下[^5]。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值