爬取优酷vip视频,下载ts格式的视频,并将视频保存为mp4格式的文件

爬取视频,首先想到的是找到视频的源.mp4文件,对于普通的视频很容易在网页源代码或者在开发者中找到对应的.mp4文件,但是想要爬取vip视频就没那么容易了,在网页源代码中,或者开发者中并没有找到对应的.mp4文件。昨天想爬取vip视频就找了相关的博客学习了下,收获了不少。在这里总结下。
找了优酷的vip视频,https://v.youku.com/v_show/id_XNDA0MDg2NzU0OA==.html?spm=a2h03.8164468.2069780.5
爬取优酷vip视频,下载ts格式的视频,并将视频保存为mp4格式的文件_第1张图片
在优酷中只能看6分钟。要想看完整的视频在优酷平台是不可能的了,更别提找到视频的源.mp4文件。所以得借助其他平台,在网上搜了些相关的资料,发现有很多网站可以解析vip视频,我选了这个
爬取优酷vip视频,下载ts格式的视频,并将视频保存为mp4格式的文件_第2张图片
把你要看的视频链接放在这了解析你就可以在此网站观看完整的视频,但是我要做的是下载视频,所以还得进一步分析。
打开Fiddle进行抓包,将视频的链接放在播放地址,点击全屏解析。视频打开后先播放一段时间,关闭Fiddle中止抓包,分析抓取到的接口。
爬取优酷vip视频,下载ts格式的视频,并将视频保存为mp4格式的文件_第3张图片
其中有个接口如下:
爬取优酷vip视频,下载ts格式的视频,并将视频保存为mp4格式的文件_第4张图片
这是个get请求,包含了全名解析视频的url和视频的url。看下他的response信息
爬取优酷vip视频,下载ts格式的视频,并将视频保存为mp4格式的文件_第5张图片
里面有个ajax字段的信息,发送的请求方式为post请求,里面的data为要提取的数据。这些信息我们可以编写代码提取出来。再接着看Fiddle下面捕获的数据。
爬取优酷vip视频,下载ts格式的视频,并将视频保存为mp4格式的文件_第6张图片
发现这里有个post请求,而且上面的data字段信息在这里都有。这个接口返回的数据是什么呢?构造代码查看。

import requests
import re
import json
class VIP(object):
    def __init__(self):
        self.api = 'http://yun.mt2t.com/lines?url='
        self.post_url = 'http://yun.mt2t.com/lines/getdata'
        self.url = 'https://v.youku.com/v_show/id_XNDA0MDg2NzU0OA==.html?spm=a2h03.8164468.2069780.5'
    def run(self):
        res = requests.get(self.api + self.url)
        html = res.content.decode()
        key = re.findall(r'key:.*?"(.*?)"', html)
        episode = re.findall(r'episode:(.*?),', html)
        name = re.findall(r'name:"(.*?)"', html)#这个字段为空,就不返回
        type = re.findall(r'type:"(.*?)".*?name', html)#这个字段为空,就不返回
        return key[0],episode[0]
    def get_playlist(self):
        key,episode = self.run()
        data = {
            "url":self.url,
            "key":key,
            "episode":episode
        }
        html = requests.post(self.post_url,data=data).content.decode()
        dic = json.loads(html)
        for d in dic:
            print(d)#先查看下输出的内容
            url = d['Url']#提取里面的Url再解析
            # url = 'http://y2.mt2t.com:91/ifr?url=rG7mvsvalVBQtYTfBb2j8l1vjFs%2fOmudRmSAcZXwT9w74YebSPlorQpY%2fbqhKB25gIOAhqqJtOBzhPvR%2bJnERQ%3d%3d&type=m3u8'得到的url为这种形式
            url = self.url2(url)
            print(url)
            # 'http://youku.kuyun-leshi.com/ppvod/17BE244D58718E511AFAEAF77ACC34F7.m3u8 '这是将url转义后的形式
    def url2(self,url):
        # url = 'http://y2.mt2t.com:91/ifrurl=rG7mvsvalVBQtYTfBb2j8l1vjFs%2fOmudRmSAcZXwT9w74YebSPlorQpY%2fbqhKB25gIOAhqqJtOBzhPvR%2bJnERQ%3d%3d&type=m3u8'
        url_param = url.replace("%2b", "+").replace("%3d", "=").replace("%2f", "/")#url为编码过后的字符串,如上形式,可以通过字符转义将Url转换过来
        return  url_param
if __name__ == '__main__':
    vip = VIP()
    vip.get_playlist()

这是上面返回的dic结果。有很多视频源从不同平台上转接过来,有爱奇艺的,芒果的等等,我们只需要其中的一个就可以。

[{"Url":"http://y2.mt2t.com:91/ifr?url=rG7mvsvalVBQtYTfBb2j8l1vjFs%2fOmudRmSAcZXwT9w74YebSPlorQpY%2fbqhKB25gIOAhqqJtOBzhPvR%2bJnERQ%3d%3d\u0026type=m3u8","Video_type":"1","Vid":null,"Scheme":"auto"},{"Url":"http://y2.mt2t.com:91/ifr?url=rG7mvsvalVBQtYTfBb2j8keSkr35i6LT1rM02IVKGh0olIjkZOQfqbvAYMRx%2bQR0q%2fx0C43SsRFOZDBdIKDZ%2fg%3d%3d\u0026type=kuyun","Video_type":"1","Vid":null,"Scheme":"auto"},{"Url":"http://y2.mt2t.com:91/ifr?url=a6tgiq6l1aQQZzObpXfOZ3Yx2pVlGEp12CtC4r6vtslI3m1Xbshtyi4WgAE8MO0p\u0026type=qq","Video_type":"1","Vid":null,"Scheme":"auto"},{"Url":"http://y2.mt2t.com:91/ifr?url=KuT7Bg63M9X8euMJDPneBNNsbxwIf7qrutSmx83GIXSndDD%2f2JtQGZrzqFdu9Egh\u0026type=爱奇艺","Video_type":"1","Vid":null,"Scheme":"auto"},{"Url":"http://y2.mt2t.com:91/ifr?url=HAoUzVAntrQdCkvIryzh%2bL8MmJ9XhqIrUXE1bER33OtqnqgH9x3FVLW4hv5HREX7\u0026type=芒果","Video_type":"1","Vid":null,"Scheme":"auto"},{"Url":"http://y2.mt2t.com:91/ifr?url=drqz2WBjm%2fCfVBLEkGaD%2fhsLgIMKwnCQ9ky6mvlAhPGQfLtn4ap555tkZyTn%2bpGilAfOMumJjZQrzt2vGcOvfA%3d%3d\u0026type=优酷","Video_type":"1","Vid":null,"Scheme":"auto"},{"Url":"http://y2.mt2t.com:91/ifr?url=k1z0pQ2anEEut%2fD7%2bpidOXUe7oWQ0sgHWCEakyObTlfU3pfqfQInM3i7%2bR1jA8IvRdzyFUYxx320ZV438yUdfw%3d%3d","Video_type":"1","Vid":null,"Scheme":"auto"}]

将上面提取的url经过编解码转换得到最终的url为
http://youku.kuyun-leshi.com/20190207/uw7GAIei/index.m3u8
关于m3u8是什么可以自己去网上搜索这里就不讲了。可以参考这篇博客下载ts文件
https://blog.csdn.net/qq_39797956/article/details/88076404
打开浏览器,发现下载了个文件,用记事本打开
http://youku.kuyun-leshi.com/ppvod/17BE244D58718E511AFAEAF77ACC34F7.m3u8
爬取优酷vip视频,下载ts格式的视频,并将视频保存为mp4格式的文件_第7张图片
爬取优酷vip视频,下载ts格式的视频,并将视频保存为mp4格式的文件_第8张图片

import requests
import time
class CatchVideo(object):
    def __init__(self):
        self.url = ""
    def file(self,i):
        if i < 1000:
            str1 = '000'
            l1 = len(str1)
            str2 = str(i)
            l = len(str2)
            new = str(str1[0:l1 - l]) + str2
            print(new)
            return new
        else:
            str1 = '0000'
            l1 = len(str1)
            str2 = str(i)
            l = len(str2)
            new = str(str1[0:l1 - l]) + str2
            print(new)
            return new
            
    def run(self):
        for i in range(1609):
            d = self.file(i)
            self.url = "http://youku.kuyun-leshi.com/20190207/uw7GAIei/800kb/hls/2X5eBP1465%s.ts" % d
            print(self.url)
            res = requests.get(url=self.url).content#这是视频文件下载的是二进制数据
            filename = self.url.split('/')[-1]
            filename = filename.split('.')[0] + '.ts'
            with open(filename,'wb') as f:
                f.write(res)
if __name__ == '__main__':
    catchvideo = CatchVideo()
    catchvideo.run()

在下载文件的路径下打开cmd窗口,输入命令将所有的ts文件保存为mp4格式的文件
在这里插入图片描述

添加个多线程爬取,因为上面的ts视频太多,所以改进下代码如下:

import requests
import time
import threading
class CatchVideo(threading.Thread):
    def __init__(self):
        super().__init__()
        self.url = ""
    def file(self,i):
        if i < 1000:
            str1 = '000'
            l1 = len(str1)
            str2 = str(i)
            l = len(str2)
            new = str(str1[0:l1 - l]) + str2
            print(new)
            return new
        else:
            str1 = '0000'
            l1 = len(str1)
            str2 = str(i)
            l = len(str2)
            new = str(str1[0:l1 - l]) + str2
            print(new)
            return new

    def run(self):
        for i in range(1609):
            d = self.file(i)
            self.url = "http://youku.kuyun-leshi.com/20190207/uw7GAIei/800kb/hls/2X5eBP1465%s.ts" % d
            print(self.url)
            res = requests.get(url=self.url).content#这是视频文件下载的是二进制数据
            filename = self.url.split('/')[-1]
            filename = filename.split('.')[0] + '.ts'
            with open(filename,'wb') as f:
                f.write(res)
if __name__ == '__main__':
    for i in range(5):开启5个线程,这里可以设置任意个线程数
        t = CatchVideo()
        t.start()
    for i in range(5):
        t.join()

你可能感兴趣的:(Python)