增加喵次元
This commit is contained in:
parent
239712f933
commit
cd02ba1e88
@ -1 +1 @@
|
|||||||
3.9.49beta27
|
3.9.49beta28
|
||||||
@ -294,7 +294,8 @@ class Spider(BaseSpider): # 元类 默认的元类 type
|
|||||||
@param vipFlags: vip标识
|
@param vipFlags: vip标识
|
||||||
@return:
|
@return:
|
||||||
"""
|
"""
|
||||||
url = 'http://bizcommon.alicdn.com/l2nDqpMmn6DGHnWzZQA/Cg9qI5imMInpPvK5Mnm%40%40hd.m3u8'
|
# url = 'http://bizcommon.alicdn.com/l2nDqpMmn6DGHnWzZQA/Cg9qI5imMInpPvK5Mnm%40%40hd.m3u8'
|
||||||
|
url = 'https://s1.bfzycdn.com/video/renmindemingyi/%E7%AC%AC07%E9%9B%86/index.m3u8'
|
||||||
parse = 0
|
parse = 0
|
||||||
headers = {
|
headers = {
|
||||||
'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1'
|
'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1'
|
||||||
@ -307,6 +308,10 @@ class Spider(BaseSpider): # 元类 默认的元类 type
|
|||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def adRemove():
|
||||||
|
return 'reg:/video/adjump.*?ts'
|
||||||
|
|
||||||
config = {
|
config = {
|
||||||
"player": {},
|
"player": {},
|
||||||
"filter": {}
|
"filter": {}
|
||||||
@ -411,3 +416,10 @@ if __name__ == '__main__':
|
|||||||
a = spider.superStr2dict(code)
|
a = spider.superStr2dict(code)
|
||||||
print(type(a), a)
|
print(type(a), a)
|
||||||
# spider.searchContent('斗罗大陆')
|
# spider.searchContent('斗罗大陆')
|
||||||
|
print(spider.playerContent(None, 1, None))
|
||||||
|
with open('ad.m3u8', encoding='utf-8') as f:
|
||||||
|
adt = f.read()
|
||||||
|
url = adt.split('\n')[0]
|
||||||
|
adt = '\n'.join(adt.split('\n')[1:])
|
||||||
|
ad_remove = 'reg:/video/adjump(.*?)ts'
|
||||||
|
print(spider.fixAdM3u8(adt, url, ad_remove))
|
||||||
|
|||||||
398
txt/hipy/喵次元.py
Normal file
398
txt/hipy/喵次元.py
Normal file
@ -0,0 +1,398 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# File : 喵次元.py
|
||||||
|
# Author: DaShenHan&道长-----先苦后甜,任凭晚风拂柳颜------
|
||||||
|
# Author's Blog: https://blog.csdn.net/qq_32394351
|
||||||
|
# Date : 2024/1/17
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
|
||||||
|
sys.path.append('..')
|
||||||
|
try:
|
||||||
|
from base.spider import BaseSpider
|
||||||
|
except ImportError:
|
||||||
|
from t4.base.spider import BaseSpider
|
||||||
|
|
||||||
|
"""
|
||||||
|
配置示例:
|
||||||
|
t4的配置里ext节点会自动变成api对应query参数extend,但t4的ext字符串不支持路径格式,比如./开头或者.json结尾
|
||||||
|
api里会自动含有ext参数是base64编码后的选中的筛选条件
|
||||||
|
{
|
||||||
|
"key":"hipy_t4_喵次元",
|
||||||
|
"name":"喵次元(hipy_t4)",
|
||||||
|
"type":4,
|
||||||
|
"api":"http://192.168.31.49:5707/api/v1/vod/喵次元",
|
||||||
|
"searchable":1,
|
||||||
|
"quickSearch":0,
|
||||||
|
"filterable":1,
|
||||||
|
"ext":""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "hipy_t3_喵次元",
|
||||||
|
"name": "喵次元(hipy_t3)",
|
||||||
|
"type": 3,
|
||||||
|
"api": "{{host}}/txt/hipy/喵次元.py",
|
||||||
|
"searchable": 1,
|
||||||
|
"quickSearch": 0,
|
||||||
|
"filterable": 1,
|
||||||
|
"ext": ""
|
||||||
|
},
|
||||||
|
"""
|
||||||
|
|
||||||
|
# 全局变量
|
||||||
|
gParam = {
|
||||||
|
"HomeDict": {},
|
||||||
|
"TypeDict": {},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class Spider(BaseSpider): # 元类 默认的元类 type
|
||||||
|
key: str = 'sLunqcoH85Nm/jDmFKns7A== '
|
||||||
|
key_str: str = 'sLunqcoH85Nm/jDmFKns7A=='
|
||||||
|
iv: str = 'fedcba9876543210'
|
||||||
|
token: str = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJBcHBUbyIsImlhdCI6MTcwMDA3MTcwMiwiZXhwIjoxNzMxNjA3NzAyLCJuYmYiOjE3MDAwNzE3MDIsInN1YiI6IkFwcFRvIiwianRpIjoiYzRjNTAzOTQxYTM4NWI1MDMyMTAyYmY3Yzk1OGY4MzEiLCJkYXRhIjp7InVzZXJfaWQiOjI0ODc1NCwidXNlcl9jaGVjayI6ImUzYmQ3NmNhNTJhMGY4NjAwMTdjNjdkZGUwN2QzZTM3IiwidXNlcl9uYW1lIjoiaGV6aWh1aSJ9fQ.4LWs3rNL-os8_Pqa9LgKtvVG5f0aIxVyAjYIagvO1F4'
|
||||||
|
ic: str = 'bmXes2xsCWvsSdfYav0s9D78Ly7w1o%2BOYXApKx6SUd4NWKsTsapbS52l7y%2FsTVCM2kcoLws2jryaDQlHLse5fxD2B2VXZXfaQo0eMTOv2Xq7CKoPa51uVt8WiIY2SPztc7wxGE89%2Fcw2Q3n85uUT3A%3D%3D'
|
||||||
|
api: str = 'https://cym.zhui.la/api.php'
|
||||||
|
api_cofig: str = api + '/type/get_list'
|
||||||
|
api_home: str = api + '/video/index'
|
||||||
|
api_cate: str = api + '/video/get_list'
|
||||||
|
api_search: str = api + '/video/get_list'
|
||||||
|
api_detail: str = api + '/video/get_detail'
|
||||||
|
api_tabs: str = api + '/video/get_player'
|
||||||
|
api_parse: str = api + '/video/get_definition'
|
||||||
|
params: dict = {"versionName": "5.6.9", "uuid": "9cc01079c64e2495", "version": "4835d0a2", "versionCode": "35"}
|
||||||
|
|
||||||
|
def getName(self):
|
||||||
|
return "喵次元"
|
||||||
|
|
||||||
|
def init(self, extend=""):
|
||||||
|
"""
|
||||||
|
初始化加载extend,一般与py文件名同名的json文件作为扩展筛选
|
||||||
|
@param extend:
|
||||||
|
@return:
|
||||||
|
"""
|
||||||
|
ext = self.extend
|
||||||
|
self.log(f'ext:{ext}')
|
||||||
|
key = self.key_str
|
||||||
|
# 转hex
|
||||||
|
key_hex_str = self.bytesToHexString(key.encode('utf-8'))
|
||||||
|
# 右侧补16个0
|
||||||
|
key_hex_str += '0' * 16
|
||||||
|
key_hex = key_hex_str
|
||||||
|
# key_hex = '734C756E71636F4838354E6D2F6A446D464B6E7337413D3D0000000000000000'
|
||||||
|
# 转回来
|
||||||
|
key = self.hexStringTobytes(key_hex).decode('utf-8')
|
||||||
|
self.key = key
|
||||||
|
|
||||||
|
def isVideoFormat(self, url):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def manualVideoCheck(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def homeContent(self, filterable=False):
|
||||||
|
"""
|
||||||
|
获取首页分类及筛选数据
|
||||||
|
@param filterable: 能否筛选,跟t3/t4配置里的filterable参数一致
|
||||||
|
@return:
|
||||||
|
"""
|
||||||
|
filter_names = {
|
||||||
|
'class': '分类',
|
||||||
|
'area': '地区',
|
||||||
|
'lang': '语言',
|
||||||
|
'year': '年份',
|
||||||
|
'star': '明星',
|
||||||
|
'director': '导演',
|
||||||
|
'state': '状态',
|
||||||
|
'version': '版本',
|
||||||
|
}
|
||||||
|
ret = self.fetch(self.api_cofig).json()
|
||||||
|
data = self.decode(ret['data'])
|
||||||
|
result = {}
|
||||||
|
classes = []
|
||||||
|
filters = {}
|
||||||
|
type_dict = {}
|
||||||
|
for tp in data.get('list') or []:
|
||||||
|
classes.append({
|
||||||
|
'type_name': tp['type_name'],
|
||||||
|
'type_id': tp['type_id']
|
||||||
|
})
|
||||||
|
type_dict[str(tp['type_id'])] = tp['type_name']
|
||||||
|
tp_filters = []
|
||||||
|
for key, value in tp['type_extend'].items():
|
||||||
|
if value:
|
||||||
|
tp_filters.append({
|
||||||
|
'key': key,
|
||||||
|
'name': filter_names.get(key) or key,
|
||||||
|
'value': [{'n': '全部', 'v': ''}] + [{'n': i, 'v': i} for i in value.split(',') if i]
|
||||||
|
})
|
||||||
|
filters[tp['type_id']] = tp_filters
|
||||||
|
|
||||||
|
result['class'] = classes
|
||||||
|
if filterable:
|
||||||
|
result['filters'] = filters
|
||||||
|
global gParam
|
||||||
|
gParam['HomeDict'].update(result)
|
||||||
|
gParam['TypeDict'].update(type_dict)
|
||||||
|
return result
|
||||||
|
|
||||||
|
def homeVideoContent(self):
|
||||||
|
"""
|
||||||
|
首页推荐列表
|
||||||
|
@return:
|
||||||
|
"""
|
||||||
|
ret = self.fetch(self.api_home).json()
|
||||||
|
data = self.decode(ret['data'])
|
||||||
|
# print(data)
|
||||||
|
d = []
|
||||||
|
for cate_data in data:
|
||||||
|
items = cate_data['video']
|
||||||
|
for item in items:
|
||||||
|
d.append({
|
||||||
|
'vod_name': item['vod_name'],
|
||||||
|
'vod_id': item['vod_id'],
|
||||||
|
'vod_pic': item['vod_pic'],
|
||||||
|
'vod_remarks': item['vod_remarks'],
|
||||||
|
})
|
||||||
|
result = {
|
||||||
|
'list': d
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
|
||||||
|
def categoryContent(self, tid, pg, filterable, extend):
|
||||||
|
"""
|
||||||
|
返回一级列表页数据
|
||||||
|
@param tid: 分类id
|
||||||
|
@param pg: 当前页数
|
||||||
|
@param filterable: 能否筛选
|
||||||
|
@param extend: 当前筛选数据
|
||||||
|
@return:
|
||||||
|
"""
|
||||||
|
page_count = 21 # 默认赋值一页列表21条数据|这个值一定要写正确看他默认一页多少条
|
||||||
|
fls = extend.keys() # 哪些刷新数据
|
||||||
|
new_params = self.params.copy()
|
||||||
|
new_params.update({'type_id': str(tid), 'limit': str(page_count), 'page': str(pg),
|
||||||
|
'orderby': '', 'ctime': str(int(time.time()))
|
||||||
|
})
|
||||||
|
for fl in fls:
|
||||||
|
new_params[f'vod_{fl}'] = extend[fl]
|
||||||
|
|
||||||
|
params = self.get_sign_params(new_params)
|
||||||
|
# print(params)
|
||||||
|
r = self.postJson(self.api_cate, json=params)
|
||||||
|
ret = r.json()
|
||||||
|
data = self.decode(ret['data'])
|
||||||
|
# print(data)
|
||||||
|
d = data['list']
|
||||||
|
result = {
|
||||||
|
'list': d,
|
||||||
|
'page': pg,
|
||||||
|
'pagecount': 9999 if len(d) >= page_count else pg,
|
||||||
|
'limit': 90,
|
||||||
|
'total': data['count'],
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
|
||||||
|
def detailContent(self, ids):
|
||||||
|
"""
|
||||||
|
返回二级详情页数据
|
||||||
|
@param ids: 一级传过来的vod_id列表
|
||||||
|
@return:
|
||||||
|
"""
|
||||||
|
# id=110102
|
||||||
|
vod_id = ids[0]
|
||||||
|
new_params = self.params.copy()
|
||||||
|
new_params.update({'vod_id': str(vod_id), 'ctime': str(int(time.time()))})
|
||||||
|
params = self.get_sign_params(new_params)
|
||||||
|
# print(params)
|
||||||
|
r = self.postJson(self.api_detail, json=params)
|
||||||
|
ret = r.json()
|
||||||
|
data = self.decode(ret['data'])
|
||||||
|
# print(data)
|
||||||
|
vod = {"vod_id": vod_id,
|
||||||
|
"vod_name": data['vod_name'],
|
||||||
|
"vod_pic": data['vod_pic'],
|
||||||
|
"type_name": data['vod_en'],
|
||||||
|
"vod_year": data['vod_year'],
|
||||||
|
"vod_area": data['vod_area'],
|
||||||
|
"vod_remarks": data['vod_remarks'],
|
||||||
|
"vod_actor": data['vod_actor'],
|
||||||
|
"vod_director": data['vod_director'],
|
||||||
|
"vod_content": data['vod_blurb'],
|
||||||
|
}
|
||||||
|
episodes = data['player']
|
||||||
|
play_map = {}
|
||||||
|
play_from = []
|
||||||
|
play_list = []
|
||||||
|
for ep in episodes:
|
||||||
|
player = ep["code"]
|
||||||
|
source = ep["name"]
|
||||||
|
new_params = self.params.copy()
|
||||||
|
new_params.update({
|
||||||
|
'vod_id': str(vod_id), 'ctime': str(int(time.time())),
|
||||||
|
'limit': str(5000), 'page': str(1),
|
||||||
|
'player': player,
|
||||||
|
})
|
||||||
|
params = self.get_sign_params(new_params)
|
||||||
|
r = self.postJson(self.api_tabs, json=params)
|
||||||
|
ret = r.json()
|
||||||
|
data = self.decode(ret['data'])
|
||||||
|
# print(data)
|
||||||
|
for playurl in data['list']:
|
||||||
|
if source not in play_map:
|
||||||
|
play_map[source] = []
|
||||||
|
play_map[source].append(
|
||||||
|
playurl["drama"] + "$" + '&'.join(
|
||||||
|
[str(playurl["ju_id"]), str(playurl["plyer"]), str(playurl["video_id"])]))
|
||||||
|
|
||||||
|
for key, value in play_map.items():
|
||||||
|
play_from.append(key)
|
||||||
|
play_list.append('#'.join(value))
|
||||||
|
|
||||||
|
vod['vod_play_from'] = '$$$'.join(play_from)
|
||||||
|
vod['vod_play_url'] = '$$$'.join(play_list)
|
||||||
|
result = {
|
||||||
|
'list': [vod]
|
||||||
|
}
|
||||||
|
# print(vod)
|
||||||
|
return result
|
||||||
|
|
||||||
|
def searchContent(self, wd, quick=False, pg=1):
|
||||||
|
"""
|
||||||
|
返回搜索列表
|
||||||
|
@param wd: 搜索关键词
|
||||||
|
@param quick: 是否来自快速搜索。t3/t4配置里启用了快速搜索,在快速搜索在执行才会是True
|
||||||
|
@param pg: 页数
|
||||||
|
@return:
|
||||||
|
"""
|
||||||
|
page_count = 21 # 默认赋值一页列表21条数据|这个值一定要写正确看他默认一页多少条
|
||||||
|
new_params = self.params.copy()
|
||||||
|
new_params.update({
|
||||||
|
'orderby': 'up', 'ctime': str(int(time.time())),
|
||||||
|
'limit': str(page_count), 'page': str(pg), 'vod_name': str(wd)
|
||||||
|
})
|
||||||
|
params = self.get_sign_params(new_params)
|
||||||
|
# print(params)
|
||||||
|
r = self.postJson(self.api_cate, json=params)
|
||||||
|
ret = r.json()
|
||||||
|
data = self.decode(ret['data'])
|
||||||
|
# print(data)
|
||||||
|
d = data['list']
|
||||||
|
result = {
|
||||||
|
'list': d
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
|
||||||
|
def playerContent(self, flag, id, vipFlags):
|
||||||
|
"""
|
||||||
|
解析播放,返回json。壳子视情况播放直链或进行嗅探
|
||||||
|
@param flag: vod_play_from 播放来源线路
|
||||||
|
@param id: vod_play_url 播放的链接
|
||||||
|
@param vipFlags: vip标识
|
||||||
|
@return:
|
||||||
|
"""
|
||||||
|
_v = id.split('&')
|
||||||
|
ju_id = _v[0]
|
||||||
|
plyer = _v[1]
|
||||||
|
video_id = _v[2]
|
||||||
|
new_params = self.params.copy()
|
||||||
|
new_params.update({
|
||||||
|
'player_id': str(plyer), 'ctime': str(int(time.time())),
|
||||||
|
'ju_id': str(ju_id), 'vod_id': str(video_id)
|
||||||
|
})
|
||||||
|
params = self.get_sign_params(new_params)
|
||||||
|
# print(params)
|
||||||
|
r = self.postJson(self.api_parse, json=params)
|
||||||
|
ret = r.json()
|
||||||
|
data = self.decode(ret['data'])
|
||||||
|
# print(data)
|
||||||
|
# 列表里第1条的分辨率最高
|
||||||
|
url = data[0]['url']
|
||||||
|
# print(url)
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
# 原始key
|
||||||
|
key = 'sLunqcoH85Nm/jDmFKns7A=='
|
||||||
|
# 转hex
|
||||||
|
key_hex_str = self.bytesToHexString(key.encode('utf-8')).replace(' ', '')
|
||||||
|
# 右侧补16个0
|
||||||
|
key_hex_str += '0'*16
|
||||||
|
key_hex = key_hex_str
|
||||||
|
# key_hex = '734C756E71636F4838354E6D2F6A446D464B6E7337413D3D0000000000000000'
|
||||||
|
# 转回来
|
||||||
|
key = self.hexStringTobytes(key_hex).decode('utf-8')
|
||||||
|
# print(key)
|
||||||
|
iv = 'fedcba9876543210'
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
# key = self.key
|
||||||
|
# iv = self.iv
|
||||||
|
# input = self.aes_cbc_decode(url,key,iv)
|
||||||
|
|
||||||
|
input = self.decode_aes(url)
|
||||||
|
parse = 0
|
||||||
|
result = {
|
||||||
|
'parse': parse, # 1=嗅探,0=播放
|
||||||
|
'playUrl': '', # 解析链接
|
||||||
|
'url': input, # 直链或待嗅探地址
|
||||||
|
# 'header': headers, # 播放UA
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
|
||||||
|
config = {
|
||||||
|
"player": {},
|
||||||
|
"filter": {}
|
||||||
|
}
|
||||||
|
header = {
|
||||||
|
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.54 Safari/537.36",
|
||||||
|
"Host": "www.baidu.com",
|
||||||
|
"Referer": "https://www.baidu.com/"
|
||||||
|
}
|
||||||
|
|
||||||
|
def localProxy(self, params):
|
||||||
|
return [200, "video/MP2T", ""]
|
||||||
|
|
||||||
|
# -----------------------------------------------自定义函数-----------------------------------------------
|
||||||
|
def get_sign_params(self, params: dict):
|
||||||
|
keys = list(params.keys())
|
||||||
|
keys.sort()
|
||||||
|
str_list = []
|
||||||
|
for key in keys:
|
||||||
|
if params.get(key):
|
||||||
|
str_list.append(params[key])
|
||||||
|
str_list.append('alskeuscli')
|
||||||
|
sign = self.md5(''.join(str_list))
|
||||||
|
params['sign'] = sign
|
||||||
|
return params
|
||||||
|
|
||||||
|
def decode(self, text):
|
||||||
|
return text
|
||||||
|
# return self.str2json(self.aes_cbc_decode(text, self.key, self.iv))
|
||||||
|
|
||||||
|
def decode_aes(self, text):
|
||||||
|
key = self.key
|
||||||
|
iv = self.iv
|
||||||
|
input = self.aes_cbc_decode(text, key, iv)
|
||||||
|
return input
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
# 在线aes测试 https://config.net.cn/tools/AES.html
|
||||||
|
# 分类页:http://60.204.185.245:7090/appto/v1/home/cateData?id=1
|
||||||
|
# 推荐页:http://60.204.185.245:7090/appto/v1/config/get?p=android
|
||||||
|
from t4.core.loader import t4_spider_init
|
||||||
|
|
||||||
|
spider = Spider()
|
||||||
|
t4_spider_init(spider)
|
||||||
|
# spider.init_api_ext_file() # 生成筛选对应的json文件
|
||||||
|
|
||||||
|
# print(spider.homeContent(True))
|
||||||
|
# print(spider.homeVideoContent())
|
||||||
|
# print(spider.categoryContent('23', 1, True, {'year': '2024'}))
|
||||||
|
# print(spider.detailContent([7533]))
|
||||||
|
# print(spider.searchContent('斗罗大陆'))
|
||||||
|
print(spider.playerContent('线路J', '1&duoduan&7533', None))
|
||||||
|
print(spider.playerContent('线路Z', '1&ziru&7533', None))
|
||||||
Loading…
x
Reference in New Issue
Block a user