作者:段小草
链接:https://www.zhihu.com/question/486484268/answer/2911872392
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
人之所以区别于动物,是会使用工具。现成的工具有太多了,程序员更倾向于不重复造轮子。
题主只说了使用 Python,没说具体如何使用。众所周知, you-get 所有代码都是由 Python 完成的。
除了 B站,you-get 还支持几乎所有市面主流的视频网站。
使用方法也非常简单。
安装:
pip install you-get
使用
$ you-get 视频链接
作为命令行工具,you-get 也提供了丰富的可供选择,比如选择分辨率、查看视频信息等,详见 Github 仓库:
https://github.com/soimort/you-getgithub.com/soimort/you-get
如果题主不单单是为了工具,而是想自己写代码,或者是为了完成某门作业之类的。比较快捷的做法是去查看 you-get 源码中关于 B站的部分。不过可能会缺少下载的部分,因为 you-get 的下载器是同一的,bilibili.py 更偏向于视频播放地址的解析。
详见:
https://github.com/soimort/you-get/blob/1c841f7e8ce60130572a8f03fb038eda99deff6a/src/you_get/extractors/bilibili.pygithub.com/soimort/you-get/blob/1c841f7e8ce60130572a8f03fb038eda99deff6a/src/you_get/extractors/bilibili.py
如果题主不想吃做好的饭,非要挑战自己,尝试重新造轮子的话。那就需要自己去找真实的播放链接了。
一般来讲,获取网站的视频播放有几种方式:
①最简单的情况下,直接查看network,会看到一个体积巨大的请求,右键,在新链接打开,直接下载就是了。
②一些网站会把视频切割成 .ts 的分段文件,然后用一个 .m3u8 的文件,可以下载所有的 .ts 文件后进行拼接重新输出。(可以搜索 m3u8 ts 拼接这些关键字,这里不展开了)
③在源码里分析,看会不会找到真实播放地址的线索,等等。
我之前设想过一个工作流:自动监测某个账号的视频更新-下载视频-语音转文字-摘要成笔记。因为现在长视频的内容太多了,其中确实有一些优秀视频,但看视频远比图文费时间,其中的主要内容还不能直接复制/粘贴整理。不过后来由于懒一直没有执行…
发布于 2023-02-26 16:37・IP 属地河南
赞同 192 条评论分享收藏喜欢收起
拾柒
合格证书
关注
嗨喽,大家好呀~这里是爱看美女的茜茜呐
又到了学Python时刻~
现在好看的妹子真的太多啦~
如何一次性把这些好看的视频全保存下来捏?
一. 思路分析
案例的分析 视频 media .mp4 .mp3 .m4a m3u8视频流
.m4s: 视频/音频 格式
数据来源分析: 找到视频内容
network抓包
二. 代码实现(代码实现基本流程)
PS:完整源码如有需要的小伙伴可以加下方的群去找管理员免费领取
导入模块
import requests
import re # 正则表达式模块
import json
import pprint
import subprocess
import os
伪装(请求头)
headers = {
# 用户信息
"cookie": "buvid3=355AA300-6A61-04E5-A05C-E891D886F69632716infoc; b_nut=1675085932; i-wanna-go-back=-1; _uuid=387EA3810-FBF5-E92C-827E-2510B578C5B9A33232infoc; buvid4=15C69C98-F6A7-EC6A-872F-E69C1840DD6D33724-023013021-1pW1w45e5fZS9RtebDiGZw%3D%3D; nostalgia_conf=-1; CURRENT_FNVAL=4048; rpdid=|(kmJY|k))lY0J'uY~l|)lmY|; SESSDATA=17eb9f1a%2C1690782878%2C6a25c%2A22; bili_jct=4af9076b42f76603dfe4cf018ad2000f; DedeUserID=422789639; DedeUserID__ckMd5=fc4901c78719b545; CURRENT_QUALITY=80; b_ut=5; b_lsid=51ED8F105_1861C3EEC10; theme_style=light; is-2022-channel=1; sid=66dafqju; fingerprint=97ca5a8b555e63aca787c9cd27273c7e; buvid_fp_plain=undefined; buvid_fp=8cc52ae38b592ff26dc2b393eebd890b; PVID=2; innersign=1; bp_video_offset_422789639=758803412994228200",
# 防盗链
"referer": "https://www.****.com/",
# 浏览器基本信息
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36"
}
发送请求
url = 'https://www.***.com/video/BV1qv4y1k7UE/?vd_source=8f216a44bce0dbe14e3447c34c2ab3e2'
response = requests.get(url, headers=headers)
获取数据
html_data = response.text
解析数据
json_str = re.findall('__playinfo__=(.*?)', html_data)[0]
# (.*?)
title = re.findall('(.*?)
', html_data)[0]
# Python基础 字典
json_data = json.loads(json_str)
# pprint.pprint(json_data)
audio_url = json_data['data']['dash']['audio'][0]['baseUrl']
print(audio_url)
video_url = json_data['data']['dash']['video'][0]['baseUrl']
print(video_url)
保存数据
audio_data = requests.get(audio_url, headers=headers).content
with open(f'{title}.mp3', mode='wb') as f:
f.write(audio_data)
video_data = requests.get(video_url, headers=headers).content
with open(f'{title}.mp4', mode='wb') as f:
f.write(video_data)
ffmpeg = f'ffmpeg -i {title}.mp4 -i {title}.mp3 -acodec copy -vcodec copy {title+"-out.mp4"}'
subprocess.run(ffmpeg)
os.remove(f'{title}.mp4')
os.remove(f'{title}.mp3')
感谢你观看我的文章呐~本次航班到这里就结束啦
希望本篇文章有对你带来帮助 ,有学习到一点知识~
躲起来的星星 也在努力发光,你也要努力加油(让我们一起努力叭)。
发布于 2023-02-10 22:56
赞同添加评论分享收藏喜欢收起
苛岚异梦
关注
5 人赞同了该回答
ffmpeg官网下载 https://ffmpeg.org/ (下载后需要配置环境变量)需要重启! 链接:https://pan.baidu.com/s/1aDSlIQ1kPOOUsVOAmcFfHw 提取码:gvw4
gitee地址 https://gitee.com/ddpoi/bili
博客地址https://www.ddblog.xyz/articles/53
# import time
import requests
import re
import os
import subprocess
# import sys,io
# sys.stdout = io.TextIOWrapper(sys.stdout.buffer,encoding='gb18030')
headers = {
'referer': 'https://www.bilibili.com/video/BV1J3411h7pm?spm_id_from=333.5.0.0',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.99 Safari/537.36 Edg/97.0.1072.69'
}
# 获取视频bvid
def get_bvid(mid,path):
''' 这里ps=30,是一页的视频数量,pn代表页数,可以自己加一个循环 '''
url = 'https://api.bilibili.com/x/space/arc/search?mid={}&ps=30&tid=0&pn=1&keyword=&order=pubdate&jsonp=jsonp'.format(mid)
response = requests.get(url=url,headers=headers).json()
mm = response['data']['list']['vlist']
for i in mm:
title = (i['title'])
bvid = (i['bvid'])
# print(title)
# print(bvid)
get_cid(bvid,title,path)
# 获取cid
def get_cid(bvid,title,path):
url = 'https://api.bilibili.com/x/player/pagelist?bvid={}&jsonp=jsonp'.format(bvid)
response = requests.get(url=url,headers=headers).json()
nn = response['data']
for i in nn:
cid = (i['cid'])
# print(cid)
get_video(bvid,cid,title,path)
# 获取视频,音频的url
def get_video(bvid,cid,title,path):
url = 'https://api.bilibili.com/x/player/playurl?cid={}&bvid={}&qn=120&type=&otype=json&fourk=1&fnver=0&fnval=4048&session=521a3c69be48043423dab7dfacc0dfde'.format(cid,bvid)
response = requests.get(url=url,headers=headers).json()
video_url = response['data']['dash']['video'][0]['baseUrl']
audio_url = response['data']['dash']['audio'][0]['baseUrl']
# print(audio_url)
# print(video_url)
save(title,video_url,audio_url,path)
# 保存视频,音频文件,(下载时文件名取第一个字符,防止含有特殊符号而报错)
def save(title,video_url,audio_url,path):
try:
video = requests.get(url=video_url,headers=headers)
with open(path+title[:1]+'.mp4','ab') as f:
f.write(video.content)
print('{}下载完成....'.format(title + '.mp4'))
audio = requests.get(url=audio_url, headers=headers)
with open(path+title[:1]+'.mp3','ab') as f:
f.write(audio.content)
print('{}下载完成....'.format(title + '.mp3'))
except:
pass
video_add(title,path)
'''
由于有些up主视频标题包含特殊字符,例如 ? | / 等。所以需要将这些字符过滤出去
'''
# 将下载的视频,音频进行合成
def video_add(title,path):
intab = "?/|.><:*"
for s in intab:
if s in title: # 将特殊字符转化为空格
print(s)
title = title.replace(s, '')
# 如果程序异常,选择忽略
try:
# print(title)
print('开始合成')
os.chdir(path)
cmd = f'ffmpeg -i {title[:1]}.mp4 -i {title[:1]}.mp3 -c:v copy -c:a aac -strict experimental {title[:1]}_1.mp4'
# print(cmd)
subprocess.call(cmd, shell=True)
'''选择是否删除原mp3、mp4文件'''
os.remove(title[:1]+'.mp4')
os.remove(title[:1]+'.mp3')
os.rename(title[:1] + '_1.mp4', title + '.mp4')
print('合成结束')
except:
pass
# 判断输入的是mid还是视频链接
def main(mid,path):
if mid == "":
print('错误,请重新输入') # mid输入不能为空
return False
if re.match(r'[a-zA-Z]', mid): # 用正则来判断输入的mid类型
bvid = (mid.split('?')[0]).split('/')[4] # 取出视频链接中的bvid
print(bvid)
title = input('请输入视频名称:') # 手动指定视频名称
get_cid(bvid,title,path)
else:
get_bvid(mid,path)
if __name__ == '__main__':
mid = input('请输入up主的mid或视频链接:')
print('路径一定要加/,默认为当前目录')
file_path = input('请输入保存文件路径:') # 输入文件路径
if file_path == "" :
path = './'
else:
path = file_path
main(mid,path)
更新时间:2024-08-19
本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828
© CopyRight 2020-2024 All Rights Reserved. Powered By 71396.com 闽ICP备11008920号-4
闽公网安备35020302034903号