关于python:辣条君写爬虫5恋爱综艺心动的信号视频下载

43次阅读

共计 3061 个字符,预计需要花费 8 分钟才能阅读完成。

最近辣条君看到一部综艺《心动的信号》,打算看一看,学一学年轻人该怎么谈恋爱。可是,某讯视频要会员,从小艰苦朴素的辣条君当然抉择白嫖了。于是乎,发现有在线资源哎~

Tip: 本文仅供学习与交换,切勿用于非法用处!!!请大家反对正版!!!

剖析与思路

明天爬取的页面是http://www.ikanmv.com/k/39050.html。底下一共有 10 集。

咱们轻易关上一集,点击 network,发现视频是m3u8 格局的。有两个 m3u8 格式文件,第一个是一些限度条件,真正的 m3u8 列表。前面就是列表中逐条下载的 ts 文件。

咱们的指标是,把一集的所有 ts 文件下载下来,通过 ffmpeg 软件进行拼接、转化,最终生成一个.mp4 文件。ffmpeg从官网下载较慢,如有须要请戳上面连贯(windows10 版本)。

链接: https://pan.baidu.com/s/1_1htbaRQP_6y_G2xHOmWBw
提取码: wivw

其实间接用 ffmpeg 也能够依据 m3u8 列表连贯间接下载,然而速度较慢,咱们代码中应用多过程,减速下载。

不过还有个问题,通过测试,ffmpeg合并 ts 文件,一次性最多合并 4、5 百个(每集 ts 文件大略在 1500~2000 个之间),再多就会报错,所以咱们先以 300 个 ts 文件为 1 组,将他们合并一下,失去几个大个的 ts 文件,再将这几个大个的 ts 文件合并成一集一个整个的 ts 文件,再转化 mp4。

所以咱们的代码流程为:== 下载某集所有 ts 文件 -> 合并成几个大个的 ts 文件 -> 合并成一个 ts 文件 -> 转化成 mp4-> 删除没用的 ts 文件 ==

代码实现

首先创立一个文件夹 D:\ts 用于寄存 ts 文件。

依据上节的代码流程,咱们能够写出主函数,几个办法逐渐实现:

if __name__ == '__main__':
    urls = [
       'https://zy.kubozy-youku-163-aiqi.com/20190710/13975_9273f090/1000k/hls/index.m3u8',
       'https://zy.kubozy-youku-163-aiqi.com/20190717/14563_0eca69d7/1000k/hls/index.m3u8',
       'https://zy.kubozy-youku-163-aiqi.com/20190724/15218_7487f9e5/1000k/hls/index.m3u8'
    ]
    # 开始的集数
    index = 4
    for url in urls:
        # 获取某集须要下载的 ts 列表
        get_list = get_m3u8(url)
        # 下载 ts 文件到本地
        download('D:\\ts', get_list, url[0:-10])
        # 合并
        merge_ts('D:\\ts', str(index)+'.mp4')
        # 删除没用的 ts
        delete_ts('D:\\ts')
        # 下一集
        index = index + 1

咱们模仿下载 4~6 集(因为没找到法则,须要手动获取几集的第二个 m3u8 申请连贯)

轻易点击两个 ts 连贯就会发现,某一集的 ts 文件申请后面都是一样的,最初拼接上 xxxxx00x.ts,而后 get 申请就能够失去某个 ts 视频资源了。首先获取某集所有 ts 文件后缀,就是 ==xxxxx00x.ts 局部 ==,实现一下 get_m3u8 办法

# 获取某集须要下载的 ts 列表
def get_m3u8(url):
    result = requests.get(url)
    lines = result.text.split('\n')
    all_ts = []
    for line in lines:
        if line.endswith('.ts'):
            all_ts.append(line)
    return all_ts

而后下载到本地

# 下载一个 ts 文件
def download_ts(ts, root, url):
    res = requests.get(url+ts)
    with open(root+"\\" + ts, 'ab') as f:
        f.write(res.content)
        f.flush()
        print(ts+'下载结束!')

# 下载 ts 文件到本地
def download(root, get_list, url):
    # 曾经下载过的文件
    had_list = []
    # 还有没下载完的就持续
    while len(list(set(get_list).difference(set(had_list)))) > 0:
        had_list = os.listdir(root)
        # 还须要下载的
        needs = list(set(get_list).difference(set(had_list)))
        print('还须要下载个数为:'+str(len(needs)))
        pool = Pool(10)
        group = ([ts for ts in needs])
        pool.map(partial(download_ts, root=root, url=url), group)
        pool.close()
        pool.join()

download办法,即主函数中应用的办法。第一个参数 root 是 ts 视频下载的地址,第二个参数 get_list 是某集所有 ts 文件后缀 (==xxxxx00x.ts 局部 ==),第三个参数url 是某个 ts 申请前缀。首先这里用到了多过程,往期博客介绍过,这里照抄就好。

值得一提的时,这边有个 while 循环。因为多过程下载某集所有 ts 文件过程中,我发现可能会造成某些 ts 文件的失落未下载,所以每次下载实现,咱们获取已下载实现的文件名称(文件名称就是 ts 后缀),和某集所有的 ts 文件后缀,做差集。持续下载这些失落的,晓得差集为空,就证实全副下载结束。

接下来须要合并。

# 合并 ts,因为一次无奈合并那么多,合并两次
def merge_ts(root, name):
    os.chdir(root)
    all_ts = os.listdir(root)
    # 计数器
    counter = 0
    big_list = []
    per_list = []
    # 将多个 ts 文件名,300 为一组拼接在一起
    for ts in all_ts:
        if counter > 300:
            counter = 0
            big_list.append('+'.join(per_list))
            per_list = []
        else:
            counter = counter+1
            per_list.append(ts)

    batch = 0
    batch_ts = []
    for big in big_list:
        batch = batch + 1
        batch_ts.append(str(batch)+'.ts')
        os.system('copy /b' + big + f'batch{batch}.ts')
    shell_str = '+'.join(batch_ts)
    # 第二次拼接
    os.system('copy /b'+shell_str+' '+name)

这里须要两次合并,第二次合并和转 mp4 格局是一个脚本操作。这里应用 os.system 调用零碎办法,因为咱们的 ffmpeg 曾经放入到环境变量中,所以这里就是间接操作 ffmpeg 软件了。

生成某集的 mp4 文件之后,咱们须要删除根目录下所有的.ts 文件,一来节约硬盘空间,二来为下一集下载.ts 文件革除烦扰。

def delete_ts(root):
    os.chdir(root)
    all_file = os.listdir(root)
    for file in all_file:
        if file.endswith('.ts'):
            os.remove(root+'\\'+file)

以上咱们就能够下载到喜爱看的视频了。喜爱的小伙伴快去试试吧~

正文完
 0