python3.6根据m3u8下载mp4视频
作者:李嘉坤 发布时间:2021-05-22 00:20:03
需要下载某网站的视频,chrome浏览器按F12打开开发者模式,发现视频链接是以"blob:http"开头的链接,打开这个链接后找不到网页,网上查了下,找到了下载方法,在这里做个记录,如果有错误,欢迎指出。
程序在Windows 10下运行,不过Linux应该也没问题。
使用到的有re模块,requests模块和Crypto模块,其中requests模块和Crypto模块如果没安装可以使用pip命令安装。(Crypto模块安装感觉比较坑,我是从anaconda里拷贝了一份)
下面开始正题:
注:以下使用的m3u8文件所在的网站是自己搭建用来测试的,链接可能会失效。
首先在chrome的network里找到一个m3u8文件的请求,可以通过它下载视频。
通过Preview可以看到m3u8文件的内容。
这里m3u8文件比较重要的内容有两个。
一个是URI后面的链接,这个是加密和解密的秘钥,如果m3u8文件里有这个URI,那么这个视频就是经过了加密的,加密的方法可以看URI前面,这里是AES-128加密算法。
另一个是以ts结尾链接,这个是视频片段,如果是没进行加密的,可以直接打开这个链接下载视频片段,下载下来的是后缀为ts的文件,一般可以直接播放,不过时间很短。如果是加密过的,下载后播放会提示视频文件已损坏。
知道这些后,就可以进行下载了,先获取m3u8文件的内容,然后解析出秘钥(key)和ts的链接,然后下载key对每一个ts进行解密,保存到一个mp4文件里。
下载用的是requests模块,解析key和ts的链接是用的re模块,解密用的是Crypto模块。
使用Crypto需要注意三个地方,一个是安装和导入,第二个是Crypto里AES.new的参数,第三个是decrypt方法的参数。下面先看代码。
导入模块:
import re
import requests
from Crypto.Cipher import AES
初始设置:
# 保存的mp4文件名
name = "dream_it_possible.mp4"
# m3u8文件的url
url = "http://www.jiuyi.info/static/video/secret/dream_it_possible.m3u8"
# 请求头,不一定需要,看网站更改
headers = {
"Referer": "http://www.jiuyi.info/video/dream_it_possible",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
"(KHTML, like Gecko) Chrome/71.0.3578.80 Safari/537.36",
}
获取m3u8文件内容,并解析出key和ts文件的url。
# 获取m3u8文件内容
r = requests.get(url)
# 通过正值表达式获取key和ts的url
k = re.compile(r"http://.*?\.key") # key的正则匹配
t = re.compile(r"http://.*?\.ts") # ts的正则匹配
key_url = k.findall(r.text)[0] # key的url
ts_urls = t.findall(r.text) # ts的url列表
下载并解密ts文件,保存为mp4文件。
# 下载key
key = requests.get(key_url).content
# 解密并保存ts
for ts_url in ts_urls:
ts_name = ts_url.split("/")[-1] # ts文件名
# 解密,new有三个参数,
# 第一个是秘钥(key)的二进制数据,
# 第二个使用下面这个就好
# 第三个IV在m3u8文件里URI后面会给出,如果没有,可以尝试把秘钥(key)赋值给IV
sprytor = AES.new(key, AES.MODE_CBC, IV=key)
# 获取ts文件二进制数据
ts = requests.get(ts_url).content
# 密文长度不为16的倍数,则添加二进制"0"直到长度为16的倍数
while len(ts) % 16 != 0:
ts += b"0"
# 写入mp4文件
with open(name, "ab") as file:
# decrypt方法的参数需要为16的倍数,如果不是,需要在后面补二进制"0"
file.write(sprytor.decrypt(ts))
print(name, "下载完成")
到这里就下载完成了。
完整代码:
import re
import requests
from Crypto.Cipher import AES
# 保存的mp4文件名
name = "dream_it_possible.mp4"
# m3u8文件的url
url = "http://www.jiuyi.info/static/video/secret/dream_it_possible.m3u8"
# 请求头,不一定需要,看网站更改
headers = {
"Referer": "http://www.jiuyi.info/video/dream_it_possible",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
"(KHTML, like Gecko) Chrome/71.0.3578.80 Safari/537.36",
}
print("正在解析:" + url.split("/")[-1])
# 获取m3u8文件内容
r = requests.get(url)
# 通过正值表达式获取key和ts的链接
k = re.compile(r"http://.*?\.key") # key的正则匹配
t = re.compile(r"http://.*?\.ts") # ts的正则匹配
key_url = k.findall(r.text)[0] # key的url
ts_urls = t.findall(r.text) # ts的url列表
# 下载key的二进制数据
print("正在下载key")
key = requests.get(key_url).content
# 解密并保存ts
for ts_url in ts_urls:
ts_name = ts_url.split("/")[-1] # ts文件名
# 解密,new有三个参数,
# 第一个是秘钥(key)的二进制数据,
# 第二个使用下面这个就好
# 第三个IV在m3u8文件里URI后面会给出,如果没有,可以尝试把秘钥(key)赋值给IV
sprytor = AES.new(key, AES.MODE_CBC, IV=key)
# 获取ts文件二进制数据
print("正在下载:" + ts_name)
ts = requests.get(ts_url).content
# 密文长度不为16的倍数,则添加b"0"直到长度为16的倍数
while len(ts) % 16 != 0:
ts += b"0"
print("正在解密:" + ts_name)
# 写入mp4文件
with open(name, "ab") as file:
# # decrypt方法的参数需要为16的倍数,如果不是,需要在后面补二进制"0"
file.write(sprytor.decrypt(ts))
print("保存成功:" + ts_name)
print(name, "下载完成")
来源:https://blog.csdn.net/u012552769/article/details/87949543
猜你喜欢
- 目录一、pyecharts绘制饼图语法简介二、绘制普通饼图三、绘制圆环图四、绘制饼图-玫瑰图一、pyecharts绘制饼图语法简介饼图主要用
- 本文实例为大家分享了GO原生实现文件上传功能的具体代码,供大家参考,具体内容如下写在前面最近在学习go,发现实践才是检验真理的唯一标准。在不
- 常用的python第三方库安装工具大概有三种:1、pip (推荐)2、easy_install3、setup.py常见的安装包格式:1、wh
- type 所有类是type生成的a = 1b = "abc"print("type a:{}&qu
- asp按关键字查询XML的问题 '-------------------------------------------------
- 一. adb 相关命令:1. 关闭adb服务:adb kill-server2. 启动adb服务 adb start
- 自己做了一个asp页面,用了一个td来显示留言本的最新消息;但是却无法控制其排版问题,因为该td的width确定,但是数据库中的文字却是未知
- CSS执行顺序与优先权的问题其实就是一个冲突解决的问题,当同一个元素(或内容)被CSS选择符选中时,就要按照优先权取舍不同的CSS规则,这其
- 使用 IE8 时发现其原生的 JSON 解析器存在 Bug,让我们先用 IE8 打开 DEMO 页面体验下。http://lab.grace
- <? // 建立一个指向新COM组件的索引 $word = new C
- 数据库镜像方案有两种镜像运行模式。一种是“高安全性模式”,它支持同步操作。在高安全性模式下,当会话开
- 这是asp利用dictionary创建二维数组的例子,这样做的优点是:1、数组下标可以是字符串2、长度不是固定的<'% ’==
- 精妙的"SQL"语句:◆复制表(只复制结构,源表名:a 新表名:b)SQL: select * into b from
- 在 PHP 中表示空的map或空数组都是以空数组形式,在转化为json数据时,会将空数组统一 json 序列化成 [],这样就存在
- 创建表书籍模型: 书籍有书名和出版日期,一本书可能会有多个作者,一个作者也可以写多本书,所以作者和书籍的关系就是多对多的关联关系(many-
- 关于数据库的逻辑设计,是一个很广泛的问题。本文主要针对开发应用中遇到在MS SQL Server上进行表设计时,对表的主键设计应注意的问题以
- 一、图像噪声图像噪声是图像在获取或者传输过程中受到随机信号干扰,妨碍人们对图像理解及分析处理的信号。很多时候将图像看作随机过程,因而描述噪声
- 一、停止线程利用Threading库我们可以很方便地创建线程,让它按照我们的想法执行我们想让它执行的事情,从而加快程序运行的效率。然而有一点
- 因为外贸网站,禁止同行抄袭,所以防止中国ip访问访问,访问的时候有密码提示,这样的代码如何写.请给一个提示.或者有好的代码,请分享下。 &n
- 用python的matplotlib画图时,往往需要加图例说明。如果不设置任何参数,默认是加到图像的内侧的最佳位置。import matpl