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包装起来哦。
————世界上没有奥特曼,但是一定有光!