python下载在线播放视频,下载器V2.0,TS爬虫

python下载在线播放视频,下载器V2.0

这个版本属于懒人版本,直接把播放的网页复制粘贴就可以下载了,部分可以下载,但是不是所有的网站都可以,还是有bug的哈,大家可以根据需要进行更改。

import time,asyncio,aiohttp,re,os,requests,threading
from alive_progress import alive_bar

class download_video():
    def __init__(self,dir_name):
        self.dir_name = dir_name
        self.url = input('\n请输入可播放视频的地址:')
        # self.ts_url = input('\n请输入ts文件的前半段(必须):')

    # 获取m3u8文件的信息
    def get_m3u8_first(self):
        global headers,authority
        headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36'}
        url = self.url
        m3u8_first = requests.get(url=url,headers=headers)
        m3u8_first.encoding = m3u8_first.apparent_encoding
        m3u8_first_url = re.findall(r'https://(.*?)\.m3u8',m3u8_first.text.replace('\\',''))[0]
        authority = m3u8_first_url.strip().split('/')[0]
        headers.update({'authority':authority})
        return 'https://'+m3u8_first_url+'.m3u8'
    # 获取带有ts文件列表的url
    def get_m3u8_second(self,m3u8_first_url):
        url = m3u8_first_url
        m3u8_seconde = requests.get(url=url,headers=headers)
        m3u8_seconde.encoding = m3u8_seconde.apparent_encoding
        m3u8_seconde_url = re.findall(r'/(.*)',m3u8_seconde.text)[0]
        return 'https://'+authority+'/'+m3u8_seconde_url

    # 获取并保存ts文件列表
    def get_ts_list_key(self,url,dir_name):
        dict_ts = {}
        authority = re.findall(r'://(.*)',url)[0].strip().split('/')[0]
        name = dir_name.split('\\')[-1]
        ts_list = []
        ts_html = requests.get(url=url,headers=headers)
        ts_html.encoding = ts_html.apparent_encoding
        # 判断是否有key存在,有就下载下来,没有就直接跳过
        if 'key.key' in ts_html.text:
            key_uri = re.findall(r'URI="(.*?)\.key"',ts_html.text)[0]
            if '://' in key_uri:
                key_url = key_uri+'.key'
                headers['authority'] = re.findall(r'://(.*)',key_url)[0].strip().split('/')[0]
                ts_url = re.findall(r'://(.*)',key_url)[0].replace('key.key','')
                key = requests.get(url=key_url,headers=headers)
                with open(dir_name+'\\'+'key.key','wb')as f:
                    f.write(key.content)
                dict_ts.update({'ts_url':'https://'+ts_url})
            else:
                key_url = 'https://'+authority+key_uri+'.key'
                ts_url = re.findall(r'://(.*)',key_url)[0].replace('key.key','')
                key = requests.get(url=key_url,headers=headers)
                with open(dir_name+'\\'+'key.key','wb')as f:
                    f.write(key.content)
                dict_ts.update({'ts_url':'https://'+ts_url})
        # 洗数据,然后保存
        ts_all = re.findall(r'(.*?)\.ts',ts_html.text)
        for i in ts_all:
            if '/'in i:
                ts_list.append(i.strip().split('/')[-1])
            else:
                ts_list.append(i)
        # 保存一份顺序列表和一份m3u8源文件
        if not dir_name+'.txt' in os.listdir(dir_name):
            with open(dir_name+'\\'+name+'ts列表.txt','w')as f1,open(dir_name+'\\'+name+'.m3u8','wb')as f2:
                for i in ts_list:
                    f1.write(i+'\n')
                f2.write(ts_html.content)
        dict_ts.update({'ts_list':ts_list})
        return dict_ts
    # 下载ts文件,创建一个异步
    async def get_ts_data(self,ts_url,dir_name):
        # 创建一个异步,意思是指定s变量是aiohttp.ClientSession(),客户端会话
        async with aiohttp.ClientSession()as s:
            # 创建一个异步
            async with await s.get(url=ts_url,headers=headers)as response:
                # response.read()获取的是二进制数据,await是指可等待的,也就是可以挂起的
                ts_data = await response.read()
                ts_name = ts_url.split('/')[-1]
                # 保存数据
                with open(dir_name+'\\'+ts_name,'wb')as f:
                    f.write(ts_data)            
    # 开始任务函数
    def start_task(self):
        m3u8_first_url = self.get_m3u8_first()
        print(m3u8_first_url)
        print(headers)
        ts_list_url = self.get_m3u8_second(m3u8_first_url=m3u8_first_url)
        print(ts_list_url)
        dir_name = self.dir_name
        print('下载的文件保存到',dir_name,'\n')
        # 文件夹是否存在,如果没有就创建一个
        if not os.path.exists(dir_name):
            os.mkdir(dir_name)
            pass
        key_ts = self.get_ts_list_key(url=ts_list_url,dir_name=dir_name)
        ts_list = key_ts['ts_list']
        if 'key.key'in os.listdir(dir_name):
            ts_url = key_ts['ts_url']
        else:
            ts_url = re.sub(r'/([0-9A-z]*?)\.m3u8','',ts_list_url)
        print(ts_url)
        while True:
            tasks = []
            # 获取当前文件夹里分别有哪些文件
            current_file = os.listdir(dir_name)
            print('\n')
            # 这里应用了一个进度条模块,不是它鸡肋,是我还不懂怎么用,要涉及到多线程
            with alive_bar(len(ts_list))as bar:
                # 创建事件循环
                loop = asyncio.get_event_loop()
                for i in ts_list:
                    # 判断这个文件是不是已经下载好了,如果下载好了就跳过,以免重复下载浪费时间
                    if i+'.ts' in current_file:
                        bar()
                        continue
                    c = self.get_ts_data(ts_url=ts_url+i+'.ts',dir_name=dir_name)
                    task = asyncio.ensure_future(c)
                    # 把所有任务集合起来
                    tasks.append(task)
                try:
                    # 把所有任务放进事件循环里,等到所有任务都运行完毕就退出
                    loop.run_until_complete(asyncio.wait(tasks))
                except:
                    print('10秒后继续下载\n如果下载已完成,请直接关闭dos窗口\n⚠请不要连续Ctrl+C,否则会直接退出⚠')
                    time.sleep(10)

if __name__ == '__main__':
    print('\n***********************************************.*** 电影下载器DOS版V2.0 ***.***********************************************\n','\n')
    while True:
        dir_name = os.getcwd()+'\\'+input('\n请输入电影名称(必须,否则文件会乱)\n如果不满意输入的内容,可以按ctrl+c退出,重新打开程序:')
        if dir_name.strip() == str(os.getcwd()+'\\'):
            print('请输入电影名称(文件夹的名称)')
        else:
            break
    download_video(dir_name=dir_name).start_task()

配合TS文件合并工具使用
只要是会使用python编译器同学就会用,可以用pyinstaller包装起来哦。

————世界上没有奥特曼,但是一定有光!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值