庆余年-分享

庆余年-分享

十二月 13, 2019 阅读 232 字数 2950 评论 0 喜欢 0

  最近热播大剧庆余年很火,小编也是很是喜欢的不行;奈何开了会员,还是需要交钱才可以看剧;关键50大洋才能看6集;实在是肉疼;万般无奈下百度了下资源网站;终于找到一个网站可以看剧,可是呢,我喜欢上下班是煲剧,必须下载;但这类网站并没有下载入口,还好懂点python,稍微分析了下这个视频网站。
  现在很多视频网站播放流视频,都不是采用mp4/flv文件直接播放,而是采用m3u8/ts这种方式播放。简单说就是,网站后台把视频切片成成百上千个xx.ts文件,一般10秒一个,每个都几百kb很小。然后通过xx.m3u8播放列表把这些文件连接起来。
  我们打开Chrome开发者模式,点击视频可以看得到自动请求m3u8的接口,接口返回了视频所有的ts文件名称,ts文件就是我们的视频,一整个视频被拆分为若干个‘ts’文件;可以看得出所有的ts文件请求的部分url都是一样的,只是后面的文件名不一样,这样就找到有迹可循。
blob

blob

图1 中index.m3u8接口返回的是所有‘ts’文件的信息,我们需要将他download下来,合成成一个文件就可以形成我们所需要的视频文件啦!
blob
这是我下载好了的,先做个展示:grin:
话不多说,先来说下怎么下载的,给自己做个笔记。

由简入繁

简单的方式
1、手动获取m3u8所有信息,用sublime工具将所有的ts文件拼接起来,做成一个列表;遍历url,使用requests库模拟请求,请求的结果返回的就是一个ts文件,将接口返回response保存到本地文件;文件下载完了就是合成文件了,我们不适用python的方式合并,原因很简单,合成速度很慢。
使用windows 中的cmd命令秒合成;几乎只有1秒左右;命令如下copy /b *.ts 26.mp4(‘b’代表以二进制方式,‘*.ts’ 表示所有以ts结尾的文件,‘26.mp4’表示新文件的格式和名称)

import requests
#列表中只选取了两个url做示例
url_li = [
    'https://iqiyi.cdn9-okzy.com/20191211/3274_e27e75a3/1000k/hls/b0a9b597937000000.ts',
    'https://iqiyi.cdn9-okzy.com/20191211/3274_e27e75a3/1000k/hls/b0a9b597937000001.ts'
]

directory = r'C:\Users\admin\Downloads\电影\27\\'

for i in url_li:
    filename = directory + i.split('/')[-1]

    res = requests.get(i,stream = True)
    # 将请求的结果保存到文件中
    with open(filename,'wb') as file:
        file.write(res.content)
        #打印下response状态
        print(res.status_code)

2、逻辑很简单,其实shell就也可以做;我们将每段ts文件放入数组中,for遍历url,Linux中有个非常好用的下载命令wget;只要在wget + url链接就可以帮你下载;真是完美!但是Linux下没有好的合成文件方式,我还是在windows下的cmd命令,毕竟是秒合成!秒合成!秒合成!

#!/bin/bash
my_array=('https://iqiyi.cdn9-okzy.com/20191211/3274_e27e75a3/1000k/hls/b0a9b597937000000.ts'
'https://iqiyi.cdn9-okzy.com/20191211/3274_e27e75a3/1000k/hls/b0a9b597937000691.ts')

for i in ${my_array[@]}
do
    wget $i
done

blob
不得不说Linux的命令简单又强大 :+1: :+1: :+1:

深入点

虽然以上两种方式比较简单,但不够自动化,还需要手动操作的东西比较多

from contextlib import closing
import requests


class qinyunian():

    def __init__(self,filename,url,directory):
        self.filename = filename
        self.url = url
        self.directory = directory
        with open(self.filename,'wb') as f:
            f.write(requests.get(self.url).content)

    def get_url(self):
        rel_url = []
        with open(self.filename,'r') as f:
            for i in f:
                if i[0] != '#':
                    rel_url.append(self.url[:-10] + i)
        print(rel_url)
        return rel_url


    def download_movie(self):

        rel_url = self.get_url()

        for i in rel_url:
            path = (self.directory+i.split('/')[-1]).strip('\n').strip(' ')

            with closing(requests.get(i.strip('\n').strip(' '), stream=True)) as response:

                with open(path, "wb") as file:
                    for data in response.iter_content():
                        file.write(data)
                        print('下载成功')


if __name__ == '__main__':

    '''
    url: m3u8源文件,返回ts文件名
    directory:下载保存到哪个目录下
    filename:设置m3u8文件的文件名,防止重复
    '''
    url = 'https://youku.com-iqiyi.net/20191216/22687_ac28360f/1000k/hls/index.m3u8'
    directory = r'C:\Users\admin\Downloads\电影\29\\'
    filename = '29-' + url.split('/')[-1]

    sp = qinyunian(filename,url,directory)
    sp.download_movie()

  我们只要将m3u8源文件的url拿到,用python将所有ts文件下载完成后使用cmd命令合成就可以啦!
  当然python下载这些ts文件有多种方式,比较原始的使用response返回iter_content写入文件,也可以使用you-get库下载这些视频,虽然库简化了逻辑,但在下载速度上不敢恭维啊!下载一个m3u8需要近2小时,等的花儿都谢了!
  代码可以进一步优化,爬取整个页面,获取每集的m3u8源文件,多线程模式下载合成;毕竟单线程太慢了。

战况!!!看完庆余年 :relieved::relieved::relieved:
真香!
blob

分享庆余年的链接:
  链接: https://pan.baidu.com/s/1ot2wk9BWWa19dgjnpme79Q 提取码: 8mwp
链接老是被屏蔽,我只能呵呵啦!!

发表评论

电子邮件地址不会被公开。 必填项已用*标注