225 lines
8.5 KiB
Python
225 lines
8.5 KiB
Python
# -*- coding: utf-8 -*-
|
|
# @Author : Doubebly
|
|
# @Time : 2025/4/9 22:22
|
|
import base64
|
|
import re
|
|
import sys
|
|
import requests
|
|
sys.path.append('..')
|
|
from base.spider import Spider
|
|
|
|
|
|
|
|
class Spider(Spider):
|
|
def getName(self):
|
|
return "非凡资源"
|
|
|
|
def init(self, extend):
|
|
self.home_url = 'http://ffzy5.tv'
|
|
self.headers = {
|
|
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36'
|
|
}
|
|
|
|
def getDependence(self):
|
|
return []
|
|
|
|
def isVideoFormat(self, url):
|
|
pass
|
|
|
|
def manualVideoCheck(self):
|
|
pass
|
|
|
|
def homeContent(self, filter):
|
|
return {
|
|
'class': [{'type_id': '1', 'type_name': '电影片'},
|
|
{'type_id': '2', 'type_name': '连续剧'},
|
|
{'type_id': '3', 'type_name': '综艺片'},
|
|
{'type_id': '4', 'type_name': '动漫片'}],
|
|
'filters': {
|
|
'1': [{'key': 'cid',
|
|
'name': '分类',
|
|
'value': [{'n': '动作片', 'v': '6'},
|
|
{'n': '喜剧片', 'v': '7'},
|
|
{'n': '爱情片', 'v': '8'},
|
|
{'n': '科幻片', 'v': '9'},
|
|
{'n': '恐怖片', 'v': '10'},
|
|
{'n': '剧情片', 'v': '11'},
|
|
{'n': '战争片', 'v': '12'},
|
|
{'n': '记录片', 'v': '20'},
|
|
{'n': '伦理片', 'v': '34'}]}],
|
|
'2': [{'key': 'cid',
|
|
'name': '分类',
|
|
'value': [{'n': '国产剧', 'v': '13'},
|
|
{'n': '香港剧', 'v': '14'},
|
|
{'n': '韩国剧', 'v': '15'},
|
|
{'n': '欧美剧', 'v': '16'},
|
|
{'n': '台湾剧', 'v': '21'},
|
|
{'n': '日本剧', 'v': '22'},
|
|
{'n': '海外剧', 'v': '23'},
|
|
{'n': '泰国剧', 'v': '24'},
|
|
{'n': '短剧', 'v': '36'}]}],
|
|
'3': [{'key': 'cid',
|
|
'name': '分类',
|
|
'value': [{'n': '大陆综艺', 'v': '25'},
|
|
{'n': '港台综艺', 'v': '26'},
|
|
{'n': '日韩综艺', 'v': '27'},
|
|
{'n': '欧美综艺', 'v': '28'}]}],
|
|
'4': [{'key': 'cid',
|
|
'name': '分类',
|
|
'value': [{'n': '国产动漫', 'v': '29'},
|
|
{'n': '日韩动漫', 'v': '30'},
|
|
{'n': '欧美动漫', 'v': '31'},
|
|
{'n': '港台动漫', 'v': '32'},
|
|
{'n': '海外动漫', 'v': '33'}]}]
|
|
}
|
|
}
|
|
|
|
def homeVideoContent(self):
|
|
video_list = []
|
|
try:
|
|
res = requests.get(f'{self.home_url}/index.php/ajax/data?mid=1', headers=self.headers)
|
|
data_list = res.json()['list']
|
|
for i in data_list:
|
|
video_list.append(
|
|
{
|
|
'vod_id': i['vod_id'],
|
|
'vod_name': i['vod_name'],
|
|
'vod_pic': i['vod_pic'],
|
|
'vod_remarks': i['vod_remarks']
|
|
}
|
|
)
|
|
except requests.RequestException as e:
|
|
return {
|
|
'list': [],
|
|
'parse': 0,
|
|
'jx': 0
|
|
}
|
|
|
|
return {
|
|
'list': video_list,
|
|
'parse': 0,
|
|
'jx': 0
|
|
}
|
|
|
|
def categoryContent(self, cid, page, filter, ext):
|
|
cid = ext.get('cid', cid)
|
|
url = f'{self.home_url}/index.php/ajax/data?mid=1&tid={cid}&page={page}&limit=20'
|
|
video_list = []
|
|
try:
|
|
res = requests.get(url,headers=self.headers)
|
|
data_list = res.json()['list']
|
|
for i in data_list:
|
|
video_list.append(
|
|
{
|
|
'vod_id': i['vod_id'],
|
|
'vod_name': i['vod_name'],
|
|
'vod_pic': i['vod_pic'],
|
|
'vod_remarks': i['vod_remarks']
|
|
}
|
|
)
|
|
except requests.RequestException as e:
|
|
return {'list': [], 'msg': e}
|
|
return {'list': video_list, 'parse': 0, 'jx': 0}
|
|
|
|
def detailContent(self, did):
|
|
ids = did[0]
|
|
video_list = []
|
|
try:
|
|
res = requests.get(f'{self.home_url}/api.php/provide/vod?ac=detail&ids={ids}', headers=self.headers)
|
|
i = res.json()['list'][0]
|
|
video_list.append(
|
|
{
|
|
'type_name': i['type_name'],
|
|
'vod_id': i['vod_id'],
|
|
'vod_name': i['vod_name'],
|
|
'vod_remarks': i['vod_remarks'],
|
|
'vod_year': i['vod_year'],
|
|
'vod_area': i['vod_area'],
|
|
'vod_actor': i['vod_actor'],
|
|
'vod_director': i['vod_director'],
|
|
'vod_content': i['vod_content'],
|
|
'vod_play_from': i['vod_play_from'].split('$$$')[-1],
|
|
'vod_play_url': i['vod_play_url'].split('$$$')[-1],
|
|
|
|
}
|
|
)
|
|
except requests.RequestException as e:
|
|
return {'list': [], 'msg': e}
|
|
return {"list": video_list, 'parse': 0, 'jx': 0}
|
|
|
|
def searchContent(self, key, quick, page='1'):
|
|
wd = key
|
|
video_list = []
|
|
if page != '1':
|
|
return {'list': video_list, 'parse': 0, 'jx': 0}
|
|
try:
|
|
response = requests.get(f'{self.home_url}/api.php/provide/vod?ac=detail&wd={wd}',headers=self.headers,)
|
|
data_list = response.json()['list']
|
|
for i in data_list:
|
|
video_list.append(
|
|
{
|
|
'vod_id': i['vod_id'],
|
|
'vod_name': i['vod_name'],
|
|
'vod_pic': i['vod_pic'],
|
|
'vod_remarks': i['vod_remarks']
|
|
}
|
|
)
|
|
except requests.RequestException as e:
|
|
return {'list': [], 'msg': e}
|
|
return {'list': video_list, 'parse': 0, 'jx': 0}
|
|
|
|
def playerContent(self, flag, pid, vipFlags):
|
|
# url = pid
|
|
url = f'{self.getProxyUrl()}&url={self.b64encode(pid)}'
|
|
return {"url": url, "header": self.headers, "parse": 0, "jx": 0}
|
|
|
|
def localProxy(self, params):
|
|
url = self.b64decode(params['url'])
|
|
r = requests.get(url, headers=self.headers)
|
|
a =r.text.strip().split('\n')[-1]
|
|
url = url.replace('index.m3u8', a)
|
|
home_url = url.replace('mixed.m3u8', '')
|
|
try:
|
|
r = requests.get(url, headers=self.headers)
|
|
data = r.text
|
|
c = []
|
|
data_list = data.strip().split('\n')
|
|
for index, data in enumerate(data_list):
|
|
if '#EXT-X-DISCONTINUITY' in data:
|
|
c.append(index)
|
|
ads = []
|
|
for index, i in enumerate(c[:-1]):
|
|
aa = c[index + 1] - c[index]
|
|
if aa == 17 or aa == 15:
|
|
# print(data_list[c[index] + 2])
|
|
# print(c[index + 1] - c[index])
|
|
ads.append([c[index], c[index + 1]])
|
|
ads.reverse()
|
|
for ad in ads:
|
|
s = ad[0]
|
|
e = ad[1]
|
|
while True:
|
|
if e < s:
|
|
break
|
|
data_list.pop(e)
|
|
e = e - 1
|
|
text = '\n'.join(data_list)
|
|
m3u8_text = re.sub('(.*ts.*)', home_url + '\\1', text)
|
|
return [200, "application/vnd.apple.mpegurl", m3u8_text]
|
|
except requests.RequestException as e:
|
|
return [302, "text/plain", None, {'Location': url}]
|
|
|
|
|
|
def destroy(self):
|
|
return '正在Destroy'
|
|
|
|
def b64encode(self, data):
|
|
return base64.b64encode(data.encode('utf-8')).decode('utf-8')
|
|
|
|
def b64decode(self, data):
|
|
return base64.b64decode(data.encode('utf-8')).decode('utf-8')
|
|
|
|
|
|
if __name__ == '__main__':
|
|
pass
|