这两天博主在摸鱼时,偶然间接触到了流媒体的概念,一时间来了兴致。再加上之前博主有着七、八年的视频制作经验,深知视频素材获取的不易。因此,打算利用自己所学的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视频的分析实战相关推荐

  1. Python小姿势 - # Python网络爬虫之如何通过selenium模拟浏览器登录微博

    Python网络爬虫之如何通过selenium模拟浏览器登录微博 微博登录接口很混乱,需要我们通过selenium来模拟浏览器登录. 首先我们需要安装selenium,通过pip安装: ``` pip ...

  2. Python网络爬虫入门篇---小白必看

    1.  预备知识 学习者需要预先掌握Python的数字类型.字符串类型.分支.循环.函数.列表类型.字典类型.文件和第三方库使用等概念和编程方法. 2. Python爬虫基本流程 a. 发送请求 使用 ...

  3. python网络爬虫——自学笔记1.用requests库爬取图片

    1.requests库的安装 rrequests库是公认的python的一个一个非常优秀的第三方库,下载方法也很简单 只需Win+R打开控制台命令窗口,输入pip install requests后回 ...

  4. python网络爬虫系列(四)——requests模块

    requests模块 知识点: 掌握 headers参数的使用 掌握 发送带参数的请求 掌握 headers中携带cookie 掌握 cookies参数的使用 掌握 cookieJar的转换方法 掌握 ...

  5. Python 网络爬虫2:第三方库requests 渗透脚本的编写(SQL注入的EXP,主机发现、端口扫描)

    文章目录 Python 编写EXP requests库的使用 http方法 发送http请求 定制头部 超时 GET传参 POST传参 上传文件 COOKIE 使用爬虫爬取网页中所有课程的名字 使用p ...

  6. 手把手教你使用Python网络爬虫获取B站视频选集内容(附源码)

    点击上方"Python爬虫与数据挖掘",进行关注 回复"书籍"即可获赠Python从入门到进阶共10本电子书 今 日 鸡 汤 位卑未敢忘忧国,事定犹须待阖棺. ...

  7. Python 网络爬虫与数据采集(二)

    Python 网络爬虫与数据采集 第二部分 初章 网络爬虫初识 4. 网络爬虫请求篇 4.1 requests 库简介 4.1.1 Requests 的安装 4.1.2 Requests 基本使用 4 ...

  8. python网络爬虫之解析网页的正则表达式(爬取4k动漫图片)[三]

    目录 前言 一.正则表达式的学习 1.正则表达式的匹配工具 2.正则表达式的样式 3.正则表达式的案例 二.爬取网页图片 1.分析网页 2.获取数据 爬取妹子网的案例 后记 前言 hello,大家好 ...

  9. python网络爬虫教程-终于明了python网络爬虫从入门到实践

    Python是一款功能强大的脚本语言,具有丰富和强大的库,重要的是,它还具有很强的可读性,易用易学,非常适合编程初学者入门.以下是小编为你整理的python网络爬虫从入门到实践 环境配置:下载Pyth ...

最新文章

  1. 2009年8月26日,用于win2003上的MSN不能正常使用
  2. linux tomcat 隐藏版本号
  3. LeetCode 110 Balanced Binary Tree 平衡二叉树
  4. 博客开通了....激动 呵呵
  5. scala创建并使用Enumerations
  6. python --- opencv部分学习
  7. 【图论】清理牛棚/Cleaning Shifts S(luogu 4644)
  8. badboy的录制和jmeter的使用
  9. iOS/Android自动化云测试工具iTestin 1.0发布
  10. 开启smb协议_SMB协议(使用说明+过程详解+抓包分析)
  11. 计算机二级c语言考试真题及答案详解,2021全国计算机二级C语言程序设计历年真题及答案节选...
  12. JavaWebServlet学生教师信息管理系统【JavaWeb】Servlet+Mysql+Jsp+Tomcat
  13. Cross-Modality Domain Adaptation
  14. .equal(String)与Stirng.equal()的区别
  15. Mac OS下安装Photoshop CC 2017破解版
  16. 支持持久化的基础设施代码所需的企业模式
  17. 三颗锦囊用完,苹果新iPad今年挡得住两大集团军吗?
  18. 互联网的996与华为的惊世骇俗
  19. ORACLE ORA-01950 对表空间无权限
  20. 外贸推广方式有哪些,外贸推广怎么做

热门文章

  1. js版四舍六入五成双方法
  2. ffmpeg js转换音频_webRTC使用ffmpeg.js将webm转换为mp4
  3. 启动PE系统找不到计算机硬盘,解决方法:如何解决戴尔计算机进入PE系统时找不到硬盘的问题...
  4. 基于微信小程序评选投票系统 投票小程序毕业设计 毕业论文 开题报告和效果图
  5. MacOS没有管理员账号的解决方法
  6. 未来计算机长啥样,未来人类到底会长成啥样?科学家公布最终模拟图!
  7. 2018 ACM-ICPC Syrian Collegiate Programming Contest(部分题解,待补)
  8. pwm一个时间单位_详解PWM原理、频率与占空比
  9. 网络最大流模板(标号法)
  10. 标号法(Dijkstra)求最短路 matlab