1. 多媒体流协议RTSP,MMS简介
2. 使用VLC软件保存捕获的网络流
首先下载并安装VLC软件
然后,添加网络串流地址
打开VLC,点击媒体 -> 打开网络串流,添加网络流媒体链接: rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mp4
选择保存到文件,选中在"本地显示":
选择文件存放目录:
选择文件的格式,这个根据网络流媒体的格式选择,这里是MP4
串流输出:
等待一段时间,关闭VLC软件后,就可以打开MP4文件
保存的视频文件:
2. 捕获B站的网络视频流并保存
2.1 使用Fiddler分析B站视频流
首先打开Fiddler,使用Ctrl X清屏,然后在浏览器播放B站视频
然后在Fiddler处查看数据包,左边是图标,蓝白色的图标表示的就是视频或者音频文件,点击它可以在右下方的Headers里看到这个数据包的内容的长度。
2.2 利用Composer下载完整内容
打开右侧Composer
抓取完整的数据包内容,上面的Content-Range里的781414表示完整的视频内容的长度,而1235-287168只是这一段数据表示的视频内容,所以我们要抓取完整的0-781414的视频内容:
点击左侧数据包,拖动它到右侧:
这个数据包只请求1235-287168段的视频数据,修改它为0-781414:
点击Execute,回到左侧,拉到最下方,可以看到有一个新的视频数据包,右键它,点击 Save→Response→Response Body 保存它:
文件默认的后缀名为m4s.txt,修改文件的后缀名为mp4:
接下来以同样的方式处理第二个数据包,这是音频文件:
得到audio.mp4:
2.3 使用VLCPlayer查看下载的视频文件
可以直接播放,但是音频文件没有合并,所以没有声音,可以用ffmpeg合并两个文件
2.4 爬取B站视频
使用BiliBili的视频流API下载
代码语言:javascript复制import json
import requests
from fake_useragent import UserAgent
import re
# setting
# 自动最大分辨率 -> 0, 1080p -> 1, 720p -> 2, 480p -> 3, 360p -> 4 ,1080 -> 5
type = 0
# 编码格式 avc -> 0, hev -> 1
codecs = 0
#cookie
cookie = ''
# 下载大小(Byte为单位,None为全部)
byte = None
# byte = '0-9999'
url1='https://api.bilibili.com/pgc/player/web/playurl?fnval=80&cid={c}'
url2='https://api.bilibili.com/x/player/playurl?fnval=80&avid={a}&cid={c}'
class VideoList:
headers={
'User-Agent': '',
'referer': '',
'cookie': cookie
}
def __init__(self,url,part=[0]):
self.url=url
self.part=part
def download(self):
self.headers['User-Agent'] = str(UserAgent().random)
try:
self.html = requests.get(self.url,self.headers).text
except Exception:
print('链接失败')
return None
if re.findall(r'.bilibili.com/video/BV',self.url) != [] or re.findall(r'.bilibili.com/video/av',self.url) != []:
return self.video()
elif re.findall(r'.bilibili.com/bangumi/play/',self.url) != []:
return self.bangumi()
else:
print('url无效')
return None
def bangumi(self):
json_ = json.loads('{' re.search(r'"epList":[. ?]',self.html).group() '}')
self.headers['referer']=self.url
for i in self.part:
try:
cid = json_['epList'][i]['cid']
except Exception:
print('分p不存在')
break
self.headers['User-Agent'] = str(UserAgent().random)
js = json.loads(requests.get(url1.format(c=cid),headers=self.headers).text)
js['referer'] = self.url
js['part'] = i
yield js
def video(self):
json_ = json.loads('{' re.search(r'"aid":d ',self.html).group() '}')
aid = json_['aid']
json_ = json.loads('{' re.search(r'"pages":[. ?]',self.html).group() '}')
self.headers['referer']=self.url
for i in self.part:
try:
cid = json_['pages'][i]['cid']
except Exception:
print('分p不存在')
break
self.headers['User-Agent'] = str(UserAgent().random)
js = json.loads(requests.get(url2.format(a=aid,c=cid),headers=self.headers).text)
js['referer'] = self.url
js['part'] = i
yield js
class Download:
headers={
'User-Agent': '',
'referer': '',
'cookie': cookie
}
def __init__(self,js):
self.js=js
def download(self,path,type = 0,codecs = 0,byte = None):
self.headers['User-Agent'] = str(UserAgent().random)
self.headers['referer'] = self.js['referer']
p = str(self.js['part'])
if 'data' in self.js:
self.js=self.js['data']
else:
self.js=self.js['result']
id = self.js['dash']['video'][0]['id']
if type == 1:
id = 80
elif type == 2:
id = 64
elif type == 3:
id = 32
elif type == 4:
id = 16
elif type == 5:
id = 112
elif type != 0:
print('type参数错误')
return None
code = 'avc'
if codecs == 1:
code = 'hev'
elif codecs != 0:
print('codecs参数错误')
return None
js_movie = None
for i in self.js['dash']['video']:
if i['id'] == id and re.findall(code,i['codecs']) != []:
js_movie = i
break
js_audio = self.js['dash']['audio'][0]
if js_movie == None:
print('指定元素相关视频不存在')
return None
if byte!=None:
self.headers['range'] = 'bytes=' byte
vid = self.headers['referer'].split('/')[-1]
with open(path vid '_' p '.mp4','wb ') as file1, open(path vid '_' p '.mp3','wb ') as file2:
print('下载中','网址:' vid ' ' '分p:' p)
file1.write(requests.get(js_movie['base_url'],headers=self.headers).content)
file2.write(requests.get(js_audio['base_url'],headers=self.headers).content)
print('下载成功')
# 需要下载的视频网址
url = 'https://www.bilibili.com/video/BV1ty4y1H7H8'
# 需要下载的视频p数列表(番剧则为集数)
part = range(0,1)
# 下载路径
path = 'video/'
# 运行此文件即可下载
if __name__ == "__main__":
vl = VideoList(url,part)
for i in vl.download():
dl = Download(i)
dl.download(path,type = type,codecs = codecs,byte = byte)
爬取结果:
3. 参考
[1] b站视频下载接口分析
[2] 爬取B站直播流 - http flv的相关研究
[3] ffmpeg合并m4s文件
[4] 【Fiddler】利用Fiddler下载保存Bilibili里的视频