Python实现下载视频

        首先

我爬取的是茶杯狐网站的视频,视频为m3u8格式,需要下载多个小片段最后再进行拼接。

网址为   

茶杯狐 cupfox官网-最新电影电视剧免费在线观看 (shjhbox.com)icon-default.png?t=N6B9https://www.shjhbox.com/

因为拼接过程中需要使用到ffmpeg软件,所以要在系统中进行环境变量的配置,具体参考如下

windows安装ffmpeg并配置环境变量_ffmpeg环境变量配置_wanggangname的博客-CSDN博客icon-default.png?t=N6B9https://blog.csdn.net/wanggangname/article/details/126335944

需要注意的是,配置完成后,应在命令行中输入ffmpeg -version命令检测是否配置成功,有些电脑的python编译器可能无法立即检测到环境变量是否配置,重启之后即可解决。

配置完成如下

 

接下来是Python代码

import os
import re
import threading
import time
from concurrent.futures import ThreadPoolExecutor, wait

import requests

# 定义全局变量,记录ts文件下载数
num = 0
headers = {
    "User-Agent":
        "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36"
}
# 电影名称
name = ''


def get_m3u8_list(url):
    global name
    session = requests.Session()
    # 获取网页内容
    resp = session.get(url, headers=headers).text
    # 获取标题
    name = re.findall("var vod_name = '(.*?)'", resp)[0].replace(' ', '')
    # 获取第一个m3u8的内容
    first_m3u8_url = re.findall('"link_pre":"","url":"(.+?index.m3u8)"', resp)[0].replace('\\', '')
    first_m3u8 = session.get(first_m3u8_url, headers=headers)
    # 获取第二个m3u8的内容
    if 'http' in first_m3u8.text:
        second_m3u8_url = re.findall('(http.*?m3u8)', first_m3u8.text)[0]
    else:
        second_m3u8_url = 'https:' + '//' + first_m3u8_url.split('/')[2] + '/' + \
                          re.findall('/(.*?m3u8)', first_m3u8.text)[
                              0]
    second_m3u8 = session.get(second_m3u8_url, headers=headers)
    m3u8_url_list = re.findall('(htt.*?ts)', second_m3u8.text)
    return m3u8_url_list


# 下载单个ts文件
def download_one_m3u8(m3u8_url, path, i):
    global num
    m3u8 = requests.get(m3u8_url, headers=headers)
    print(i, '开始下载')
    with open(path + f'/{i}.ts', mode='wb') as f:
        f.write(m3u8.content)
    print(i, '下载完成')
    # 每下载一个文件,数量加1
    num += 1


# 下载全部ts文件
def download_all_m3u8(lists):
    path = './' + name
    if not os.path.exists(path):
        os.mkdir(path)
    # 创建线程池
    pool = ThreadPoolExecutor(200)
    i = 0
    tasks = []
    for item in lists:
        tasks.append(pool.submit(download_one_m3u8, item, path, i))
        i += 1
    # 等待下载完毕
    wait(tasks)
    merge(path)


def merge(filePath, filename='output'):
    '''
    进行ts文件合并 解决视频音频不同步的问题 建议使用这种
    :param filePath:
    :return:
    '''
    # 根据当前文件名称的数字进行排序
    file_list = sorted(os.listdir(filePath), key=lambda x: int(x.split('.')[0]))
    length = len(file_list)
    # ./ts/1.ts|./ts/2.ts ...
    # ffmpeg 无法一次拼接过多文件,应分开拼接,最后合并
    for i in range(int(length / 100) + 1):
        Str = ''
        # 一次拼接100个
        for j in range(i * 100, (i + 1) * 100):
            if j == length:
                break
            Str += f'{filePath}/' + file_list[j] + '|'
        cmd = f'ffmpeg -i "concat:{Str}" -c copy "{name + str(i)}.ts"'
        print(os.system(cmd))
    mp4 = ''
    # 拼接最终的文件
    for i in range(int(length / 100) + 1):
        mp4 += f'./{name + str(i)}.ts|'
    cmd = f'ffmpeg -i "concat:{mp4}" -c copy "./电影/{name}.mp4"'
    print(os.system(cmd))
    # 删除中间过程中产生的ts文件
    for i in range(int(length / 100) + 1):
        remove = f'del {name + str(i)}.ts'
        os.system(remove)
    # 删除所有ts文件
    os.system(f'rd {name} /s /q ')

    merge(f'./{name}')


# 定时执行结束函数,强制程序退出
def jieshu():
    global num
    # 循环检查当前是否在下载文件,如果超出30秒未下载文件,则停止下载,并将已下载的文件拼接完整
    while 1:
        num1 = num
        print('已下载', num)
        time.sleep(30)
        if num1 == num:
            merge(f'./{name}')
            print('下载结束')
            os.system("taskkill /f /t /im python.exe")


if __name__ == '__main__':
    url = input('请输入url')
    print('开始下载')
    # url = 'https://www.shjhbox.com/vodplay/66776-1-1.html'
    # 创建文件夹
    if not os.path.exists('./电影'):
        os.mkdir('./电影')

    # 获取下载文件目录
    m3u8_url_list = get_m3u8_list(url)
    # 开始计时
    threading.Thread(target=jieshu).start()
    print('over')
    # 开始下载
    download_all_m3u8(m3u8_url_list)

 有些软件包可能需要自己下载,如果无法下载的话建议使用阿里的源进行下载。

效果展示

 

而且,这个网站可能会比较卡,所以建议线程开的少一点,代码中同时开了100个线程,

并且设置了如果30秒没有下载任何文件,则直接停止下载,并将已下载好的视频拼接完成,

也可以适当延长时间

url的输入格式为播放页的地址,如下

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

财大彭于晏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值