网页抓取解密( )
优采云 发布时间: 2021-10-29 02:12网页抓取解密(
)
主要用途
1、获取视频上的m3u8视频流文件网站。
2、对于加密的视频流文件,获取加密密钥并进行解码。
3、将视频文件保存在本地并合并。
运行环境:Win10 + Python 3.8
Python 包:请求
一、使用浏览器的开发者功能查找视频的m3u8文件地址网站
二、m3u8文件内容,其中.ts文件为要下载的视频文件地址,#EXT-X-KEY表示加密方式和KEY文件地址
代码和描述
import sys, os # os包用来在python环境下执行windows 的 cmd 命令
import requests
from Crypto.Cipher import AES # 用于AES解码
requests.packages.urllib3.disable_warnings() # 关闭https verify
class m3u8(object):
def __init__(self, name, m3u8_url): # 输入视频名称和 m3u8 文件地址
self.name = name
self.m3u8_url = m3u8_url
self.host = m3u8_url[:m3u8_url[10:].find('/')]
self.m3u8 = ''
self.method = ''
self.key = ''
self.key_url = ''
self.tslist = []
self.cryptor = ''
self.header = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:75.0) Gecko/20100101 Firefox/75.0'}
if self.name not in os.listdir('tmp/'):
os.mkdir(f'tmp/{self.name}') # 创建保存目录
self.savedir = f'tmp/{self.name}/'
def get_m3u8(self):
"""
获取 m3u8 配置文件, 执行
1. 从链接下载 m3u8 配置文件, 并保存到本地
2. 检查文件头部是否为 m3u8 格式文件
3. 检查是否有加密方法, 以及 key 文件地址
4. 提取所有 .ts 文件链接
"""
r = requests.get(self.m3u8_url, headers=self.header, verify=False)
with open(f'{self.savedir}{self.name}.m3u8', 'wb') as f:
f.write(r.content)
self.m3u8 = r.text
if '#EXTM3U' not in r.text:
raise BaseException('非m3u8链接')
for index, line in enumerate(r.text.split('\n')):
if '#EXT-X-KEY' in line:
self.method = line[line.find('METHOD=')+7: line.find(',')]
self.key_url = line[line.find('URI="')+5:-1]
if '.ts' in line:
if line[0] == '/':
self.tslist.append(f'{self.host}{line}')
elif line[:4] == 'http':
self.tslist.append(line)
else:
self.tslist.append(f'{self.m3u8_url[:self.m3u8_url.rfind("/")+1]}{line}')
def get_key(self):
"""
下载 key 文件, 并生成AES解密
"""
r = requests.get(self.key_url, headers=self.header, verify=False)
self.key = r.content
self.cryptor = AES(self.key, AES.MODE_CBC, self.key) # 生成*敏*感*词*,以供调用
with open(f'{self.savedir}{self.name}.key', 'wb') as f:
f.write(r.content)
def get_ts(self, url):
"""
下载指定的ts文件,保存到本地
"""
try:
r = requests.get(url,headers=self.header, verify=False)
# 如果是加密格式的文件, 需要先解密再保存
content = self.cryptor.decrypt(r.content) if self.method else r.content
with open(f'{self.savedir}{url[url.rfind("/")+1:]}', 'ab') as f:
f.write(content)
return True
except Exception as Err:
print(url, Err)
return False
def get_ts_all(self):
""" 批量下载.ts文件 """
filelist = list(reversed(self.tslist))
while filelist:
print(f'start get .ts files {len(filelist)}')
tsurl = filelist.pop()
if self.get_ts(tsurl):
print(f'get .ts successed, NO. {self.tslist.index(tsurl)} / {len(self.tslist)} : {tsurl}')
else:
filelist.insert(0, tsurl)
print(f'get .ts failed, NO. {self.tslist.index(tsurl)} / {len(self.tslist)} : {tsurl} ')
def merge_file(self):
"""
使用cmd命令行合并.ts文件
"""
os.chdir(self.savedir)
os.system(f'copy /b *.ts {self.name}.mp4')
os.system(f'del /Q *.ts')
if __name__ == '__main__':
name, url = sys.argv[1], sys.argv[2]
t = m3u8(name, url)
t.get_m3u8()
t.get_ts_all()
t.merge_file()