import requests
import re
import os
from concurrent.futures import ThreadPoolExecutor
from Crypto.Cipher import AES
from bs4 import BeautifulSoup
"""
专门下载 《极速资源》 的电影
1.首先进入要下载的某个电影的主页,将网址输入程序
2.运行get_name方法,获取电影播放地址(非m3u8地址),key播放地址,以及电影名字
3.运行get_m3u8,最终获取到的是一个装有ts地址的列表
4.运行thread_download,开始多线程下载ts文件,在调用download方法时,可能会得到一个空文件
5.运行thread_decode,开始多线程解码ts文件,如果ts文件本身是空,那么解码会失败,但不会报错
6.运行check_ts,检查是不是全部解码完成,通过os.path.isfile('文件路径')反馈会一个新的列表self.new_lst,
接收的是解码未成功的ts文件名称是self.lst列表中的索引,如果服务器断限制了你的访问,这地方会很有意思,
总之,只要服务器端不是完全切断网络连接,就一定能全部解码完成。
7.运行marge,大功告成.
后记:
class实在是太好玩了,比函数好用多了
如果电脑性能好的话,可以修改ThreadPoolExecutor(50)里面的数值,数值越大,速度越快
"""
class Application:
def __init__(self, url):
self.url = url
self.new_lst = [] # 接收解码失败的文件
self.i = 0 # 统计download函数被重复调用的次数
self.j = 0 # 统计经过多少级解码才完成全部解码
self.IV = b'0000000000000000' # 源文件32位,更改成16位
self.headers = {
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
'Chrome/132.0.0.0 Safari/537.36 Edg/132.0.0.0'
}
def get_name(self):
resp = requests.get(self.url, headers=self.headers)
resp.close()
# print(resp.text)
bs = BeautifulSoup(resp.text, 'html.parser')
self.url = bs.find('span', id='1_1t').text.split('$')[-1].strip() # 这个地方必须要加strip()
self.movie_name = bs.find('div', class_='vod-img').find('img').get('alt') # 太好玩了,可以连续用find
self.key_url = self.url + '/enc.key'
# print(self.url)
# print(self.key_url)
def get_m3u8(self):
resp = requests.get(url=self.url, headers=self.headers)
resp.close()
# print(resp.text)
obj1 = re.compile("url: '(?P<m3u8_url>.*?)',", re.S)
m3u8_url = obj1.search(resp.text).group('m3u8_url')
# print(m3u8_url)
resp1 = requests.get(m3u8_url, self.headers)
resp1.close()
# print(resp1.text)
obj2 = re.compile('https://p.ji.*?\.ts')
self.lst = obj2.findall(resp1.text)
# print(self.lst)
def thread_download(self):
new_lst = []
with ThreadPoolExecutor(50) as t:
for k, v in enumerate(self.lst):
t.submit(self.download, name=k, ts_url=v)
for i in range(len(self.lst)):
if os.path.isfile(f'video/{i}'):
continue
else:
new_lst.append(i)
if new_lst:
print('==============================ts文件没有全部下载成功!======================================')
print(new_lst)
else:
print('==============================ts文件全部下载成功!')
def download(self, name, ts_url):
try: # 这个地方有可能下载不成功,但不会报错,会继续执行,最终获得一个空的ts文件
resp = requests.get(ts_url, headers=self.headers, timeout=10)
resp.close()
with open(f'video/{name}', mode='wb') as f:
f.write(resp.content)
print(f'{name}下载成功')
except Exception as e:
self.i += 1
self.download(name, ts_url)
print(f'{name}下载失败,第{self.i}次重新调用download方法====================')
def thread_decode_ts(self):
self.j += 1
resp = requests.get(self.key_url, headers=self.headers)
resp.close()
self.key = resp.content
self.aes = AES.new(self.key, AES.MODE_CBC, self.IV)
with ThreadPoolExecutor(50) as t:
for i in range(len(self.lst)):
t.submit(self.decode_ts, name=i)
print(f'第{self.j}次解码完成!')
def decode_ts(self, name):
with open(f'video/{name}', 'rb') as f:
de_ts = self.aes.decrypt(f.read())
with open(f'video/{name}_1', 'wb') as f1:
f1.write(de_ts)
print(f'video/{name}解码成功')
def marge(self):
with open(f'video/{self.movie_name}.mp4', mode='wb') as f:
for i in range(len(self.lst)):
with open(f'video/{i}_1', mode='rb') as f1:
f.write(f1.read())
os.remove(f'video/{i}')
os.remove(f'video/{i}_1')
print(f'{self.movie_name}下载完成!')
def check_ts(self):
for i in range(len(self.lst)):
if not os.path.isfile(f'video/{i}_1'):
self.new_lst.append(i)
if self.new_lst:
self.j += 1
print('以下没有解码成功')
print(self.new_lst)
with ThreadPoolExecutor(50) as t:
for j in self.new_lst:
t.submit(self.download, name=j, ts_url=self.lst[j])
with ThreadPoolExecutor(50) as t:
for j in self.new_lst:
t.submit(self.decode_ts, name=j)
print(f'第{self.j}次解码完成!')
self.new_lst = []
self.check_ts()
else:
print('全部解码完成!!!')
def main(self):
self.get_name()
self.get_m3u8()
self.thread_download()
self.thread_decode_ts()
self.check_ts()
self.marge()
if __name__ == '__main__':
# url = 'https://www.jisuzy.com/index.php/vod/detail/id/67042.html?ac=detail' # 下载单个电影,进入这个电影的主页面
url = input('请输入要下载的电影网址:').strip()
# url = 'https://play.jisuzyv.com/play/DdwGGY1d' # 下载电视剧某一集 不能直接用了
# key_url = url + '/enc.key'
app = Application(url)
app.main()
python递归下载极速资源的电影
于 2025-01-28 00:33:41 首次发布

76万+

被折叠的 条评论
为什么被折叠?



