import os
import requests
import time
import re
from tqdm import tqdm
from Crypto.Cipher import AES
from concurrent.futures import ThreadPoolExecutor,wait
# pip install pycryptodome
headers = {
'User-Agent':'Mozilla/5.0(WindowsNT10.0;Win64;x64)AppleWebKit/537.36(KHTML,like Gecko)Chrome/117.0.0.0 Safari/537.36'
}
u_len = 0
def log_file(url):
timestamp = time.time() # 转换成localtime
time_local = time.localtime(timestamp)
# 转换成新的时间格式(2016-05-05 20:28:54)
dt = time.strftime("%Y-%m-%d %H:%M:%S", time_local)
url = url + '\t' + dt +' \n'
if not os.path.exists('./index/log.log'):
os.mkdir('./index/')
with open('./index/log.log','a') as f:
f.write(url)
pass
def down_index(url):
global moive_name
headers = {
'User-Agent': 'Mozilla/5.0(WindowsNT10.0;Win64;x64)AppleWebKit/537.36(KHTML,like Gecko)Chrome/117.0.0.0 Safari/537.36'
}
pro_key = ''
try:
page_text = requests.get(url,headers=headers).text
except Exception as e:
try:
page_text = requests.get(url, headers=headers, verify=False).text
except Exception as e:
# page_text = '"url":"https://2.bo.com/2020011/PsGhiYT/index."'
print('网页拒绝链接')
for i in range(1,11):
print(11-i,'秒后退出',)
time.sleep(1)
exit()
log_file(url)
# print(page_text)
# <h1 class="title"><a href="/index.php/vod/detail/id/401058.html">变形金刚:超能勇士崛起 国语版 HD【无尽资源】</a></h1>
try:
moive_name = re.findall(r'<h1 class="title"><a href=".*?">(.*?)</a></h1>',page_text)[0]
print(moive_name)
except Exception as e:
try:
moive_name = re.findall(r'<h1>(.*?)</h1>', page_text)[0]
print(moive_name)
except Exception as e:
# < title >《洛基第一季》第01集在线观看_九九美剧 < / title >
moive_name = re.findall(r'<title>(.*?)</title>', page_text)[0]
print(moive_name)
if re.search(r'https://(.*?)index.m3u8',page_text):
try:
index_url = re.findall(r'now="(.*?)index.m3u8',page_text)[0]
index = index_url + 'index.m3u8'
print(index,'=================')
page_data = requests.get(index,headers=headers).text
page_text = page_data.split('\n')
print(page_text)
except:
#
index_url = re.findall(r'link_pre":"","url":"(.*?)index.m3u8"', page_text)[0]
print(index_url, '===========++++++++++')
index_url = index_url.replace('\\', '')
index = index_url + 'index.m3u8'
print(index, 200, '次请求')
page_data = requests.get(index,headers=headers).text
page_text = page_data.split('\n')
if '' in page_text:
page_text.remove('')
if len(page_text) == 1 and page_text[0] =='file not found':
print(page_text[0], 304, '没有文件')
return 0
print(page_text, 200, '次--请求')
if len(page_data) < 500:
if len(page_text[-1]) > 20:
pro_key = index_url[:8]+index_url[8:-1].split('/')[0] + '\n'
next_url = index_url[:8]+index_url[8:-1].split('/')[0] + page_text[-1]
# print(next_url)
print('--网址的头:', pro_key)
pass
else:
next_url = index_url + page_text[-1]
# print(next_url,'0000000')
pro_key = next_url[:-10] + '\n'
print('++网址的头:',pro_key.strip())
print(next_url,'拿到m3u8')
page_text = requests.get(next_url,headers=headers).text
# print(page_data)
else:
# print(page_text)
url_suffix = re.findall(r'url(.*?)url_next', page_text)[0][3:-3]
# print(url_suffix)
profix_url = 'https://zj.sp-flv.com:8443/?url='
video_url = profix_url + url_suffix
print('跳转iframe的网页地址')
page_text = requests.get(video_url, ).text
url = re.findall(r'video_url = (.*?);', page_text)[0][1:-1]
print(url,' iframe的网页地址,拿到index.m3u8文件')
pro_key = url.split('index.m3u8')[0] + '\n' #网址的请求头部分
page_text = requests.get(url, headers=headers).text
# print(page_text,'----------+++++++-----','二次请求')
if len(page_text) < 500:
page_text = page_text.split('\n')
if '' in page_text:
page_text.remove('')
print('--------------')
pro_list = pro_key.strip()[8:].split('/')
if '' in pro_list:
pro_list.remove('')
if page_text[-1].strip().startswith('https:'):
next_url = page_text[-1].strip()
else:
suf_list = page_text[-1].strip().split('/')
if '' in suf_list:
suf_list.remove('')
print(pro_list, suf_list,'查看地址中是否有重负的字段')
for i in suf_list:
if i in pro_list:
pro_list.remove(i)
next_url = pro_key.strip()[:8]+ '/'.join(pro_list+suf_list)
print('-------',next_url,3,'次请求')
# 获取m3u8文件
page_text = requests.get(next_url,headers=headers).text
# print(page_text)
pro_key = next_url[:-10] + '\n'
# 将获取的m3u8文件写入到本地的inde/index.m3u8下
with open('./index/index.m3u8', mode='w', encoding='utf8') as f:
f.writelines(pro_key)
f.write(page_text)
# print(page_text)
log_file(url)
pass
# 处理下载下来的index.m3u8文件
def get_key():
'''有加密的拿到加密的然后进行解密,下载地址也做了判断全地址的直接保存,不是的会进行拼接'''
url_key = ''
# 读取index.m3u8文件
with open('./index/index.m3u8', 'r') as f:
keys = f.readlines()
# print(keys)
pro_url_key = keys[0].strip()
keys.pop(0)
print(pro_url_key)
for i in range(10):
if re.findall(r'URI="(.*?)"',keys[i].strip()):
if re.findall(r'URI="(.*?)"', keys[i].strip())[0].startswith('http'):
url_key = re.findall(r'URI="(.*?)"', keys[i].strip())[0]
else:
url_key = pro_url_key + re.findall(r'URI="(.*?)"', keys[i].strip())[0]
break
# 做个标记文件是否是加密视频,是写入秘钥,否写入222
if url_key == '':
page_text = '222'
else:
page_text = requests.get(url_key).text
print(page_text)
pass
pass_url = ['7ce9fef4fac0493266.ts', '7ce9fef4fac0493267.ts', '7ce9fef4fac0493268.ts', '7ce9fef4fac0493269.ts']
with open('./index/url.txt', 'w') as f:
f.write(page_text+'\n')
for i in keys:
# if len(i.strip()) >=60 and len(i.strip()) <=62:
# f.write(i)
if not i.startswith('#'):
if i.startswith('http'):
f.write(i)
else:
try:
int(i.strip().split('.')[0][-5:])
f.write(pro_url_key + i)
except Exception as e:
if len(i.strip().split('/')[-1]) > 15:
pass
else:
try:
int(i.strip().split('.')[0][-1:])
f.write(pro_url_key + i)
except:
if i in pass_url:
pass
f.write(pro_url_key + i)
def add_video(path='./video/'):
global moive_name
new_name = path + moive_name + '.mp4'
if not os.path.exists('./video/'):
os.mkdir('./video/')
print("正在合并文件")
file_list = os.listdir('./ts01/')
file_list = sorted(file_list, key=lambda x:int(x.split('.')[0]))
num = len(os.listdir(path))
video_name = path + 'video'+str(num)+'.ts'
for i in tqdm(file_list):
file_path = './ts01/' + i
with open(file_path, mode='rb',) as fr:
content= fr.read()
with open(video_name, mode='ab', ) as f:
f.write(content)
for i in file_list:
file_path = './ts01/' + i
os.remove(file_path)
os.removedirs('./ts01/')
os.renames(video_name,new_name)
print("合并完成")
def down_ts(url, name):
global header
global u_len
if len(url) - u_len < 7:
try:
page_data = requests.get(url,headers=headers,timeout=15).content
except:
down_ts(url, name)
# page_data = requests.get(url,headers=headers, timeout=15).content
# print(type(file))
file_dir = './ts01/'
if not os.path.exists(file_dir):
os.mkdir(file_dir)
file_name = file_dir + str(name) + '.ts'
with open(file_name, mode='wb') as f:
f.write(page_data)
for i in range(1000):
for j in range(10):
i = i+j
print(url, name, file_name)
else:
pass
def down_decode_ts(key,url, name):
global headers
global u_len
if len(url) -u_len < 7:
try:
page_data = requests.get(url,headers=headers,timeout=15).content
except:
down_decode_ts(key, url, name)
# page_data = requests.get(url,headers=headers, timeout=15).content
key = key.encode()
# print(key)
aes = AES.new(key=key,IV=b'0000000000000000', mode=AES.MODE_CBC)
file = aes.decrypt(page_data)
# print(type(file))
file_dir = './ts01/'
if not os.path.exists(file_dir):
os.mkdir(file_dir)
file_name = file_dir + str(name)+'.ts'
with open(file_name, mode='wb') as f:
f.write(file)
print(url, name, file_name)
else:
pass
def down_file(thred_num=75):
global header
global u_len
url_list = []
with open('./index/url.txt', 'r') as f:
url_list = f.readlines()
pool = ThreadPoolExecutor(thred_num)
task = []
u_len = len(url_list[2].strip())
if url_list[0].strip() == '222':
url_list.pop(0)
num = 0
for i in url_list:
# down_ts(i.strip(), num)
# break
task.append(pool.submit(down_ts, i.strip(), num))
num += 1
# time.sleep(1)
for i in range(1000):
for j in range(500):
i = i + j
wait(task)
else:
key = url_list[0].strip()
url_list.pop(0)
num = 0
for i in url_list:
name = i.strip().split('/')[-1]
# print(name)
# print(page_content)
task.append(pool.submit(down_decode_ts,key, i.strip() , num))
num += 1
# break
wait(task)
pass
if __name__ == '__main__':
moive_name = ''
if not os.path.exists('./index/'):
os.mkdir('./index/')
url = input("输入要下载的网址:")
down_index(url)
get_key()
down_file(100)
add_video()
certifi2023.11.17
chardet5.2.0
charset-normalizer3.3.2
click8.1.7
colorama0.4.6
colorlog6.8.0
comtypes1.2.1
dacite1.8.1
docker6.1.3
Faker18.13.0
Flask2.2.5
idna3.6
importlib-metadata6.7.0
itsdangerous2.1.2
Jinja23.1.3
lxml5.1.0
MarkupSafe2.1.3
Naked0.1.32
packaging23.2
pocsuite32.0.7
prettytable3.7.0
pycryptodome3.20.0
pycryptodomex3.20.0
pypiwin32223
PySocks1.7.1
python-dateutil2.8.2
PyUserInput0.1.10
pywifi1.1.12
pywin32306
PyYAML6.0.1
requests2.31.0
requests-toolbelt1.0.0
scapy2.5.0
shellescape3.8.1
six1.16.0
termcolor2.3.0
tqdm4.66.1
typing-extensions4.7.1
urllib32.0.7
wcwidth0.2.13
websocket-client1.6.1
Werkzeug2.2.3
zipp==3.15.0