python 下载 b站视频 和音频

ops/2024/12/14 0:39:02/

video_bvid:在这里插入图片描述

python">import os
import requests
import json
import re
from bs4 import BeautifulSoup
import subprocess
# from detail_video import video_bvid# video_bvid 是一个从外部得到的单个视频ID
video_bvid = 'BV1cx421Q7ve'class BilibiliVideoAudio:def __init__(self, bvid):"""初始化方法,接收一个bvid作为视频的唯一标识符。"""self.bvid = bvid# 设置请求头,用于模拟浏览器访问Bilibili网站self.headers = {"referer": "https://search.bilibili.com/all?keyword=%E4%B8%BB%E6%92%AD%E8%AF%B4%E8%81%94%E6%92%AD&from_source=webtop_search&spm_id_from=333.1007&search_source=5&page=4&o=90","origin": "https://search.bilibili.com",'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 Edg/120.0.0.0','Accept-Encoding': 'gzip, deflate, br'}def get_video_audio(self):"""获取视频和音频的链接以及视频标题。"""# 构造视频链接并发送请求获取页面内容url = f'https://www.bilibili.com/video/{self.bvid}/?spm_id_from=333.337.search-card.all.click&vd_source=14378ecd144bed421affe1fe0ddd8981'content = requests.get(url, headers=self.headers).content.decode('utf-8')# 使用BeautifulSoup解析HTML内容soup = BeautifulSoup(content, 'html.parser')# 获取视频标题meta_tag = soup.head.find('meta', attrs={'name': 'title'})title = meta_tag['content']# 获取视频和音频链接的正则表达式pattern = r'window\.__playinfo__=({.*?})\s*</script>'# 提取并解析JSON数据json_data = re.findall(pattern, content)[0]data = json.loads(json_data)# 提取视频和音频的基础URLvideo_url = data['data']['dash']['video'][0]['base_url']audio_url = data['data']['dash']['audio'][0]['base_url']# 返回包含标题、视频URL和音频URL的字典return {'title': title,'video_url': video_url,'audio_url': audio_url}def download_video_audio(self, url, filename):"""下载视频或音频文件。"""# 对文件名进行清理,去除不合规字符filename = self.sanitize_filename(filename)try:# 发送请求下载文件内容resp = requests.get(url, headers=self.headers).content# 构造下载路径download_path = os.path.join('D:\\video', filename)# 将文件内容写入到指定路径with open(download_path, mode='wb') as file:file.write(resp)# 打印下载完成信息print("{:*^30}".format(f"下载完成:{filename}"))except Exception as e:# 打印异常信息print(e)def sanitize_filename(self, filename):"""清理文件名中的不合规字符。"""# 定义不合规字符的正则表达式invalid_chars_regex = r'[\"*<>?\\|/:,]'# 替换不合规字符为空格sanitized_filename = re.sub(invalid_chars_regex, ' ', filename)return sanitized_filenamedef merge_video_audio(self, video_path, audio_path, output_path):"""使用ffmpeg来合并视频和音频。"""try:# 构造ffmpeg命令行参数command = ['ffmpeg','-y',  # 覆盖输出文件如果它已经存在'-i', video_path,  # 输入视频路径'-i', audio_path,  # 输入音频路径'-c', 'copy',  # 复制原始数据,不进行转码output_path  # 输出视频路径]# 执行ffmpeg命令subprocess.run(command, check=True)# 打印合并完成信息print(f"视频和音频合并完成:{output_path}")except subprocess.CalledProcessError as e:# 打印合并失败信息print(f"合并失败: {e}")def main():try:# 只处理一个 bvid(Bilibili 视频的唯一标识符)bilibili = BilibiliVideoAudio(video_bvid)  # 创建一个Bilibili视频音频处理对象,传入视频bvidvideo_audio_info = bilibili.get_video_audio()  # 获取视频和音频的信息# 从返回的信息中提取标题、视频URL和音频URLtitle = video_audio_info['title']video_url = video_audio_info['video_url']audio_url = video_audio_info['audio_url']# 定义处理后的视频存放路径processed_videos_path = 'D:\\processed_videos'# 如果该路径不存在,则创建该路径if not os.path.exists(processed_videos_path):os.makedirs(processed_videos_path)# 构造视频文件名、音频文件名和输出文件名video_filename = f"{title}.mp4"audio_filename = f"{title}.mp3"output_filename = f"{title} - combined.mp4"# 构造视频文件、音频文件和输出文件的完整路径video_file_path = os.path.join('D:\\video', video_filename)audio_file_path = os.path.join('D:\\video', audio_filename)output_file_path = os.path.join(processed_videos_path, output_filename)# 下载视频和音频到指定位置bilibili.download_video_audio(video_url, video_filename)  # 下载视频bilibili.download_video_audio(audio_url, audio_filename)  # 下载音频# 合并下载的视频和音频文件到指定输出路径bilibili.merge_video_audio(video_file_path, audio_file_path, output_file_path)# 可选:合并后删除单独的视频和音频文件# os.remove(video_file_path)# os.remove(audio_file_path)except Exception as ex:# 捕获并打印处理视频/音频时发生的异常print(f"处理视频/音频 {video_bvid} 失败: {ex}")main()

http://www.ppmy.cn/ops/141670.html

相关文章

新手上路,学Go还是Python

对于新手来说&#xff0c;Go和Python都是很好的编程语言&#xff0c;它们各有特点&#xff0c;以下是详细的对比来帮助你决定先学哪一个&#xff1a; 一、语法和学习难度 Python 语法简洁易懂&#xff1a;Python以其简洁、优雅的语法而闻名&#xff0c;代码的可读性很高。例如…

[Redis#19] 集群 | 数据分片 | docker模拟 | 故障转移 | 集群扩容

目录 集群 数据分片算法 1. 哈希求余 2 一致性哈希算法 3. 哈希槽分区算法 (Redis 使用) Docker搭建集群 i&#xff1a;创建目录和配置文件 编写 generate.sh 脚本 执行生成命令 ii&#xff1a;编写 docker-compose.yml 网络配置 iii: 构建集群 连接并验证集群 重…

TPM 2.0:安全固件的新标准

得益于可信计算组 ( TCG ) 推出的全新 TPM 2.0规范&#xff0c;联网设备可以更好地抵御网络攻击&#xff0c;并且不太可能受到错误的攻击。 制造商将可信平台模块 (TPM) 附加到设备上&#xff0c;以帮助用户和管理员验证其身份、生成和存储加密密钥以及确保平台完整性。 在 T…

【Innodb阅读笔记】之 本地搭建多个MYSQL

一、背景 在开展工作与学习任务的进程中&#xff0c;时常会涉及到运用多个 MySQL 实例执行特定操作的需求。例如&#xff0c;在深入研习主从复制机制时&#xff0c;借助多个 MySQL 实例能够更为直观地观察数据的传输与同步过程&#xff0c;有效加深对其原理及应用场景的理…

SpringBoot启动执行操作实现

伴随SpringBoot启动执行操作实现方式总结 引言方案使用EventListener监听使用ApplicationRunner 或者CommandLineRunner接口使用Spring Bean初始化方法使用Async注解Async 的主要效果和特性 使用SmartLifecycle接口 总结 引言 在实际项目中&#xff0c;经常需要在当项目启动的…

JavaScript 写css的内联样式

一、使用style属性-直接设置单个 CSS 属性 // 获取元素 var element document.getElementById("myElement");// 设置样式 element.style.color "red"; element.style.backgroundColor "blue"; element.style.fontSize "20px"; 二…

Qt源码阅读(六) ⏱️QTimer

Qt源码阅读(六) ⏱️QTimer Qt 为我们提供了一个非常实用的定时器&#xff08;QTimer&#xff09;&#xff0c;而在标准库中却没有类似的通用定时器。网络上有很多文章教你如何实现一个定时器&#xff0c;但本着就近原则&#xff0c;今天我们将深入阅读 Qt 中 QTimer 的源码&a…

spring boot之@Import注解的应用

我们知道spring boot会通过ComponentScan定义包扫描路径进行业务定义的bean的加载&#xff0c;但是对于很多不在此包路径下定义的bean怎么办呢&#xff1f;比如其他jar包中定义的。这时候import就发挥作用了&#xff0c;通过它也可以实现bean的定义。具体是怎么做的呢&#xff…