【Python网络爬虫实战篇】使用selenium+requests爬取下载高清源视频:关于爬取m3u8文件链接解析为ts视频合并成mp4视频的分析实战
这两天博主在摸鱼时,偶然间接触到了流媒体的概念,一时间来了兴致。再加上之前博主有着七、八年的视频制作经验,深知视频素材获取的不易。因此,打算利用自己所学的python网络爬虫的知识,通过编写代码实现获取视频解析m3u8链接完成视频的下载功能。
目录
- 流媒体
- 流媒体的介绍
- 流媒体的分类
- 分析实战
- 编码过程
- 整体代码
- 总结
流媒体
流媒体的介绍
流媒体:从远程服务器传输过来的文件流(分段传输,例如:.ts视频)。
流媒体的分类
1.伪流媒体:边下边存,会保存下来,渐进式下载。
- 特征:能够暂停、看到时间(时长)、快进、后退。
- 协议:http/https。
2.实时流媒体:边下边播,不会保存,看不到时间。
- 协议:HLS(苹果端,流媒体的传输协议)/RTMP协议(Adobe,实时消息传输协议)
- 框架:ffmpeg(底层由纯C语言编写,用来进行解码的音视频播放器框架)
- 实时流媒体图示:
其中:
① ts:高清单独编辑码的视频文件。
② m3u8:记录文件的文件,ts的顺序记录在m3u8文件中。
- 视频合成指令(需要按照顺序命名,多个ts合并成一个ts):
cat *.ts>hecheng.mp4 # mac
copy /b *.ts hecheng.mp4 # windows
分析实战
编码过程
1.通过selenium的无头模式获取视频名称和m3u8长链接。
from selenium import webdriverurl = 'http://jx.618g.com/?url=https://v.qq.com/x/cover/0pj8vuntnocu797/o0034hawh6r.html'
# 开启无头模式提取视频m3u8路径地址
chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument('--headless')
browser = webdriver.Chrome(options=chrome_options)
videoAnalysis = browser.get(url)
videoName = browser.title # 获取当前页面title值
print(videoName)
videoSrcAll = browser.find_element_by_id('player').get_attribute('src')
print(videoSrcAll)
browser.close()
2.观察输出结果,发现我们所需要的m3u8链接的url应该是获取到的长链接去除http://jx.618g.com/m3u8-dp.php?url=的url,因此,我们只需要保留等于号后面的内容即可。
# 链接分割取出真正的m3u8
videoSrc = str(videoSrcAll).split('=')[1] # 取出“=”分割的右半部分
print(videoSrc) # 输出我们所需的url
res = requests.get(videoSrc).text
print(res) # 输出我们所需的url的内容
加上上述代码观察输出结果,发现我们已经成功解析出了我们所需要的m3u8链接的url。其中输出的url内容如下所示:
#EXTM3U
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=800000,RESOLUTION=1080x608
1000k/hls/index.m3u8
url的内容表示m3u8链接作了跳转,这个只是将文件设置为二次访问获取真实地址。因此我们只需将m3u8链接改为 https://iqiyi.cdn27-okzy.com/20200802/6686_1e6ee0d8/1000k/hls/index.m3u8 再次请求访问内容才能得到真正的m3u8文件内容。
3.将链接复制粘贴到浏览器,浏览器会自动下载m3u8文件,那么我们可以以此为模板,将刚刚第2步获取到的m3u8链接与其内容的第三行进行整合。
getShortSrc = res.split('\n')[2] # 获取文件第三行内容
print(getShortSrc)
noindexurl = url.replace('index.m3u8', '') # 删除url的index.m3u8
trueUrl = noindexurl + getShortSrc # 得到m3u8二次链接(真正的m3u8链接)
print(trueUrl)
4.整合成功后,我们对真正的m3u8链接进行请求。
res1 = requests.get(trueUrl).text
print(res1)
观察m3u8文件内容,其中第一行 “#EXTM3U” 表明这是一个 m3u8 格式的视频文件,“#EXTINF”后面的一行链接便是每一个视频流的文件地址。如果将链接输入到浏览器中访问,你将得到一个以 .ts 结尾的几秒钟视频文件。这个m3u8文件中所有的链接全部请求合并得到的就是一个完整的视频。
有时候得到的 m3u8 文件不一样,会有一行 “#EXT-X-KEY” ,说明这个视频是经过加密的,需要我们去解密才能得到视频,否则得到的视频文件打开就会报错。本次实战的视频解析网站解析出来的m3u8链接经过测试并未进行加密,因此不进行加密情况的讨论。
5.接下来,我们需要提取出每一个ts视频链接并保存到列表中。根据第4步观察的ts视频名称,我们需要按照第3步的整合方法ts视频名称前加上前缀“https://iqiyi.cdn27-okzy.com/20200802/6686_1e6ee0d8/1000k/hls/”,这样整合而成的ts链接才是真正下载下来能观看的高清单独编辑码的视频文件。(注意:ts链接前缀和m3u8链接前缀相同,不同的只是将index.m3u8改成ts名称)之后,将ts链接全部保存在一个列表中。
tslist = re.findall('EXTINF:(.*),\n(.*)\n#', res1) # 得到每一个ts视频名称
newlist = []
for i in tslist:newlist.append(i[1]) # 将ts视频名称添加到列表中
# print(newlist) # 输出列表
noindextrueurl = trueUrl.replace('index.m3u8', '') # 删除trueurl的index.m3u8
tslisturl = [] # 构造链接空列表
for i in newlist:tsurl = noindextrueurl + itslisturl.append(tsurl)
print(tslisturl) # 输出列表
6.获取所有的ts链接并合并成mp4视频。这一步在本次实战中由于我是用普通文件二进制追加(ab+)的形式合并的,因此速度较慢。建议有能力的同学尝试改用多线程,因为我还没学习多线程这一块暂时就这样了,未来会进行多线程的改写。
def downloadvideo(urllist, videoName):header = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36'}path = './' + videoName.strip() + ".mp4"videolen = len(urllist)for i in urllist:print("视频下载中...剩余" + str(videolen) + "个ts视频未下载!")videolen = videolen - 1r = requests.get(i, header).content# tsname = i[-9:-3] + '.ts'with open(path, 'ab+') as f:f.write(r)# f.close()print("视频下载完毕!")
整体代码
from selenium import webdriver
import requests
import redef getvideourl(url):# 开启无头模式提取视频m3u8路径地址chrome_options = webdriver.ChromeOptions()chrome_options.add_argument('--headless')browser = webdriver.Chrome(options=chrome_options)browser.get(url)videoName = browser.title # 获取当前页面title值print(videoName) # 输出视频名称videoSrcAll = browser.find_element_by_id('player').get_attribute('src')# print(videoSrcAll) # 输出视频m3u8长链接(带前缀)browser.close()# 链接分割取出第一个m3u8链接videoSrc = str(videoSrcAll).split('=')[1] # 取出“=”分割的右半部分# print(videoSrc) # 输出视频m3u8第一个链接res = requests.get(videoSrc).text# print(res) # 输出所请求的m3u8第一个链接中的内容getShortSrc = res.split('\n')[2]# print(getShortSrc) # 获取m3u8第一个链接中的内容的第三行noindexurl = videoSrc.replace('index.m3u8', '') # 删除第一个m3u8链接的index.m3u8# 得到m3u8二次链接(真正的m3u8链接)trueUrl = noindexurl + getShortSrc# print(trueUrl) # 输出真正的m3u8链接(第二个m3u8链接)res1 = requests.get(trueUrl).text# print(res1) # 输出真正的m3u8链接的内容(第二个m3u8链接)tslist = re.findall('EXTINF:(.*),\n(.*)\n#', res1) # 得到每一个ts视频链接newlist = []for i in tslist:newlist.append(i[1])# print(newlist) # 输出列表noindextrueurl = trueUrl.replace('index.m3u8', '') # 删除trueurl的index.m3u8tslisturl = []for i in newlist:tsurl = noindextrueurl + itslisturl.append(tsurl)print(tslisturl) # 输出列表return tslisturl, videoNamedef downloadvideo(urllist, videoName):header = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36'}path = './' + videoName.strip() + ".mp4"videolen = len(urllist)for i in urllist:print("视频下载中...剩余" + str(videolen) + "个ts视频未下载!")videolen = videolen - 1r = requests.get(i, header).content# tsname = i[-9:-3] + '.ts'with open(path, 'ab+') as f:f.write(r)# f.close()print("视频下载完毕!")if __name__ == '__main__':getVideoUrl = input("请输入视频链接:") # https://v.qq.com/x/cover/0pj8vuntnocu797/o0034hawh6r.htmlurl = 'http://jx.618g.com/?url=' + getVideoUrltslisturl,videoName = getvideourl(url) # 获取ts视频列表downloadvideo(tslisturl, videoName) # 下载视频
总结
本次实战由于采用普通文件二进制追加(ab+)的形式将ts视频合并成mp4视频,因而耗费时间较长,所以不再展示最终效果图。但是经过亲身测试,已经证明了代码的可行性,只是实用性不强(下载太慢),未来会更新为多线程下载方式。本次对视频的爬取下载,只是为了学习了解m3u8文件的构造。总体来说较为成功。
【Python网络爬虫实战篇】使用selenium+requests爬取下载高清源视频:关于爬取m3u8文件链接解析为ts视频合并成mp4视频的分析实战相关推荐
- Python小姿势 - # Python网络爬虫之如何通过selenium模拟浏览器登录微博
Python网络爬虫之如何通过selenium模拟浏览器登录微博 微博登录接口很混乱,需要我们通过selenium来模拟浏览器登录. 首先我们需要安装selenium,通过pip安装: ``` pip ...
- Python网络爬虫入门篇---小白必看
1. 预备知识 学习者需要预先掌握Python的数字类型.字符串类型.分支.循环.函数.列表类型.字典类型.文件和第三方库使用等概念和编程方法. 2. Python爬虫基本流程 a. 发送请求 使用 ...
- python网络爬虫——自学笔记1.用requests库爬取图片
1.requests库的安装 rrequests库是公认的python的一个一个非常优秀的第三方库,下载方法也很简单 只需Win+R打开控制台命令窗口,输入pip install requests后回 ...
- python网络爬虫系列(四)——requests模块
requests模块 知识点: 掌握 headers参数的使用 掌握 发送带参数的请求 掌握 headers中携带cookie 掌握 cookies参数的使用 掌握 cookieJar的转换方法 掌握 ...
- Python 网络爬虫2:第三方库requests 渗透脚本的编写(SQL注入的EXP,主机发现、端口扫描)
文章目录 Python 编写EXP requests库的使用 http方法 发送http请求 定制头部 超时 GET传参 POST传参 上传文件 COOKIE 使用爬虫爬取网页中所有课程的名字 使用p ...
- 手把手教你使用Python网络爬虫获取B站视频选集内容(附源码)
点击上方"Python爬虫与数据挖掘",进行关注 回复"书籍"即可获赠Python从入门到进阶共10本电子书 今 日 鸡 汤 位卑未敢忘忧国,事定犹须待阖棺. ...
- Python 网络爬虫与数据采集(二)
Python 网络爬虫与数据采集 第二部分 初章 网络爬虫初识 4. 网络爬虫请求篇 4.1 requests 库简介 4.1.1 Requests 的安装 4.1.2 Requests 基本使用 4 ...
- python网络爬虫之解析网页的正则表达式(爬取4k动漫图片)[三]
目录 前言 一.正则表达式的学习 1.正则表达式的匹配工具 2.正则表达式的样式 3.正则表达式的案例 二.爬取网页图片 1.分析网页 2.获取数据 爬取妹子网的案例 后记 前言 hello,大家好 ...
- python网络爬虫教程-终于明了python网络爬虫从入门到实践
Python是一款功能强大的脚本语言,具有丰富和强大的库,重要的是,它还具有很强的可读性,易用易学,非常适合编程初学者入门.以下是小编为你整理的python网络爬虫从入门到实践 环境配置:下载Pyth ...
最新文章
- 2009年8月26日,用于win2003上的MSN不能正常使用
- linux tomcat 隐藏版本号
- LeetCode 110 Balanced Binary Tree 平衡二叉树
- 博客开通了....激动 呵呵
- scala创建并使用Enumerations
- python --- opencv部分学习
- 【图论】清理牛棚/Cleaning Shifts S(luogu 4644)
- badboy的录制和jmeter的使用
- iOS/Android自动化云测试工具iTestin 1.0发布
- 开启smb协议_SMB协议(使用说明+过程详解+抓包分析)
- 计算机二级c语言考试真题及答案详解,2021全国计算机二级C语言程序设计历年真题及答案节选...
- JavaWebServlet学生教师信息管理系统【JavaWeb】Servlet+Mysql+Jsp+Tomcat
- Cross-Modality Domain Adaptation
- .equal(String)与Stirng.equal()的区别
- Mac OS下安装Photoshop CC 2017破解版
- 支持持久化的基础设施代码所需的企业模式
- 三颗锦囊用完,苹果新iPad今年挡得住两大集团军吗?
- 互联网的996与华为的惊世骇俗
- ORACLE ORA-01950 对表空间无权限
- 外贸推广方式有哪些,外贸推广怎么做
热门文章
- js版四舍六入五成双方法
- ffmpeg js转换音频_webRTC使用ffmpeg.js将webm转换为mp4
- 启动PE系统找不到计算机硬盘,解决方法:如何解决戴尔计算机进入PE系统时找不到硬盘的问题...
- 基于微信小程序评选投票系统 投票小程序毕业设计 毕业论文 开题报告和效果图
- MacOS没有管理员账号的解决方法
- 未来计算机长啥样,未来人类到底会长成啥样?科学家公布最终模拟图!
- 2018 ACM-ICPC Syrian Collegiate Programming Contest(部分题解,待补)
- pwm一个时间单位_详解PWM原理、频率与占空比
- 网络最大流模板(标号法)
- 标号法(Dijkstra)求最短路 matlab