我们在做数据抓取的时候遇到后缀是.m3u8文件的几率特别大,一般都是加密之后的视频流(ts文件),具体为什么要这么做,说是加快了速度,细节这里不剖析。
主要讲一下如何根据.m3u8文件来获取到我们需要的视频:
第一步:.m3u8文件的获取,这个比较简单,网页版F12查找也好,app抓包也好,我们会获取到一个后缀是.m3u8的链接,请求这个链接就能得到.m3u8文件,浏览器里可以根据链接直接下载。
大致.m3u8文件里的内容如下:
上面几行不讲,大致就是一些标准、要求之类的 ,这里我们需要注意的是一下几点,加密方式、key的获取,以及iv(偏移量)。
加密方式就是上面标注的AES-128,key值是URL请求以后获取到的,iv也已经给出了。
先抛出一个问题,就是key的获取过程中,如果直接请求链接,发现返回的key是其他形式要先处理key为bytes格式。
上图的实例中刚好是bytes格式就不再处理,如图:
如果是直接用链接在浏览器里下载再打开,会发现是一个乱码,会让人感觉是不是搞错了。
第二步:
AES-128加密方式讲解
from Crypto.Cipher import AES #未安装的需要安装一下,安装过程百度到处可见
def decrypt_single_ts(data,key, iv):
"""
加密破解
:param data:直接请求加密视频链接获取的数据流
:param key: 获取到的key,注意必须是bytes格式且长度是16,24,32,等
:param iv:偏移量也是bytes格式
:return:
"""
cipher = AES.new(key, AES.MODE_CBC, iv=iv)
plain_data = cipher.decrypt(data)
with open ('video.mp4','wb')as f:
f.write(plain_data)
f.close()
第二个问题iv,我们可以看到文件中给出的iv(0xaa3dcf6a7acb92ff4fb08d9b3b3d6f51)并不是16位,如果把这个直接带入函数,会报错说是iv的长度不是十六位,我们就简单处理一下。
iv='aa3dcf6a7acb92ff4fb08d9b3b3d6f51'
def hexStringTobytes(str):
"""
str就是要传入的值,但是需要把前面的0X去掉,这一点需要注意,返回的就是16位的bytes
"""
str = str.replace(" ", "")
print(len(bytes.fromhex(str)))
return bytes.fromhex(str)
最后一步就是将正确的参数分别带入破解函数,获取可以播放的视频。经实测,是可以的。
当然,实际中可能key的加密是分情况的,不同的网站会根据情况设置不同形式的加密方式,要根据情况来获取到正确的key。
剩下的还有两个问题,一个是拼接视频流,另一个是提高下载的效率,多线程操作,这两个问题后续解决。