前言
前两天尔羽说让我爬一下菜鸟窝的教程视频,这次就跟大家来说说 Python 爬取视频的经验
正文
https://www.cniao5.com/
菜鸟窝上有很多教程视频,但是这些视频好像没有直接的下载地址,而且有些教程视频还是有期限的,那么问题就产生了
我看的速度比较慢而且视频又很多,没等我看完视频就到期了怎么办?这时候写一个爬虫将这些教程视频下载下来就很好地解决了这个问题
当然,对于某些视频网站的 VIP 电影、视频之类的,一般情况下是无法在没有开通 VIP 的情况下用爬虫下载的,因为涉及到利益问题,同时数据传输也是加密的;想要看的话还是得开通会员再进行爬取
回到这次的目标上来,我们要爬取的是
https://www.cniao5.com/course/lessons/10153
上面的 24 章,共计 202 个教程视频
接下来我们来看看我们应该如何获取这些视频
首先我们看一下这个界面的源代码中没有关于课程视频的信息,那么我们点进去一个视频看看
通过开发者工具我们可以看到左侧都是这次加载视频是动态加载的信息,我们一个个来看
首先是url,我们可以看到这个链接是Post方式请求的(然鹅实际上再通过postman测试可以知道,并不用带上什么参数请求,吓唬人呢...)
这就是url返回的数据,其中hd、shd代表高清、超清的视频类型,而当你访问这个链接后会自动下载一个m3u8文件,这介绍一下
m3u8文件是指 UTF-8 编码格式的 M3U 文件。M3U 文件是记录了一个索引纯文本文件,打开它时播放软件并不是播放它,而是根据它的索引找到对应的音视频文件的网络地址进行在线播放
而我们下载视频的方式就是通过向m3u8文件中的这些 .ts的链接发送请求而下载一个个ts视频流 (暂时这么称呼)
下一个就是chapters,这里呢则是包含了所有 24 章视频的一些基本信息
注意这里的vid参数,之后我们会用到
这个就是网页上加载的m3u8文件
这看似乱码的ts文件下载下来后就是一个几秒钟的视频了
而我们最后要做的就是将这些ts文件合成为一个mp4文件
那么如何来操作呢?
思路
通过请求chapters的链接获取每一个章节中每一个lesson的播放url地址(就是返回中带有hd、shd的),取出并请求 hd 的链接,下载m3u8文件,匹配m3u8文件中的每一个ts,请求ts文件对应的链接并下载到本地,最后合成为一个mp4视频
来跟着代码看一下
首先小编是在本地先用代码创建好最终合成视频的存放的空文件夹以便访问
接着创建对应章节的文件夹
对章节中的每一个课程,获取其id、key、file_id创建对应的课程文件夹(用来保存ts文件)
对于之后则需要分为两种情况,我不知道菜鸟窝是怎么想的,你可以看到对于有的视频vid有具体的数值,有的则是 0
也就是说对于vid有值的我们可以很容易构造url链接从而获取m3u8文件进而下载ts视频;但是对于没有的来说就麻烦了,我们不能直接构造这个url链接
而对于这一类视频则是这样的
这类视频不是通过m3u8来处理视频的而是直接给了一个mp4的地址,那么也就是说对于vid为 0 的视频我们需要访问
https://playvideo.qcloud.com/getplayinfo/v2/1255567694/5285890782726972640
才可以拿到这个视频,那么这个 url 中后面的两个参数是什么呢
这个我们在上图中可以发现就是之前提到的file_id这也是我们为什么要获取的原因;而前面的你多看几个就知道这个是不变的
而当你去访问这个 MP4 的链接时菜鸟窝会告诉你,你没有权限请求这个链接,what?
而这时候你要知道所谓爬虫就是模拟人对浏览器进行的操作而获取一定的结果,那么我们可以带上请求头来试试,小编是在用 fiddler 抓包后肯定了这一点,最后测试发现只要带上 header 中的referer就可以访问
而这个referer也是有讲究的,这个后面跟的奇怪的参数正是上述中你们都快忘了的key,这个是每个lesson中都有的
所以对于这种情况,之后只要把请求MP4链接后的内容以二进制方式保存就行
此外还要注意对于ts文件,在请求时的前缀是
而在合并ts文件时,我用的是通过Python调用windows自带的合成的命令来合成,但是需要注意合成时候的文件名一定按001,002,...,010,...,099,100...如此排列;而如果按1,2,3,...,10,11,...,99,100则合并不会成功
所以在保存时就应该注意指定文件的名称即可
好了看到这里相信你应该有了一个基本的认识了,需要完整源码的也可以联系小编
领取专属 10元无门槛券
私享最新 技术干货