mirror of
https://github.com/ls125781003/tvboxtg.git
synced 2025-10-28 04:12:19 +00:00
更新线路
整体线路:v1018 潇洒线路:v1018(15)
This commit is contained in:
29
小米/api.json
29
小米/api.json
@@ -108,6 +108,15 @@
|
||||
"url_key": "Duopan4"
|
||||
}
|
||||
},
|
||||
{
|
||||
"key": "csp_LIVING",
|
||||
"name": "🎮游戏┃直播",
|
||||
"type": 3,
|
||||
"api": "csp_Living",
|
||||
"quickSearch": 0,
|
||||
"searchable": 1,
|
||||
"ext": "https://api.muxia.fun"
|
||||
},
|
||||
{
|
||||
"key": "csp_Bili",
|
||||
"name": "🏵️哔哩┃哔哩",
|
||||
@@ -245,6 +254,15 @@
|
||||
"api": "csp_AppQi",
|
||||
"ext": "9ee0oa0Y30GapSvZ2C2RVE2HwH08KKvP0VhAZCVWpnluXpZNLRZrNCMeKyCWw1JOnmBt4WntUB96Gzw7GkroAUK4RePU806mDtHSmD09164W8EWpaWaU/Gg8nPkgUt5F"
|
||||
},
|
||||
{
|
||||
"key": "花猪",
|
||||
"name": "🐖花猪┃影视",
|
||||
"type": 3,
|
||||
"searchable": 1,
|
||||
"quickSearch": 0,
|
||||
"api": "csp_AppQi",
|
||||
"ext": "llmvPPU1h/vqmWtANHI55wjkhfSXUVRucMnPpIfDe+l3hpqpWlt3meXji00/Qg7Yb84SQ3EzXzZZ0jeFYWPcvEHOBaptd0aJSFS2ac8gZBJ6TodggbUva1hHidOGZOWx"
|
||||
},
|
||||
{
|
||||
"key": "麻花",
|
||||
"name": "🌸麻花┃影视",
|
||||
@@ -298,15 +316,6 @@
|
||||
"api": "csp_AppQi",
|
||||
"ext": "Ruh/okyt5lxEpcdQOao0NkSkj8M9vdB0soaZbGJldzA3817rfAzlvyWHCewZEFD4+BBCXxVVHkmAtv6gi+JRQlKwhK1WjuT8blTygReol77ICMmtZZPsmzfgjOtOXiEJ"
|
||||
},
|
||||
{
|
||||
"key": "lanyingys",
|
||||
"name": "橘子4K┃APP",
|
||||
"type": 3,
|
||||
"api": "csp_Muou",
|
||||
"jar": "./jars/lanyingys.jar",
|
||||
"playerType": 2,
|
||||
"ext": "7lj763gg0939790i413gi4igh94585i7g0l98449i3997320425124lgl71154400h9k4jghg17hgggjhki06i0h311g04h3hk323g0k"
|
||||
},
|
||||
{
|
||||
"key": "巧技",
|
||||
"name": "🚗聚搜┃影视",
|
||||
@@ -315,7 +324,7 @@
|
||||
"quickSearch": 0,
|
||||
"api": "csp_qiao2",
|
||||
"playerType": 2,
|
||||
"jar": "./jars/lanyingys.jar",
|
||||
"jar": "./jars/巧技.jar",
|
||||
"ext": "7lj763gg402i79425739i7jghj118797l4hj840gi18633331l4708g2h7145403549g44l8ii56i187681hkjj3hhgh1ih3l32j250lk1k786lj20j468hk3hli4l46gig4i3g7g2722328j0136h01i7g5183k22k7gg3i72hk81gl8k9839kl7i0707"
|
||||
},
|
||||
{
|
||||
|
||||
263
小米/api/AppV2.py
263
小米/api/AppV2.py
@@ -1,263 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# by @嗷呜
|
||||
# 基于原作者 @嗷呜 版本修改,仅可用于个人学习用途
|
||||
|
||||
from base.spider import Spider
|
||||
from urllib.parse import urlparse, urlencode
|
||||
import re,sys,time,json,urllib3,hashlib,datetime
|
||||
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
||||
sys.path.append('..')
|
||||
|
||||
class Spider(Spider):
|
||||
headers,api,apisignkey,datasignkey = {'User-Agent': 'okhttp/4.12.0',},'', '' , ''
|
||||
|
||||
def init(self, extend=""):
|
||||
ext = extend.rstrip()
|
||||
if ext.startswith('http'):
|
||||
self.api = ext.rstrip('/')
|
||||
else:
|
||||
arr = json.loads(ext)
|
||||
self.api = arr['api'].rstrip('/')
|
||||
self.apisignkey = arr.get('apisignkey', '')
|
||||
if self.apisignkey:
|
||||
self.datasignkey = arr.get('datasignkey', '6QQNUsP3PkD2ajJCPCY8')
|
||||
|
||||
def homeContent(self, filter):
|
||||
if self.api.endswith('v1.vod'):
|
||||
path = '/types'
|
||||
if self.apisignkey and self.datasignkey:
|
||||
path = self.datasign(path)
|
||||
data = self.fetch(f"{self.api}{path}", headers=self.headers, verify=False).json()
|
||||
data = data['data']
|
||||
else:
|
||||
data = self.fetch(f"{self.api}/nav?token=", headers=self.headers, verify=False).json()
|
||||
keys = ["class", "area", "lang", "year", "letter", "by", "sort"]
|
||||
filters = {}
|
||||
classes = []
|
||||
for item in data.get('list',data.get('data',[])):
|
||||
has_non_empty_field = False
|
||||
jsontype_extend = item["type_extend"]
|
||||
classes.append({"type_name": item["type_name"], "type_id": item["type_id"]})
|
||||
for key in keys:
|
||||
if key in jsontype_extend and jsontype_extend[key].strip() != "":
|
||||
has_non_empty_field = True
|
||||
break
|
||||
if has_non_empty_field:
|
||||
filters[str(item["type_id"])] = []
|
||||
for dkey in jsontype_extend:
|
||||
if dkey in keys and jsontype_extend[dkey].strip() != "":
|
||||
values = jsontype_extend[dkey].split(",")
|
||||
value_array = [{"n": value.strip(), "v": value.strip()} for value in values if
|
||||
value.strip() != ""]
|
||||
filters[str(item["type_id"])].append({"key": dkey, "name": dkey, "value": value_array})
|
||||
result = {"class": classes, "filters": filters}
|
||||
return result
|
||||
|
||||
def homeVideoContent(self):
|
||||
if self.api.endswith('v1.vod'):
|
||||
path = '/vodPhbAll'
|
||||
if self.apisignkey and self.datasignkey:
|
||||
keytime = self.keytime()
|
||||
path += self.datasign(f'?apikey={self.apikey()}&keytime={keytime}',keytime)
|
||||
data = self.fetch(f"{self.api}{path}", headers=self.headers, verify=False).json()
|
||||
data = data['data']
|
||||
else:
|
||||
data = self.fetch(f"{self.api}/index_video?token=", headers=self.headers, verify=False).json()
|
||||
videos = []
|
||||
if self.api.endswith('v1.vod'):
|
||||
for item in data['list']: videos.extend(item['vod_list'])
|
||||
elif 'list' in data:
|
||||
for item in data['list']: videos.extend(item['vlist'])
|
||||
elif 'data' in data:
|
||||
for item in data['data']: videos.extend(item['vlist'])
|
||||
return {'list': videos}
|
||||
|
||||
def categoryContent(self, tid, pg, filter, extend):
|
||||
if self.api.endswith('v1.vod'):
|
||||
path = f"?type={tid}&class={extend.get('class', '')}&lang={extend.get('lang', '')}&area={extend.get('area', '')}&year={extend.get('year', '')}&by=&page={pg}&limit=9"
|
||||
if self.apisignkey and self.datasignkey:
|
||||
keytime = self.keytime()
|
||||
path = self.datasign(f'{path}&apikey={self.apikey()}&keytime={keytime}' ,keytime)
|
||||
data = self.fetch(f"{self.api}{path}", headers=self.headers, verify=False).json()
|
||||
data = data['data']
|
||||
else:
|
||||
params = {'tid': tid, 'class': extend.get('class', ''), 'area': extend.get('area', ''), 'lang': extend.get('lang', ''), 'year': extend.get('year', ''), 'limit': '18', 'pg': pg}
|
||||
data = self.fetch(f"{self.api}/video", params=params, headers=self.headers, verify=False).json()
|
||||
if 'data' in data:
|
||||
data = {'list':data['data']}
|
||||
return data
|
||||
|
||||
def searchContent(self, key, quick, pg="1"):
|
||||
if self.api.endswith('v1.vod'):
|
||||
path = f"?page={pg}&limit=10&wd={key}"
|
||||
if self.apisignkey and self.datasignkey:
|
||||
keytime = self.keytime()
|
||||
path = self.datasign(f'{path}&apikey={self.apikey()}&keytime={keytime}',keytime)
|
||||
else:
|
||||
path = f"/search?text={key}&pg={pg}"
|
||||
data = self.fetch(f"{self.api}{path}", headers=self.headers, verify=False).json()
|
||||
data2 = data.get('list',data.get('data',[]))
|
||||
if 'type' in data2:
|
||||
for item in data2:
|
||||
item.pop('type', None)
|
||||
if not 'list' in data2:
|
||||
data2 = {'list': data2, 'page': pg}
|
||||
return data2
|
||||
|
||||
def detailContent(self, ids):
|
||||
if self.api.endswith('v1.vod'):
|
||||
path = f'/detail?vod_id={ids[0]}&rel_limit=10'
|
||||
if self.apisignkey and self.datasignkey:
|
||||
keytime = self.keytime()
|
||||
path = self.datasign(f'{path}&apikey={self.apikey()}&keytime={keytime}',keytime)
|
||||
data = self.fetch(f"{self.api}{path}", headers=self.headers, verify=False).json()
|
||||
else:
|
||||
data = self.fetch(f"{self.api}/video_detail?id={ids[0]}", headers=self.headers, verify=False).json()
|
||||
data = data['data']
|
||||
if 'vod_info' in data:
|
||||
data = data['vod_info']
|
||||
show = ''
|
||||
vod_play_url = ''
|
||||
if 'vod_url_with_player' in data:
|
||||
for i in data['vod_url_with_player']:
|
||||
show += i.get('name', '') + '$$$'
|
||||
parse_api = i.get('parse_api','')
|
||||
if parse_api and parse_api.startswith('http'):
|
||||
url = i.get('url','')
|
||||
if url:
|
||||
url2 = '#'.join([i+ '@' + parse_api for i in url.split('#')])
|
||||
vod_play_url += url2 + '$$$'
|
||||
else:
|
||||
vod_play_url += i.get('url','') + '$$$'
|
||||
data.pop('vod_url_with_player')
|
||||
if 'vod_play_list' in data:
|
||||
for i in data['vod_play_list']:
|
||||
parses = ''
|
||||
player_info = i['player_info']
|
||||
show += f"{player_info['show']}({i['from']})$$$"
|
||||
parse = player_info.get('parse','')
|
||||
parse2 = player_info.get('parse2','')
|
||||
if 'parse' in player_info and parse.startswith('http'):
|
||||
parses += parse + ','
|
||||
if 'parse2' in player_info and parse2.startswith('http') and parse2 != parse:
|
||||
parses += parse2
|
||||
parses = parses.rstrip(',')
|
||||
url = ''
|
||||
for j in i['urls']:
|
||||
if parse:
|
||||
url += f"{j['name']}${j['url']}@{parses}#"
|
||||
else:
|
||||
url += f"{j['name']}${j['url']}#"
|
||||
url = url.rstrip('#')
|
||||
vod_play_url += url + '$$$'
|
||||
if 'vod_play_list' in data:
|
||||
data.pop('vod_play_list')
|
||||
if 'rel_vods' in data:
|
||||
data.pop('rel_vods')
|
||||
if 'type' in data:
|
||||
data.pop('type')
|
||||
data['vod_play_from'] = show.rstrip('$$$')
|
||||
data['vod_play_url'] = vod_play_url.rstrip('$$$')
|
||||
return {'list': [data]}
|
||||
|
||||
def playerContent(self, flag, id, vipFlags):
|
||||
video_pattern = re.compile(r'https?:\/\/.*\.(?:m3u8|mp4|flv)')
|
||||
jx, url, ua = 0, '', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36'
|
||||
if '@' in id:
|
||||
rawurl, jxapi = id.split('@', 1)
|
||||
if ',' in jxapi:
|
||||
jxapis = jxapi.split(',', 1)
|
||||
else:
|
||||
jxapis = [jxapi]
|
||||
for jxapi_ in jxapis:
|
||||
try:
|
||||
res = self.fetch(f"{jxapi_}{rawurl}", headers=self.headers, timeout=10, verify=False).json()
|
||||
url = res.get('url', '')
|
||||
if url.startswith('http'):
|
||||
jxua = res.get('ua')
|
||||
if jxua:
|
||||
ua = jxua
|
||||
except Exception:
|
||||
url = ''
|
||||
continue
|
||||
if url.startswith('http'):
|
||||
jx = 0
|
||||
else:
|
||||
url = rawurl
|
||||
jx = 0 if video_pattern.match(rawurl) else 1
|
||||
else:
|
||||
url = id
|
||||
jx = 0 if video_pattern.match(id) else 1
|
||||
if url.startswith('NBY'):
|
||||
jx, url = 0, ''
|
||||
return {'jx': jx, 'parse': 0, 'url': url, 'header': {'User-Agent': ua}}
|
||||
|
||||
def keytime(self):
|
||||
return str(int(datetime.datetime.now().timestamp()))
|
||||
|
||||
def md5(self, str):
|
||||
hash_obj = hashlib.md5()
|
||||
hash_obj.update(str.encode('utf-8'))
|
||||
return hash_obj.hexdigest()
|
||||
|
||||
def apikey(self):
|
||||
date = datetime.datetime.now()
|
||||
year = str(date.year)
|
||||
hour = str(date.hour)
|
||||
minute = str(date.minute)
|
||||
|
||||
if len(hour) < 2:
|
||||
hour = "0" + hour
|
||||
if len(minute) < 2:
|
||||
minute = "0" + minute
|
||||
|
||||
str_value = self.apisignkey
|
||||
sign_str = f"{year}:{hour}:{year}:{minute}:{str_value}"
|
||||
md5_hash = self.md5(sign_str)
|
||||
return md5_hash
|
||||
|
||||
def datasign(self, url='', timestamp=''):
|
||||
parsed_url = urlparse(url)
|
||||
query_params = self._parse_query_params(parsed_url.query)
|
||||
if not timestamp:
|
||||
timestamp = str(time.time())
|
||||
query_params["timestamp"] = timestamp
|
||||
sorted_params = sorted(query_params.items(), key=lambda x: x[0])
|
||||
sign = self._generate_signature(sorted_params)
|
||||
query_params["datasign"] = sign
|
||||
new_query = urlencode(query_params)
|
||||
new_url = parsed_url._replace(query=new_query).geturl()
|
||||
return new_url
|
||||
|
||||
def _parse_query_params(self, query_str):
|
||||
params = {}
|
||||
if not query_str:
|
||||
return params
|
||||
for param in query_str.split('&'):
|
||||
if '=' not in param:
|
||||
continue
|
||||
key, value = param.split('=', 1)
|
||||
if value:
|
||||
params[key] = value
|
||||
return params
|
||||
|
||||
def _generate_signature(self, sorted_params):
|
||||
param_str = '&'.join([f"{k}={v}" for k, v in sorted_params])
|
||||
raw_sign_str = f"{param_str}{self.datasignkey}"
|
||||
md5_hash = hashlib.md5(raw_sign_str.encode('utf-8')).hexdigest()
|
||||
return md5_hash
|
||||
|
||||
def localProxy(self, param):
|
||||
pass
|
||||
|
||||
def getName(self):
|
||||
pass
|
||||
|
||||
def isVideoFormat(self, url):
|
||||
pass
|
||||
|
||||
def manualVideoCheck(self):
|
||||
pass
|
||||
|
||||
def destroy(self):
|
||||
pass
|
||||
Binary file not shown.
0
小米/jars/巧技.jar
Normal file
0
小米/jars/巧技.jar
Normal file
BIN
小米/spider.jar
BIN
小米/spider.jar
Binary file not shown.
Reference in New Issue
Block a user