python3.6根据m3u8下载mp4视频


Posted in Python onJune 17, 2019

需要下载某网站的视频,chrome浏览器按F12打开开发者模式,发现视频链接是以"blob:http"开头的链接,打开这个链接后找不到网页,网上查了下,找到了下载方法,在这里做个记录,如果有错误,欢迎指出。

程序在Windows 10下运行,不过Linux应该也没问题。

使用到的有re模块,requests模块和Crypto模块,其中requests模块和Crypto模块如果没安装可以使用pip命令安装。(Crypto模块安装感觉比较坑,我是从anaconda里拷贝了一份)

下面开始正题:

注:以下使用的m3u8文件所在的网站是自己搭建用来测试的,链接可能会失效。

首先在chrome的network里找到一个m3u8文件的请求,可以通过它下载视频。

python3.6根据m3u8下载mp4视频

通过Preview可以看到m3u8文件的内容。

python3.6根据m3u8下载mp4视频

这里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, "下载完成")

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
跟老齐学Python之关于类的初步认识
Oct 11 Python
pycharm中连接mysql数据库的步骤详解
May 02 Python
python安装numpy&安装matplotlib& scipy的教程
Nov 02 Python
单链表反转python实现代码示例
Feb 08 Python
对Tensorflow中权值和feature map的可视化详解
Jun 14 Python
使用sklearn进行对数据标准化、归一化以及将数据还原的方法
Jul 11 Python
python高阶爬虫实战分析
Jul 29 Python
详解python编译器和解释器的区别
Jun 24 Python
通过python扫描二维码/条形码并打印数据
Nov 14 Python
Python3开发实例之非关系型图数据库Neo4j安装方法及Python3连接操作Neo4j方法实例
Mar 18 Python
pytorch 如何使用float64训练
May 24 Python
python编程实现清理微信重复缓存文件
Nov 01 Python
python如何实现视频转代码视频
Jun 17 #Python
python批量爬取下载抖音视频
Jun 17 #Python
python批量下载抖音视频
Jun 17 #Python
Python基础学习之类与实例基本用法与注意事项详解
Jun 17 #Python
python文本数据处理学习笔记详解
Jun 17 #Python
python3+PyQt5 实现Rich文本的行编辑方法
Jun 17 #Python
Appium+python自动化之连接模拟器并启动淘宝APP(超详解)
Jun 17 #Python
You might like
PHP 日志缩略名的创建函数代码
2010/05/26 PHP
PHP图片验证码制作实现分享(全)
2012/05/10 PHP
PHP实现的策略模式简单示例
2017/08/25 PHP
ThinkPHP5.1框架页面跳转及修改跳转页面模版示例
2019/05/06 PHP
PHP连接MySQL数据库操作代码实例解析
2020/07/11 PHP
Javascript在IE下设置innerHTML时出现未知的运行时错误的解决方法
2011/01/12 Javascript
分享27款非常棒的jQuery 表单插件
2011/03/28 Javascript
深入理解JavaScript系列(7) S.O.L.I.D五大原则之开闭原则OCP
2012/01/15 Javascript
让AJAX不依赖后端接口实现方案
2012/12/03 Javascript
jQuery插件jQuery-JSONP开发ajax调用使用注意事项
2013/11/22 Javascript
js实现不重复导入的方法
2016/03/02 Javascript
Node.js读写文件之批量替换图片的实现方法
2016/09/07 Javascript
JS实现搜索关键词的智能提示功能
2017/07/07 Javascript
React Native AsyncStorage本地存储工具类
2017/10/24 Javascript
jquery中done和then的区别(详解)
2017/12/19 jQuery
vue项目关闭eslint校验
2018/03/21 Javascript
python使用json序列化datetime类型实例解析
2018/02/11 Python
机器学习实战之knn算法pandas
2019/06/22 Python
PyQt5+Caffe+Opencv搭建人脸识别登录界面
2019/08/28 Python
Linux下升级安装python3.8并配置pip及yum的教程
2020/01/02 Python
Matplotlib使用Cursor实现UI定位的示例代码
2020/03/12 Python
基于jupyter代码无法在pycharm中运行的解决方法
2020/04/21 Python
python 常见的排序算法实现汇总
2020/08/21 Python
美国开幕式潮店:Opening Ceremony
2018/02/10 全球购物
俄罗斯珠宝市场的领导者之一:Бронницкий ювелир
2019/10/02 全球购物
广播电视新闻学专业应届生求职信
2013/10/08 职场文书
党员年终民主评议的自我评价
2013/11/05 职场文书
应届生英语教师求职信
2013/11/05 职场文书
六十岁生日答谢词
2014/01/10 职场文书
报效祖国演讲稿
2014/09/15 职场文书
英语感谢信范文
2015/01/20 职场文书
2015年挂职干部工作总结
2015/05/14 职场文书
致运动员的广播稿
2015/08/19 职场文书
MySQL中distinct和count(*)的使用方法比较
2021/05/26 MySQL
详解Spring Boot使用系统参数表提升系统的灵活性
2021/06/30 Java/Android
Python实战实现爬取天气数据并完成可视化分析详解
2022/06/16 Python