M3U8流视频数据爬虫
M3U8流视频数据爬虫
HLS技术介绍
现在大部分视频客户端都采用HTTP Live Streaming(HLS,Apple为了提高流播效率开发的技术),而不是直接播放MP4等视频文件。HLS技术的特点是将流媒体切分为若干【TS片段】(比如几秒一段),然后通过一个【M3U8列表文件】将这些TS片段批量下载供客户端播放器实现实时流式播放。因此,在爬取HLS的流媒体文件的思路一般是先【下载M3U8文件】并分析其中内容,然后在批量下载文件中定义的【TS片段】,最后将其【组合】成mp4文件或者直接保存TS片段。
M3U8文件详解
如果想要爬取HLS技术下的资源数据,首先要对M3U8的数据结构和字段定义非常了解。M3U8是一个扩展文件格式,由M3U扩展而来。那么什么是M3U呢?
M3U文件
M3U这种文件格式,本质上说不是音频视频文件,它是音频视频文件的列表文件,是纯文本文件。
M3U这种文件被获取后,播放软件并不是播放它,而是根据它的记录找到媒体的网络地址进行在线播放。也就是说,M3U格式的文件只是存储多媒体播放列表,并提供了一个指向其他位置的音频视频文件的索引,播放的是那些被指向的文件。
为了能够更好的理解M3U的概念,我们先简单做一个M3U文件(myTest.m3u)。在电脑中随便找几个MP3,MP4文件依次输入这些文件的路径,myTest.m3u文件内容如下
E:\Users\m3u8\刘德华 - 无间道.mp4
E:\Users\m3u8\那英 - 默.mp3
E:\Users\m3u8\周杰伦 - 不能说的秘密.mp4
E:\Users\m3u8\花粥 - 二十岁的某一天.mp3
E:\Users\m3u8\周深 - 大鱼.mp4
M3U8文件
M3U8也是一种M3U的扩展格式(高级的M3U,所以也属于M3U)。
**M3U8示例:**大家会看到在该文件中有大量的ts文件的链接地址,这个就是我们之前描述的真正的视频文件。其中任何一个ts文件都是一小段视频,可以单独播放。我们做视频爬虫的目标就是把这些ts文件都爬取下来。
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:6
#EXT-X-PLAYLIST-TYPE:VOD
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:3.127,
/20230512/RzGw5hDB/1500kb/hls/YZefAiEF.ts
#EXTINF:3.127,
/20230512/RzGw5hDB/1500kb/hls/FsliUCL6.ts
#EXTINF:3.127,
/20230512/RzGw5hDB/1500kb/hls/DD7c47bz.ts
#EXT-X-ENDLIST
实战
需求:
- https://www.mjtt5.tv/
具体操作
- 进入视频播放页
- 点击播放按钮,定位ts数据包,从中提取ts片段的url,探究url的规律
- 打开抓包工具,刷新页面,全局搜索m3u8定位到找到m3u8文件
- 解析m3u8文件提取文件中ts片段链接
- 同步操作代码
import requests
from urllib.parse import urljoin
import re
import os
dirName = 'tsLib'
if not os.path.exists(dirName):os.mkdir(dirName)headers = {'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36'
}
#m3u8地址
url = "https://cdn13.tvtvgood.com/202310/20/c1959422deee/playlist.m3u8?token=d5i9GCr3ljqGsSf48-aG2w&expires=1698221543"
page_text = requests.get(url=url,headers=headers).text
page_text = page_text.strip()#解析出每一个ts切片的地址
ts_url_list = []
for line in page_text.split('\n'):if not line.startswith('#'):ts_url = line#不同ts下载地址ts_url = 'https://cdn13.tvtvgood.com/202310/20/c1959422deee/'+ts_urlts_url_list.append(ts_url)print(ts_url_list)
#请求到每一个ts切片的数据
for url in ts_url_list:#获取ts片段的数据ts_data = requests.get(url=url,headers=headers).contentts_name = url.split('/')[-1]ts_path = dirName+'/'+ts_namewith open(ts_path,'wb') as fp:#需要将解密后的数据写入文件进行保存fp.write(ts_data)print(ts_name,'下载保存成功!')# ts文件的合并,最好网上找专业的工具进行合并,自己手动合并会经常出问题
- 异步操作代码:协程
#https://cdn8.tvtvgood.com/202206/21/6abfb3237d01/playlist8.ts
#https://cdn8.tvtvgood.com/202206/21/6abfb3237d01/playlist7.ts
import requests
import os
import asyncio
import aiohttp
from threading import Thread
dirName = 'tsLib'
if not os.path.exists(dirName):os.mkdir(dirName)headers = {'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36'
}
#m3u8文件的url
m3u8_file_url = 'https://cdn8.tvtvgood.com/202206/21/6abfb3237d01/playlist.m3u8?token=9vVIuesP2MAZ4G1V6y6DnA&expires=1698927688'
m3u8_text = requests.get(url=m3u8_file_url,headers=headers).textts_url_list = [] #存储解析出来的每一个ts片段的url
for line in m3u8_text.split('\n'):if not line.startswith('#'):ts_url = linets_url = 'https://cdn8.tvtvgood.com/202206/21/6abfb3237d01/'+ts_urlts_url_list.append(ts_url)#基于协程实现异步的ts片段的请求
async def get_reqeust(url):#参数url就是ts片段的请求urlasync with aiohttp.ClientSession() as req:async with await req.get(url=url,headers=headers) as response:ts_data = await response.read()dic = {'ts_data':ts_data,'ts_title':url.split('/')[-1]}return dicdef save_ts_data(t):dic = t.result()ts_data = dic['ts_data']ts_title = dic['ts_title']ts_path = dirName + '/' + ts_titlewith open(ts_path,'wb') as fp:fp.write(ts_data)print(ts_title,':保存下载成功!')tasks = []
for url in ts_url_list:c = get_reqeust(url)task = asyncio.ensure_future(c)task.add_done_callback(save_ts_data)tasks.append(task)loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))#使用协程:实现一定得有一个url列表,遍历该列表进行多协程的创建
#使用多个loop的场景:两种数据资源下载,需要实现有两个url列表
#问题:两个loop之间的关系是异步的吗?
#注意:千万别搞loop的嵌套。#特殊的方式:创建两个线程,两个线程中封装处理两个loop。
线程池的实现方案:
#https://cdn8.tvtvgood.com/202206/21/6abfb3237d01/playlist8.ts
#https://cdn8.tvtvgood.com/202206/21/6abfb3237d01/playlist7.ts
import requests
import os
from threading import Thread
from multiprocessing.dummy import PooldirName = 'tsLib'
if not os.path.exists(dirName):os.mkdir(dirName)headers = {'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36','Connection':'closed'
}
#m3u8文件的url
m3u8_file_url = 'https://cdn8.tvtvgood.com/202206/21/6abfb3237d01/playlist.m3u8?token=9vVIuesP2MAZ4G1V6y6DnA&expires=1698927688'
m3u8_text = requests.get(url=m3u8_file_url,headers=headers).textts_url_list = [] #存储解析出来的每一个ts片段的url
for line in m3u8_text.split('\n'):if not line.startswith('#'):ts_url = linets_url = 'https://cdn8.tvtvgood.com/202206/21/6abfb3237d01/'+ts_urlts_url_list.append(ts_url)def get_reqeust(url):#参数url就是ts片段的请求urlts_data = requests.get(url=url,headers=headers,verify=False).contentts_path = dirName + '/' + url.split('/')[-1]with open(ts_path,'wb') as fp:fp.write(ts_data)print(ts_path,':保存下载成功!')#HTTPSConnectionPool异常原因:#网络请求的并发量太大(减少并发or在headers中添加一个Connection:closed)pool = Pool(100)
pool.map(get_reqeust,ts_url_list)
相关文章:
M3U8流视频数据爬虫
M3U8流视频数据爬虫 HLS技术介绍 现在大部分视频客户端都采用HTTP Live Streaming(HLS,Apple为了提高流播效率开发的技术),而不是直接播放MP4等视频文件。HLS技术的特点是将流媒体切分为若干【TS片段】(比如几秒一段…...
保护您的数字财富:模块化沙箱在源代码防泄露中的突破
在数字化浪潮中,企业面临着前所未有的数据安全挑战。源代码、商业机密、客户数据……这些宝贵的数字资产一旦泄露,后果不堪设想。SDC沙盒防泄密系统,以其卓越的技术实力和创新的解决方案,为企业提供了一个坚不可摧的安全屏障。 核…...
FFmpeg源码:avio_r8、avio_rl16、avio_rl24、avio_rl32、avio_rl64函数分析
一、引言 AVIOContext是FFmpeg(本文演示用的FFmpeg源码版本为5.0.3)中的字节流上下文结构体,用来管理输入输出数据。打开一个媒体文件的时候,需要先把数据从硬盘读到缓冲区,然后会用到AVIOContext中的如下成员&#x…...
如何使用 API 查看极狐GitLab 镜像仓库中的镜像?
GitLab 是一个全球知名的一体化 DevOps 平台,很多人都通过私有化部署 GitLab 来进行源代码托管。极狐GitLab :https://gitlab.cn/install?channelcontent&utm_sourcecsdn 是 GitLab 在中国的发行版,专门为中国程序员服务。可以一键式部署…...
软件-vscode-plantUML-IDEA
文章目录 vscode基础命令 实操1. vscode实现springboot项目搭建 (包括spring data jpa和sqlLite连接) PlantUMLIDEA下载及安装Eval Reset插件配置修改IDEA创建项目的默认目录IDEA配置gitIDEA翻译插件translationIDEA断点调试IDEA全局搜索快捷键不能使用代…...
ES6语法详解,面试必会,通俗易懂版
目录 Set的基本使用WeakSet 使用Set 和 WeakSet 区别内存泄漏示例:使用普通 Set 保存 DOM 节点如何避免这个内存泄漏MapWeakMap 的使用 Set的基本使用 在ES6之前,我们存储数据的结构主要有两种:数组、对象。 在ES6中新增了另外两种数据结构&a…...
CTFshow--Web--代码审计
目录 web301 web302 web303 web304 web305 web306 web307 web308 web309 web310 web301 开始一个登录框, 下意识sql尝试一下 发现 1 的时候会到一个 checklogin.php 的路径下, 但啥也没有 好吧, 这是要审计代码的 ,下载好源码, 开始审计 看了一下源码 , 应该就是sql…...
Java语言程序设计——篇十(1)
🌿🌿🌿跟随博主脚步,从这里开始→博主主页🌿🌿🌿 接口介绍 接口概述接口定义接口的实现实战演练 👅接口的继承实战演练实战演练 接口的类型常量实战演练 静态方法默认方法解决默认方…...
Qt对比MFC优势
从Qt小白到现在使用了有四年的时间,之前也搞过MFC,WinForm,基本上都是桌面的框架, 从难易程度看MFC>QT>WinForm; 运行的效率上来看MFC>QT>WinForm; 开发效率上WinForm>QT>MFC; 跨平台Qt首选; 界面的美观难易程度Qt>…...
RuntimeError: No CUDA GPUs are available
RuntimeError: No CUDA GPUs are available 目录 RuntimeError: No CUDA GPUs are available 【常见模块错误】 【解决方案】 解决步骤如下: 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主页,我是博主英杰,211科…...
URL参数中携带中文?分享 1 段优质 JS 代码片段!
本内容首发于工粽号:程序员大澈,每日分享一段优质代码片段,欢迎关注和投稿! 大家好,我是大澈! 本文约 800 字,整篇阅读约需 1 分钟。 今天分享一段优质 JS 代码片段,在发送 ajax 请…...
sass的使用
一、变量 //声明一个变量 $highlight-color: #F90; .selected {border: 1px solid $highlight-color; }//编译后 .selected {border: 1px solid #F90; }二、导入 import "xxx.scss"三、混合器简单定义 通过mixin定义,通过include调用 // mixin.scss /…...
【足球走地软件】走地数据分析预测【大模型篇】走地预测软件实战分享
了解什么是走地数据? 走地数据分析,在足球赛事的上下文中,是一种针对正在进行中的比赛进行实时数据分析的方法。这种方法主要用于预测比赛中的某些结果或趋势,如总进球数、比分变化、球队表现等。 在足球走地数据分析中…...
现在有什么赛道可以干到退休?
最近,一则“90后无论男女都得65岁以后退休”的消息在多个网络平台流传,也不知道是真是假,好巧不巧今天刷热点的时候又看到一条这样的热点:现在有什么赛道可以干到退休? 点进去看了几条热评,第一条热评说的…...
c程序杂谈系列(职责链模式与if_else)
从处理器的角度来说,条件分支会导致指令流水线的中断,所以控制语句需要严格保存状态,因为处理器是很难直接进行逻辑判断的,有可能它会执行一段时间,发现出错后再返回,也有可能通过延时等手段完成控制流的正…...
前端开发技术之CSS(层叠样式表)
盒模型(Box Model) CSS盒模型描述了如何计算一个元素的总宽度和高度。 它包括以下几个部分: 1. 内容(Content):元素的实际内容,比如文本或图片。 2. 内边距(Padding)&…...
go语言day20 使用gin框架获取参数 使用自定义的logger记录日志
Golang 操作 Logger、Zap Logger 日志_golang zap-CSDN博客 目录 一、 从控制器中获取参数的几种形式 1) 页面请求url直接拼接参数。 2) 页面请求提交form表单 3) 页面请求发送json数据,使用上下文对象c的BindJSON()方法接…...
DHCP笔记
DHCP---动态主机配置协议 作用:为终端动态提供IP地址,子网掩码,网关,DNS网址等信息 具体流程 报文抓包 在DHCP服务器分配iP地址之间会进行广播发送arp报文,接收IP地址的设备也会发送,防止其他设备已经使用…...
TCP为什么需要四次挥手?
tcp为什么需要四次挥手? 答案有两个: 1.将发送fin包的权限交给被动断开发的应用层去处理,也就是让程序员处理 2.接第一个答案,应用层有了发送fin的权限,可以在发送fin前继续向对端发送消息 为了搞清楚这个问题&…...
MySQL 索引相关基本概念
文章目录 前言一. B Tree 索引1. 概念2. 聚集索引/聚簇索引3. 辅助索引/二级索引4. 回表5. 联合索引/复合索引6. 覆盖索引 二. 哈希索引三. 全文索引 前言 InnoDB存储引擎支持以下几种常见索引:BTree索引,哈希索引,全文索引 一. B Tree 索引…...
手游刚开服就被攻击怎么办?如何防御DDoS?
开服初期是手游最脆弱的阶段,极易成为DDoS攻击的目标。一旦遭遇攻击,可能导致服务器瘫痪、玩家流失,甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案,帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...
零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?
一、核心优势:专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发,是一款收费低廉但功能全面的Windows NAS工具,主打“无学习成本部署” 。与其他NAS软件相比,其优势在于: 无需硬件改造:将任意W…...
全球首个30米分辨率湿地数据集(2000—2022)
数据简介 今天我们分享的数据是全球30米分辨率湿地数据集,包含8种湿地亚类,该数据以0.5X0.5的瓦片存储,我们整理了所有属于中国的瓦片名称与其对应省份,方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...
C++ 基础特性深度解析
目录 引言 一、命名空间(namespace) C 中的命名空间 与 C 语言的对比 二、缺省参数 C 中的缺省参数 与 C 语言的对比 三、引用(reference) C 中的引用 与 C 语言的对比 四、inline(内联函数…...
《基于Apache Flink的流处理》笔记
思维导图 1-3 章 4-7章 8-11 章 参考资料 源码: https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...
排序算法总结(C++)
目录 一、稳定性二、排序算法选择、冒泡、插入排序归并排序随机快速排序堆排序基数排序计数排序 三、总结 一、稳定性 排序算法的稳定性是指:同样大小的样本 **(同样大小的数据)**在排序之后不会改变原始的相对次序。 稳定性对基础类型对象…...
macOS 终端智能代理检测
🧠 终端智能代理检测:自动判断是否需要设置代理访问 GitHub 在开发中,使用 GitHub 是非常常见的需求。但有时候我们会发现某些命令失败、插件无法更新,例如: fatal: unable to access https://github.com/ohmyzsh/oh…...
云安全与网络安全:核心区别与协同作用解析
在数字化转型的浪潮中,云安全与网络安全作为信息安全的两大支柱,常被混淆但本质不同。本文将从概念、责任分工、技术手段、威胁类型等维度深入解析两者的差异,并探讨它们的协同作用。 一、核心区别 定义与范围 网络安全:聚焦于保…...
聚六亚甲基单胍盐酸盐市场深度解析:现状、挑战与机遇
根据 QYResearch 发布的市场报告显示,全球市场规模预计在 2031 年达到 9848 万美元,2025 - 2031 年期间年复合增长率(CAGR)为 3.7%。在竞争格局上,市场集中度较高,2024 年全球前十强厂商占据约 74.0% 的市场…...
IP选择注意事项
IP选择注意事项 MTP、FTP、EFUSE、EMEMORY选择时,需要考虑以下参数,然后确定后选择IP。 容量工作电压范围温度范围擦除、烧写速度/耗时读取所有bit的时间待机功耗擦写、烧写功耗面积所需要的mask layer...
