Sync all projects
This commit is contained in:
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
@header({
|
||||
searchable: 1,
|
||||
filterable: 1,
|
||||
quickSearch: 1,
|
||||
title: '03影视',
|
||||
author: '小可乐/250915/第一版',
|
||||
'类型': '影视',
|
||||
lang: 'dr2'
|
||||
})
|
||||
*/
|
||||
|
||||
var rule = {
|
||||
author: '小可乐/250915/第一版',
|
||||
title: '03影视',
|
||||
类型: '影视',
|
||||
host: 'https://www.03yy.live',
|
||||
headers: {
|
||||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/128.0.0.0 Safari/537.36',
|
||||
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
|
||||
'Accept-Language': 'zh-CN,zh;q=0.9'
|
||||
},
|
||||
编码: 'utf-8',
|
||||
timeout: 5000,
|
||||
url: '/type/indexfyclass-fypage.html',
|
||||
filter_url: '',
|
||||
searchUrl: '/search.php?searchword=**',
|
||||
searchable: 1,
|
||||
quickSearch: 1,
|
||||
filterable: 1,
|
||||
|
||||
class_name: '电影&电视剧&综艺&动漫',
|
||||
class_url: '1&2&3&4',
|
||||
filter_def: {},
|
||||
预处理: $js.toString(() => {
|
||||
// 使用withHeaders: true来获取响应头
|
||||
const res = request(HOST, {
|
||||
headers: rule.headers,
|
||||
withHeaders: true,
|
||||
redirect: false,
|
||||
method: 'GET'
|
||||
});
|
||||
const resJson = typeof res === 'string' ? JSON.parse(res) : res;
|
||||
|
||||
// 提取set-cookie头
|
||||
const setCookie = resJson['set-cookie'] || '';
|
||||
|
||||
// 处理cookie格式
|
||||
let cookies = '';
|
||||
if (Array.isArray(setCookie)) {
|
||||
cookies = setCookie.map(c => c.split(';')[0].trim()).join('; ');
|
||||
} else if (setCookie) {
|
||||
cookies = setCookie.split(';')[0].trim();
|
||||
}
|
||||
|
||||
// 更新rule.headers中的cookie
|
||||
if (cookies) {
|
||||
rule.headers["cookie"] = rule.headers["cookie"] ?
|
||||
rule.headers["cookie"] + '; ' + cookies : cookies;
|
||||
rule_fetch_params.headers = Object.assign({}, rule.headers);
|
||||
}
|
||||
|
||||
console.log(`提取的Cookie: ${cookies || '无'}`);
|
||||
console.log(`最终Cookie: ${rule.headers["cookie"] || '无'}`);
|
||||
}),
|
||||
play_parse: true,
|
||||
lazy: $js.toString(() => {
|
||||
let html = request(input, {
|
||||
headers: rule.headers,
|
||||
withHeaders: true,
|
||||
redirect: false,
|
||||
method: 'GET'
|
||||
});
|
||||
|
||||
// 处理转义引号:将 \" 替换为 "
|
||||
html = html.replace(/\\"/g, '"');
|
||||
|
||||
// 匹配参数
|
||||
const nowMatch = html.match(/var\s+now\s*=\s*base64decode\s*\(\s*["']([^"']+)["']\s*\)/);
|
||||
const prePageMatch = html.match(/var\s+prePage\s*=\s*["']([^"']+)["']/);
|
||||
const nextPageMatch = html.match(/var\s+nextPage\s*=\s*["']([^"']+)["']/);
|
||||
var now = nowMatch[1];
|
||||
now = base64Decode(now);
|
||||
console.log("now:" + now);
|
||||
|
||||
if (/\.(m3u8|mp4|mkv|jpg)/.test(now)) {
|
||||
input = {parse: 0, url: now}
|
||||
} else {
|
||||
const prePage = prePageMatch[1];
|
||||
const nextPage = nextPageMatch[1];
|
||||
console.log("prePage:" + prePage);
|
||||
console.log("nextPage:" + nextPage);
|
||||
|
||||
let jx = `${HOST}/api/dplayer.php?url=${now}&ref=${encodeURIComponent(prePage)}&next=${encodeURIComponent(nextPage)}`;
|
||||
|
||||
console.log("请求URL:" + jx);
|
||||
|
||||
let videohtml = request(jx, {
|
||||
headers: rule.headers,
|
||||
withHeaders: true,
|
||||
redirect: false,
|
||||
method: 'GET'
|
||||
});
|
||||
console.log("videohtml:" + videohtml);
|
||||
|
||||
const mediaInfoRegex = /mediaInfo\s*=\s*(\[.*?\]);/gis;
|
||||
const mediaInfoMatch = mediaInfoRegex.exec(videohtml);
|
||||
let videoUrl = "";
|
||||
|
||||
if (mediaInfoMatch && mediaInfoMatch[1]) {
|
||||
const mediaInfoContent = mediaInfoMatch[1];
|
||||
const qualityLevels = ["1080", "720", "540", "360"];
|
||||
const urls = [];
|
||||
for (const quality of qualityLevels) {
|
||||
const urlRegex = new RegExp(
|
||||
`definition.*?${quality}.*?url.*?:.*?"(https.*?)"`,
|
||||
'is'
|
||||
);
|
||||
const urlMatch = mediaInfoContent.match(urlRegex);
|
||||
if (urlMatch && urlMatch[1]) {
|
||||
videoUrl = urlMatch[1];
|
||||
videoUrl = videoUrl.replace(/\\\\\//g, '/').replace(/\\+/g, '');
|
||||
console.log(`找到${quality}清晰度的URL:`, videoUrl);
|
||||
urls.push(quality, videoUrl);
|
||||
}
|
||||
}
|
||||
input = { parse: 0, url: urls };
|
||||
if (!videoUrl) {
|
||||
console.log("未找到任何已知清晰度的URL");
|
||||
}
|
||||
} else {
|
||||
console.error("未匹配到mediaInfo");
|
||||
}
|
||||
}
|
||||
}),
|
||||
limit: 9,
|
||||
double: true,
|
||||
推荐: '.Pic-list&&.pic-content;a&&title;img&&src;span&&Text;a&&href',
|
||||
一级: '.type-box&&.pic-height-a;a&&title;img&&src;span&&Text;a&&href',
|
||||
二级: {
|
||||
title: 'h2&&Text;.m-content&&ul&&li:eq(4)',
|
||||
img: 'img&&src',
|
||||
desc: '.color-red&&Text;.m-content&&ul&&span:eq(2)&&Text;.m-content&&ul&&span:eq(0)&&Text;.m-content&&ul&&li:eq(1)&&Text;.m-content&&ul&&li:eq(0)&&Text',
|
||||
content: '.m-intro&&Text',
|
||||
tabs: '#playlist&&li',
|
||||
tab_text: 'body&&Text',
|
||||
lists: '.play_list:eq(#id)&&li',
|
||||
list_text: 'body&&Text',
|
||||
list_url: 'a&&href'
|
||||
},
|
||||
搜索: '*',
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"请求头": "User-Agent$MOBILE_UA",
|
||||
"编码": "UTF-8",
|
||||
"图片代理": "0",
|
||||
"主页url": "https://www.dui100.com/",
|
||||
"首页": "120",
|
||||
"起始页": "1",
|
||||
"分类url": "https://www.dui100.com/list/{cateId}-{catePg}.html;;mrcd0",
|
||||
"分类": "言情$1001#武侠$1002#悬疑$1003#历史$1004#军事$1005#评书$1006#相声小品$1007#商业财经$1009",
|
||||
"二次截取": "",
|
||||
"数组": "lazyload\"&&</a",
|
||||
"标题": "title=\"&&\"",
|
||||
"图片": "data-original=\"&&\"",
|
||||
"副标题": "text-right\">&&<",
|
||||
"链接": "href=\"&&\"",
|
||||
"影片年代": "年份:&&</p",
|
||||
"影片地区": "地区:&&</p",
|
||||
"影片类型": "类型:&&</p",
|
||||
"导演": "导演:&&</p",
|
||||
"主演": "主演:*>&&</a",
|
||||
"状态": "备注:*>&&</a",
|
||||
"简介": "class=\"col-pd\">&&</div",
|
||||
"线路二次截取": "",
|
||||
"线路数组": "<h3&&/h3>",
|
||||
"线路标题": "👶+>&&</font",
|
||||
"播放二次截取": "",
|
||||
"播放数组": "<ul class=\"stui-content__playlist column8 clearfix\">&&</ul>",
|
||||
"播放列表": "<a&&/a>",
|
||||
"播放标题": ">&&<",
|
||||
"播放链接": "href=\"&&\"",
|
||||
"解析": "",
|
||||
"直接播放": "0",
|
||||
"播放请求头": "",
|
||||
"嗅探词": ".mp3#.m4a",
|
||||
"过滤词": "",
|
||||
"搜索请求头": "User-Agent$MOBILE_UA",
|
||||
"搜索url": "https://www.dui100.com/search.php?searchword={wd}",
|
||||
"搜索模式": "1",
|
||||
"跳转播放链接": "var now=\"&&\""
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
# coding=utf-8
|
||||
# !/usr/bin/python
|
||||
|
||||
"""
|
||||
|
||||
作者 丢丢喵推荐 🚓 内容均从互联网收集而来 仅供交流学习使用 版权归原创者所有 如侵犯了您的权益 请通知作者 将及时删除侵权内容
|
||||
====================Diudiumiao====================
|
||||
|
||||
"""
|
||||
|
||||
from Crypto.Util.Padding import unpad
|
||||
from Crypto.Util.Padding import pad
|
||||
from urllib.parse import unquote
|
||||
from Crypto.Cipher import ARC4
|
||||
from urllib.parse import quote
|
||||
from base.spider import Spider
|
||||
from Crypto.Cipher import AES
|
||||
from datetime import datetime
|
||||
from bs4 import BeautifulSoup
|
||||
from base64 import b64decode
|
||||
import urllib.request
|
||||
import urllib.parse
|
||||
import datetime
|
||||
import binascii
|
||||
import requests
|
||||
import base64
|
||||
import json
|
||||
import time
|
||||
import sys
|
||||
import re
|
||||
import os
|
||||
|
||||
sys.path.append('..')
|
||||
|
||||
xurl = "https://www.4kvm.net"
|
||||
|
||||
headerx = {
|
||||
'User-Agent': 'Mozilla/5.0 (Linux; U; Android 8.0.0; zh-cn; Mi Note 2 Build/OPR1.170623.032) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/61.0.3163.128 Mobile Safari/537.36 XiaoMi/MiuiBrowser/10.1.1'
|
||||
}
|
||||
|
||||
class Spider(Spider):
|
||||
global xurl
|
||||
global headerx
|
||||
|
||||
def getName(self):
|
||||
return "首页"
|
||||
|
||||
def init(self, extend):
|
||||
pass
|
||||
|
||||
def isVideoFormat(self, url):
|
||||
pass
|
||||
|
||||
def manualVideoCheck(self):
|
||||
pass
|
||||
|
||||
def extract_middle_text(self, text, start_str, end_str, pl, start_index1: str = '', end_index2: str = ''):
|
||||
if pl == 3:
|
||||
plx = []
|
||||
while True:
|
||||
start_index = text.find(start_str)
|
||||
if start_index == -1:
|
||||
break
|
||||
end_index = text.find(end_str, start_index + len(start_str))
|
||||
if end_index == -1:
|
||||
break
|
||||
middle_text = text[start_index + len(start_str):end_index]
|
||||
plx.append(middle_text)
|
||||
text = text.replace(start_str + middle_text + end_str, '')
|
||||
if len(plx) > 0:
|
||||
purl = ''
|
||||
for i in range(len(plx)):
|
||||
matches = re.findall(start_index1, plx[i])
|
||||
output = ""
|
||||
for match in matches:
|
||||
match3 = re.search(r'(?:^|[^0-9])(\d+)(?:[^0-9]|$)', match[1])
|
||||
if match3:
|
||||
number = match3.group(1)
|
||||
else:
|
||||
number = 0
|
||||
if 'http' not in match[0]:
|
||||
output += f"#{match[1]}${number}{xurl}{match[0]}"
|
||||
else:
|
||||
output += f"#{match[1]}${number}{match[0]}"
|
||||
output = output[1:]
|
||||
purl = purl + output + "$$$"
|
||||
purl = purl[:-3]
|
||||
return purl
|
||||
else:
|
||||
return ""
|
||||
else:
|
||||
start_index = text.find(start_str)
|
||||
if start_index == -1:
|
||||
return ""
|
||||
end_index = text.find(end_str, start_index + len(start_str))
|
||||
if end_index == -1:
|
||||
return ""
|
||||
|
||||
if pl == 0:
|
||||
middle_text = text[start_index + len(start_str):end_index]
|
||||
return middle_text.replace("\\", "")
|
||||
|
||||
if pl == 1:
|
||||
middle_text = text[start_index + len(start_str):end_index]
|
||||
matches = re.findall(start_index1, middle_text)
|
||||
if matches:
|
||||
jg = ' '.join(matches)
|
||||
return jg
|
||||
|
||||
if pl == 2:
|
||||
middle_text = text[start_index + len(start_str):end_index]
|
||||
matches = re.findall(start_index1, middle_text)
|
||||
if matches:
|
||||
new_list = [f'{item}' for item in matches]
|
||||
jg = '$$$'.join(new_list)
|
||||
return jg
|
||||
|
||||
def homeContent(self, filter):
|
||||
result = {"class": []}
|
||||
|
||||
detail = requests.get(url=xurl, headers=headerx)
|
||||
detail.encoding = "utf-8"
|
||||
res = detail.text
|
||||
doc = BeautifulSoup(res, "lxml")
|
||||
soups = doc.find_all('ul', class_="main-header")
|
||||
|
||||
for soup in soups:
|
||||
vods = soup.find_all('li')
|
||||
|
||||
for vod in vods:
|
||||
|
||||
name = vod.text.strip()
|
||||
|
||||
if any(keyword in name for keyword in ["首页", "电视剧", "高分电影", "影片下载", "热门播放"]):
|
||||
continue
|
||||
|
||||
id = vod.find('a')['href']
|
||||
if 'http' not in id:
|
||||
id = xurl + id
|
||||
|
||||
result["class"].append({"type_id": id, "type_name": name})
|
||||
|
||||
return result
|
||||
|
||||
def homeVideoContent(self):
|
||||
videos = []
|
||||
|
||||
detail = requests.get(url=xurl, headers=headerx)
|
||||
detail.encoding = "utf-8"
|
||||
res = detail.text
|
||||
doc = BeautifulSoup(res, "lxml")
|
||||
|
||||
soups = doc.find_all('article', class_="item movies")
|
||||
|
||||
for vod in soups:
|
||||
|
||||
name = vod.find('img')['alt']
|
||||
|
||||
ids = vod.find('div', class_="poster")
|
||||
id = ids.find('
|
||||
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"请求头": "User-Agent$MOBILE_UA",
|
||||
"编码": "UTF-8",
|
||||
"主页url": "https://wap.mogudong.com/",
|
||||
"首页": "120",
|
||||
"起始页": "1",
|
||||
"简介": "display: none;\">&&</span>",
|
||||
"分类url": "https://wap.mogudong.com/vodshow/{cateId}-{area}-{by}-{class}-{lang}-{letter}---{catePg}---{year}.html",
|
||||
"分类": "电影&电视剧&综艺&动漫&短剧大全",
|
||||
"分类值": "dianying&dianshiju&zongyi&dongman&duanju",
|
||||
"跳转播放链接": "var player_*\"url\":\"&&\"",
|
||||
"搜索请求头": "User-Agent$MOBILE_UA",
|
||||
"搜索url": "https://wap.mogudong.com/vodsearch/{wd}----------{pg}---.html",
|
||||
"搜索模式": "1",
|
||||
"筛选": "1",
|
||||
"类型": "动作片$dongzuopian#喜剧片$xijupian#爱情片$aiqingpian#科幻片$kehuanpian#恐怖片$kongbupian#剧情片$juqingpian#战争片$zhanzhengpian#动画片$dongman||国产剧$guochanju#韩国剧$gangtaiju#欧美剧$rihanju#香港剧$oumeiju#台湾剧$taiwanju#日本剧$ribenju#泰国剧$taiguoju||港台综艺$gangtaizongyi#大陆综艺$daluzongyi#日韩综艺$rihanzongyi#欧美综艺$oumeizongyi||国产动漫$guochandongman#日韩动漫$rihandongman#欧美动漫$oumeidongman||空",
|
||||
"排序": "最新上映&超高人气&全网热播&高分好评",
|
||||
"排序值": "time&hits&up&score",
|
||||
"年份": "1950-2025",
|
||||
"年份值": "*"
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
[
|
||||
{
|
||||
"name": "魔都资源",
|
||||
"url": "https://caiji.moduapi.cc",
|
||||
"parse_url": "",
|
||||
"cate_exclude": "电影|连续剧|综艺|伦理片",
|
||||
"class_name": "H4sIAAAAAAAAAzWPWQ6CQBBEb8M5FaMyxIh8iAskfriMIiJqXECH09A9cAtnmuGrX3VXV1IQiqrg4B7xd7ZwsW82p04kXJbTTnyu4GVGNOOJnMdGqFGJSLKxBUEEjGuSzg0HQyLuQ/7VhP0Z9gLyMW6u6CyrghENXLTXdE1fUFyIvF29JR9MR+DdyWcnMvAp2b1KERP1y2ZdaqrTDMScdps2om3HuNUcVrqDJtUwFJpMQ0WqG+Yl7RZ7jBKi5xt2AdEjMx8qVo0/1LC8rzQBAAA=",
|
||||
"class_url": "1&2&3&4&5&6&10&11&12&13&14&15&16&17&18&20&21&22&23&24&25&26&27&28&29&30&31&32&33&34&35&36&37&38"
|
||||
},
|
||||
{
|
||||
"name": "360资源",
|
||||
"url": "https://360zy.com",
|
||||
"parse_url": "",
|
||||
"cate_exclude": "电影|连续剧|综艺|动漫|伦理片|体育|爽文短剧",
|
||||
"class_name": "H4sIALGjdWYC/zWRa3aCMBCFd5N9tAvomhRaFHoqcKpYrUd7VEQtCD6rYGAzee6iYYi/8s0kmZl7h/fPFO+RqKa8SKgdIV7chZ0j6qzZ/ReR+4p7Frc7dYLgCVAwUQ9r4t09M9+AIp/eippY22OtAN7Zkb5l3S+S25D7xiSP6j5yNWLXFGi2UemaWBzxslcTwZ/COKCX5yfETIcZY/i8u9A84akidykWUJr2LOoeoIkR88CHYZyU4y1Qu5TjEijfUjwAmiVaD+/DxNTN2K2E/sOQTWKg8x9dBkDHTE9Hl5EcWdqfenY3ewTDUIl4BCDiYWOjtzFTy9MB/NGBuBy5ZyKe7uqDTba0a/F9gURYSXPdWI1Z0FGzw456GSkW0sT0aiDx6rPTtFGP6O2kbvimEhdHu0SKESl/VPAhcKzKgJTwKOc+a7+rDarteHJQyZYl5sk/IOiszA8CAAA=",
|
||||
"class_url": "1&2&3&4&5&6&7&8&9&10&11&12&13&14&15&16&17&18&20&21&22&23&24&25&26&27&28&29&30&31&32&33&34&35&36&37&38&39&40&41&42&43&45&46&47&48&49&50&51&52&53"
|
||||
},
|
||||
{
|
||||
"name": "豪华资源",
|
||||
"url": "https://hhzyapi.com",
|
||||
"parse_url": "",
|
||||
"cate_exclude": "电视剧|电影|综艺|动漫|短剧|伦理片",
|
||||
"class_name": "H4sIALGjdWYC/zVPWw6CMBC8Tc/pI6D1w0eCKErCj1ofKBBjokg5DbsLt7Bdy1dnZrezMxS8WuWDVIKCF+hCYKqonluhO0X4zhglF/vg5sjskuIzt6ipTrT0SU4EzM6Nji2iaYFjj7UwNkusqRV8vhbhcImDkKdSuT2cbptSWtQ+ctBr54fVTYDvQcynjEABWzTvO+y1WzCRME578o/+J/StWlkKWOT4qdnhoLrId7L5Z0r1xLRc5D1hE0doWHe7mkOOUgpXXGaWkb5yyOPE1aLkbk78ALNMUSlMAQAA",
|
||||
"class_url": "1&2&3&4&5&6&7&8&9&10&11&12&13&14&15&16&17&20&23&24&25&26&27&28&30&31&32&33&34&35&36&37&38"
|
||||
},
|
||||
{
|
||||
"name": "速播资源",
|
||||
"url": "https://subocaiji.com",
|
||||
"parse_url": "",
|
||||
"cate_exclude": "电影|电视剧|动漫|综艺|短剧|伦理片",
|
||||
"class_name": "H4sIALGjdWYC/zWPWw6CMBBFd9N1+ohKNVGMiBpI+FHrAyJISHiV1bQzsAuZgl/39LY9k0En0zJh6GStWGoumF4/oH4zrOqWlwzLl5ZH5CvqlfSJ0EpgvjAk9rqoiMA6q5Kbd1yMtzC1YeKazvX7erT0dhyG6qvoLsPQXQxFQ9QFTwpsthSQf6BJDZ1uJtKYQtV3tJckVPLQzr5t5qlyw1QeaU+OG/Q/wA//h1CQctwtiHrJD0Ycn8r6AAAA",
|
||||
"class_url": "1&2&3&4&5&6&7&8&9&10&11&12&13&14&15&16&17&18&20&21&22&23&24&25&26&27"
|
||||
},
|
||||
{
|
||||
"name": "红牛资源",
|
||||
"url": "https://www.hongniuzy2.com",
|
||||
"parse_url": "",
|
||||
"cate_exclude": "电影|连续剧|综艺|动漫|纪录片|伦理片|体育赛事|短剧",
|
||||
"class_name": "H4sIALGjdWYC/y2PXQ6CMBCEb9Nz+hOVaqIYFU0g8qRV1AgSEikUL9Pu1lvorj7Nl5nNZBbXlTOF8K89NjcnlcCm9VILNz1BeyGxJkE5ES5KvjERBgUMR0xq6eqGCPoh9CK+k+qfQrCzWrIXG6sVtcPzDl3JtD2wXBV2cyK3yKHu2Ctzknd65kE6c2bDNbwJf4tte8RwTLY1Kz94+Cq2eiYwpS8+mOVyptYAAAA=",
|
||||
"class_url": "1&2&3&4&5&6&7&8&9&10&11&12&13&14&15&16&17&18&19&20&21&29&30"
|
||||
},
|
||||
{
|
||||
"name": "新浪资源",
|
||||
"url": "https://api.xinlangapi.com",
|
||||
"parse_url": "",
|
||||
"api": "/xinlangapi.php/provide/vod/from/xlm3u8/",
|
||||
"cate_exclude": "电影|电视剧|动漫|综艺|纪录片|伦理片|体育|短剧",
|
||||
"class_name": "H4sIALGjdWYC/0WOXQ6CMBCEb9Nz+hOR+qAYETUh4UWtikaQkEihPU27W24hXU18msk3m53BuLaqZBjXTgSWC2YXF+hyhm3nuGQob1Ztkc89Nyr1DsMSpjNyYm2b1jsI90ZyuuPil8I4glFCLEkHTO4o+gP1wPsJuqLGVQGNJnYXqJf/Ffgd12dXSncnkqrwYrozRoH/adTGTV4Ms8fAP2ziC/TQAAAA",
|
||||
"class_url": "1&2&3&4&5&6&7&8&9&10&11&12&13&14&15&16&17&18&20&21&22&23&24"
|
||||
},
|
||||
{
|
||||
"name": "黑木耳资源",
|
||||
"url": "https://www.heimuer.tv",
|
||||
"parse_url": "",
|
||||
"cate_exclude": "^电影$|^电视剧$|^综艺$|^动漫$|^短剧$",
|
||||
"class_name": "H4sIALGjdWYC/0WSbXKCQAyGb8M5UQcRqgU7DFal2mllKBa/pqNjQexl2M1yi7LZpP2175PNJnkDEJ1FfbIgOqtsKLzMEv6HvH1aUN2UV1pdRA4c8Fwdb+oE1fCpneeowrG0M1Rx0qWiSl3xXWkle6G0Y4wt66bMdHV5PeijXedIsxSPfgHxFJ8MfNlfaAW9e7u4oxqdaATwD1BvUWVTatKNBVEF5GK9w3pfR3QS4CGLDO6PqOJjmxd45VyaKsbYbqxGK+w9em5KD6tXgXCuqOopVAlV7x6J/eDfD61IWwqOBNrYsuabWSqTggHHYMBJujl5zTgPQ7BR7w55UfNQ9h4IWnuo3nbs0mzNAKQrddpymjuBaE0gNpOmcjkt/1EXnyFKxP6V026lsv+ahmOxf+EbY5uammWaf8T4IzDOCeiDUxouiIGdcyZWN/ALQpTFCIwCAAA=",
|
||||
"class_url": "1&2&3&4&6&7&8&9&10&11&12&13&14&15&16&20&21&22&23&24&25&26&27&28&29&30&31&32&33&34&35&36&37&38&39&40&41&42&43&44&45&46&47&48&49&50&51&52&53&54&55&56&57&58&59&60&61&62&63"
|
||||
},
|
||||
{
|
||||
"name": "暴风资源",
|
||||
"url": "https://bfzyapi.com",
|
||||
"parse_url": "",
|
||||
"cate_exclude": "电影片|连续剧|综艺片|动漫片|伦理片|电影解说|体育|演员|新闻资讯",
|
||||
"class_name": "H4sIALGjdWYC/zWRa3aCMBCFd5N1+kIFj1VOLdbq0Z6iBq0VrI8qGN1MMhN20WSAP8x34c7NZMDRWYkDuh2mvEiKGVEwUy63BPUh1AJLyH11y4i6B2g65HN5SdB9l6lLX9OtEm9Ew7bep5b0c47Zj3EzNRUy5ZZgx/HxYilfT+AaEy02xkC+QQK3B/nGK5jtiM5/ahkQHZPK50Vw/6ZZimTStslmlaI4qRTmpEFSiSKxEJjdtUvjqiXPJ+1Clw2VoNxKUG4pTAiOivXQQjUPdXxi+VdL+Z59LcWrbvzq81SmPaYvRxw2GcZ7KsK3BYJYx6lyegwXdllmDOVELO/0cbSAxDc3ZLh56ounbieZhQxfElN0VDM/wWysr8UOuwICc4PVEeo9qGU6rLN8vFWbD1xn5snyplDXhm75cJqbnqUOHZlN5OPzH964N6gIAgAA",
|
||||
"class_url": "20&21&22&23&24&25&26&27&28&29&30&31&32&33&34&35&36&37&38&39&40&41&42&43&44&45&46&47&48&49&50&51&52&53&54&55&56&57&58&65&66&67&68&69&70&71&72"
|
||||
},
|
||||
{
|
||||
"name": "量子资源",
|
||||
"url": "https://cj.lziapi.com",
|
||||
"parse_url": "",
|
||||
"cate_exclude": "电影片|连续剧|动漫片|综艺片|伦理片|电影解说|体育|演员|新闻资讯",
|
||||
"class_name": "H4sIALGjdWYC/zWR607DMAyF3ybPCbuxDom1Yms3UTEJtmWI0bSMAr1kvEzspG9B46S/8h3b8XEcvSpBFjq4Y+bvWTcfEHCmm9YEtY3B4oTtuyclU6I47Yss6XmB4ykRj6BqLOFtiDcx1QXcZ3G+UXVAsSepam49uuMWfwXR7q0PW8Iz19cHSybLQa7pxjLH6krZ5IDpmaj8gX1MdMn9XdjzbjtzkzPbeZkPIjn0FoMgCy/8NPRGXzYIN4kX1G0QztsJ1R51OKMF0BoNfzXiiyn5aEafzHxfdDhmWmR0yMgeGAsjapjeM2xXEG36QN4ljSknJhNDGyfgVKgqdHnWvUwgWpDVzn7SP/ilxw64AQAA",
|
||||
"class_url": "1&2&3&4&6&7&8&9&10&11&12&13&14&15&16&20&21&22&23&24&25&26&27&28&29&30&31&32&33&34&35&36&37&38&39&40&41&42&43&44&45&46"
|
||||
},
|
||||
{
|
||||
"name": "非凡资源",
|
||||
"url": "http://cj.ffzyapi.com",
|
||||
"parse_url": "",
|
||||
"cate_exclude": "电影片|连续剧|动漫片|综艺片|伦理片",
|
||||
"class_name": "H4sIAFhXhmYC/zWQWw6CMBBFd8M6NUakfggmChKJ/ADViFpiiPIobqadwi6kQ/k7d153ZtShlLxQZGP1v4tqHpJQSzVtT2odk9srtHdDgkdIfjQWaVJOAas1Et3LqtEESw8WPtYRarLgnERNMHbmoqbaY8hC+L6Q4tsY1gQ5Vd1OU/9kkh+xw2VQdZgNUohypPIjEx/pzUyvTOgQ2tPmlp7sslkE6WgxC7QwwmyDN5qyWUybGIHTZjF5T0K0mfJsfECsP/cHYziM500BAAA=",
|
||||
"class_url": "1&2&3&4&6&7&8&9&10&11&12&13&14&15&16&20&21&22&23&24&25&26&27&28&29&30&31&32&33&34&36"
|
||||
},
|
||||
{
|
||||
"name": "索尼资源",
|
||||
"url": "https://suoniapi.com",
|
||||
"parse_url": "",
|
||||
"cate_exclude": "电影|电视剧|综艺|动漫|体育赛事|预告片|影视解说|爽文短剧|伦理|港台三级|两性课堂|写真热舞",
|
||||
"class_name": "H4sIAFlXhmYC/z1RbXaCMBC8TU7QW/RSip/oq8orxVp56hNoaqtFq1gFopfJZsMtGhLor93Z3czuTNBNgB0IuomkXbApwSyXdkpg8CHyrzJw5qPdI+D5ql1m2D+IVkdn1IFrVmaiORENT8/ZtOqK/itPbV2bM57Skl1sKd5GZVYsN7owjXS4xGWA8V6jow6YfgJ70VTJL4SenghpMetWR6rHiqYGimK8r4HeU2sx640i86YG5px/regaNZqqnjG7K5C74B54/kY4e5bWj0zmPB0SjL9x0iLyfCxDsW6DM9BEXizjFDpDokxWBksayPikHGTC6+FyVyri+TtOutVOfrExNeaoo01HRnfhXeuxaST8bQX4JRQNKuMbrCwC3Rn6S2ztZH9BHh7RfKzwbQhqKRAdi7UjmkP1hcrrJ8m26hRjfCiDDs9m/LYicD3xLMDNXZ4HRLYdcVoIa4ueQ3C0V52ixeBikcJKxH5s9vwBtOQp10cCAAA=",
|
||||
"class_url": "1&2&3&4&6&7&8&9&10&11&12&13&14&15&16&17&18&19&20&23&25&26&27&28&29&30&31&39&44&45&47&48&49&50&51&52&53&54&55&56&57&58&59&60&61&62&63&64&65&66&67&68&69&70"
|
||||
},
|
||||
{
|
||||
"name": "️极速资源",
|
||||
"url": "https://jszyapi.com",
|
||||
"parse_url": "",
|
||||
"cate_exclude": "电视剧|电影|动漫|综艺|短剧|伦理片",
|
||||
"api": "/api.php/provide/vod/at/json/",
|
||||
"class_name": "H4sIAGJXhmYC/zVP0W7CMBD7m3znYKIQkICKUsaoxMsgsBUooEpQmn5N7i79iyVH+hTbsXw2JaVVEUglKClBXwXmipqpF9r9Gh8XRtujf3C1Y3bM8V54ZOo9zSOSQwHjg9GZRzS64ueAtTRzJtZUDM+XR9ib40fKv1IFH46+TCU9sucC9DLkYf0nIBpAxqecQAlHmMcJNjoYXCXM8o68q78JvWorKwGzAp8Nl9UL27/ZcmOqiYAf1a6j4HEhbmFH3ORZ0RFODIR6TfvdcON+TmnMy8YX0r/ceDcMG2l7cvf+AYiMpdZZAQAA",
|
||||
"class_url": "1&2&3&4&5&6&7&8&9&10&11&12&13&14&15&16&17&20&23&24&25&26&27&28&29&30&31&32&33&34&35&36&37&38"
|
||||
},
|
||||
{
|
||||
"name": "光速资源",
|
||||
"url": "https://api.guangsuapi.com",
|
||||
"parse_url": "",
|
||||
"cate_exclude": "电影|电视剧|综艺|动漫|记录片|伦理片|体育赛事|短剧",
|
||||
"class_name": "H4sIAFVXhmYC/y2Oaw6CMBCEb9Nz+ohINVGMiBpJ+KNW4gskJPJoT9PulltIF3/Nl5nJ7GJYGpkzDEsrPMMFw6a1vGZmcYP27kTLGPmcmSjuY0fo5zCdEYmNqRpKufh7MA5gFBH5B11zSs+iO9I6PASqFdH3Dapw1CWpk+EiDv/A/kLeOoNKUb3InNhXZuTOber2ioFHJLd28rHlSddLhsmz7/0A4RcQUdYAAAA=",
|
||||
"class_url": "1&2&3&4&6&7&8&9&10&11&12&13&14&15&16&20&21&22&23&24&25&30&31"
|
||||
},
|
||||
{
|
||||
"name": "卧龙资源",
|
||||
"url": "https://collect.wolongzy.cc",
|
||||
"parse_url": "",
|
||||
"cate_exclude": "电影片|连续剧|综艺片|动漫片|伦理片|电影解说|体育|短剧",
|
||||
"class_name": "H4sIAFZXhmYC/1WR0VLCQAxF/6bfqXQsbB9omYEq2JEHKqtQ2iIC0nbxZ5pk+Qt303VG307uZnJvsjQ9gtqTGHr6+4WaHQjpUdNqUVsNwjdst446lTIlqWmyRKM9+g9McgKXxhLex3iXcJ+Q7hVHT10tWHtWXS2tx209x6+SafluZEuYS7qOLUFU4eXK2uMrpjnT8QxZYkkXFagZ+y53LhxNmz8GHPt3niv6Qa4w1lHV7+kCuAIyeZsHrsBD9S+ak4lvpuVKl58e+iEOFuxdnKDu80SZXvHqMA4g+uAjDHJKJhw6LEltmMqCYt/r2jXFAf/B6WAFs5Yx/QEG4wmPmwEAAA==",
|
||||
"class_url": "1&2&3&4&5&6&7&8&9&10&11&12&13&14&15&16&17&18&22&23&24&25&26&27&30&31&32&33&37&38&39&42&43&44&45&46&48&49&51&54"
|
||||
},
|
||||
{
|
||||
"name": "无尽资源",
|
||||
"url": "https://api.wujinapi.me",
|
||||
"parse_url": "",
|
||||
"cate_exclude": "电影|连续剧|综艺|动漫|伦理片|体育赛事|影视解说|短剧|预告片|资讯|公告|头条|港台三级|韩国伦理|西方伦理|日本伦理|两性课堂|写真热舞",
|
||||
"class_name": "H4sIAFhXhmYC/zVRWVbCQBC8zZxTwxp8CnliFI2AEhzUaIIQhSxwmeklt3Ayk/xVdVe/7qqmaQrlVvB5TvkXuFJQXrCbCRhtsPgUnHb5O66ZKgNyBwL8QKtqRMMtdnoGSQ+OeY3wcoIXvtG5suni8EFlrqk9lSqT9ZLqbYaHuEYwTvB4MotPN1pgar0IvJGAcI/PL0IVbzTpmz3ZB5R3NaoW740W79cYRAalfxD6Zj6U1azfGNECrW6JXjpOWhJJvbP1a2+zru1MS4ysJU5EvmfMjDY0NaZpFFP5YWrrQRNE5aSYjMmGi7ukPkuVt+z8cPqksitB8TdNOkK3WfZZrjjeC1qYD9gj24XWVUOKKUy3qngU/Lurx6vXrk7KpGyG1MGlTDbx2OAEr8/oHxti42qIOoR4ITk+wdIR0J9RsKDOFw/nAgMXVu0JsN5Vrx5eXumP639dcxnR0ITPXQ/3c5uJgONe5St6P/Ov/t045FVP5TN1Wgq6SXSn6pRwcP4BxMt0fHACAAA=",
|
||||
"class_url": "1&2&3&4&5&6&7&8&9&10&11&12&13&14&15&16&17&18&20&21&22&23&24&25&26&27&28&29&30&31&32&33&34&35&36&37&38&39&40&41&42&43&44&45&46&47&48&49&50&51&52&53&54&55&56&57&58&59"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,378 @@
|
||||
globalThis.getRandomItem = function(items) {
|
||||
return items[Math.random() * items.length | 0];
|
||||
}
|
||||
var rule = {
|
||||
title: '采集之王[合]',
|
||||
author: '道长',
|
||||
version: '20240706 beta17',
|
||||
update_info: ``.trim(),
|
||||
host: '',
|
||||
homeTid: '',
|
||||
homeUrl: '/api.php/provide/vod/?ac=detail&t={{rule.homeTid}}',
|
||||
detailUrl: '/api.php/provide/vod/?ac=detail&ids=fyid',
|
||||
searchUrl: '/api.php/provide/vod/?wd=**&pg=#TruePage##page=fypage',
|
||||
classUrl: '/api.php/provide/vod/',
|
||||
url: '/api.php/provide/vod/?ac=detail&pg=fypage&t=fyfilter',
|
||||
filter_url: '{{fl.类型}}',
|
||||
headers: {
|
||||
'User-Agent': 'MOBILE_UA'
|
||||
},
|
||||
timeout: 5000,
|
||||
limit: 20,
|
||||
search_limit: 10,
|
||||
searchable: 1,
|
||||
quickSearch: 0,
|
||||
filterable: 1,
|
||||
play_parse: true,
|
||||
parse_url: '',
|
||||
search_match: false,
|
||||
search_pic: true,
|
||||
预处理: $js.toString(() => {
|
||||
function getClasses(item) {
|
||||
let classes = [];
|
||||
if (item.class_name && item.class_url) {
|
||||
if (!/&|电影|电视剧|综艺|动漫[\u4E00-\u9FA5]+/.test(item.class_name)) {
|
||||
try {
|
||||
item.class_name = ungzip(item.class_name)
|
||||
} catch (e) {
|
||||
log(`不识别的class_name导致gzip解码失败:${e}`)
|
||||
return classes
|
||||
}
|
||||
}
|
||||
let names = item.class_name.split('&');
|
||||
let urls = item.class_url.split('&');
|
||||
let cnt = Math.min(names.length, urls.length);
|
||||
for (let i = 0; i < cnt; i++) {
|
||||
classes.push({
|
||||
'type_id': urls[i],
|
||||
'type_name': names[i]
|
||||
});
|
||||
}
|
||||
}
|
||||
return classes
|
||||
}
|
||||
if (typeof(batchFetch) === 'function') {
|
||||
rule.search_limit = 16;
|
||||
log('当前程序支持批量请求[batchFetch],搜索限制已设置为16');
|
||||
}
|
||||
let _url = rule.params;
|
||||
log(`传入参数:${_url}`);
|
||||
if (_url && typeof(_url) === 'string' && /^(http|file)/.test(_url)) {
|
||||
if (_url.includes('$')) {
|
||||
let _url_params = _url.split('$');
|
||||
_url = _url_params[0];
|
||||
rule.search_match = !!(_url_params[1]);
|
||||
if (_url_params.length > 2) {
|
||||
rule.search_pic = !!(_url_params[2]);
|
||||
}
|
||||
}
|
||||
let html = request(_url);
|
||||
let json = JSON.parse(html);
|
||||
let _classes = [];
|
||||
rule.filter = {};
|
||||
rule.filter_def = {};
|
||||
json.forEach(it => {
|
||||
let _obj = {
|
||||
type_name: it.name,
|
||||
type_id: it.url,
|
||||
parse_url: it.parse_url || '',
|
||||
searchable: it.searchable !== 0,
|
||||
api: it.api || '',
|
||||
cate_exclude: it.cate_exclude || '',
|
||||
cate_excludes: it.cate_excludes || [],
|
||||
};
|
||||
_classes.push(_obj);
|
||||
try {
|
||||
let json1 = [];
|
||||
if (it.class_name && it.class_url) {
|
||||
json1 = getClasses(it);
|
||||
} else {
|
||||
json1 = JSON.parse(request(urljoin(_obj.type_id, _obj.api || rule.classUrl))).class;
|
||||
}
|
||||
if (_obj.cate_excludes && Array.isArray(_obj.cate_excludes) && _obj.cate_excludes.length > 0) {
|
||||
json1 = json1.filter(cl => !_obj.cate_excludes.includes(cl.type_name));
|
||||
} else if (_obj.cate_exclude) {
|
||||
json1 = json1.filter(cl => !new RegExp(_obj.cate_exclude, 'i').test(cl.type_name));
|
||||
}
|
||||
rule.filter[_obj.type_id] = [{
|
||||
"key": "类型",
|
||||
"name": "类型",
|
||||
"value": json1.map(i => {
|
||||
return {
|
||||
"n": i.type_name,
|
||||
'v': i.type_id
|
||||
}
|
||||
})
|
||||
}];
|
||||
if (json1.length > 0) {
|
||||
rule.filter_def[it.url] = {
|
||||
"类型": json1[0].type_id
|
||||
};
|
||||
}
|
||||
} catch (e) {
|
||||
rule.filter[it.url] = [{
|
||||
"key": "类型",
|
||||
"name": "类型",
|
||||
"value": [{
|
||||
"n": "全部",
|
||||
"v": ""
|
||||
}]
|
||||
}];
|
||||
}
|
||||
});
|
||||
rule.classes = _classes;
|
||||
}
|
||||
}),
|
||||
class_parse: $js.toString(() => {
|
||||
input = rule.classes;
|
||||
}),
|
||||
推荐: $js.toString(() => {
|
||||
VODS = [];
|
||||
if (rule.classes) {
|
||||
let randomClass = getRandomItem(rule.classes);
|
||||
let _url = urljoin(randomClass.type_id, input);
|
||||
if (randomClass.api) {
|
||||
_url = _url.replace('/api.php/provide/vod/', randomClass.api)
|
||||
}
|
||||
try {
|
||||
let html = request(_url, {
|
||||
timeout: rule.timeout
|
||||
});
|
||||
let json = JSON.parse(html);
|
||||
VODS = json.list;
|
||||
VODS.forEach(it => {
|
||||
it.vod_id = randomClass.type_id + '$' + it.vod_id;
|
||||
it.vod_remarks = it.vod_remarks + '|' + randomClass.type_name;
|
||||
});
|
||||
} catch (e) {}
|
||||
}
|
||||
}),
|
||||
一级: $js.toString(() => {
|
||||
VODS = [];
|
||||
if (rule.classes) {
|
||||
let _url = urljoin(MY_CATE, input);
|
||||
let current_vod = rule.classes.find(item => item.type_id === MY_CATE);
|
||||
if (current_vod && current_vod.api) {
|
||||
_url = _url.replace('/api.php/provide/vod/', current_vod.api)
|
||||
}
|
||||
let html = request(_url);
|
||||
let json = JSON.parse(html);
|
||||
VODS = json.list;
|
||||
VODS.forEach(it => {
|
||||
it.vod_id = MY_CATE + '$' + it.vod_id
|
||||
});
|
||||
}
|
||||
}),
|
||||
二级: $js.toString(() => {
|
||||
VOD = {};
|
||||
if (orId === 'update_info') {
|
||||
VOD = {
|
||||
vod_content: rule.update_info.trim(),
|
||||
vod_name: '更新日志',
|
||||
type_name: '更新日志',
|
||||
vod_pic: 'https://resource-cdn.tuxiaobei.com/video/FtWhs2mewX_7nEuE51_k6zvg6awl.png',
|
||||
vod_remarks: `版本:${rule.version}`,
|
||||
vod_play_from: '道长在线',
|
||||
vod_play_url: '随机小视频$http://api.yujn.cn/api/zzxjj.php',
|
||||
};
|
||||
} else {
|
||||
if (rule.classes) {
|
||||
let _url = urljoin(fyclass, input);
|
||||
let current_vod = rule.classes.find(item => item.type_id === fyclass);
|
||||
if (current_vod && current_vod.api) {
|
||||
_url = _url.replace('/api.php/provide/vod/', current_vod.api)
|
||||
}
|
||||
let html = request(_url);
|
||||
let json = JSON.parse(html);
|
||||
let data = json.list;
|
||||
VOD = data[0];
|
||||
if (current_vod && current_vod.type_name) {
|
||||
VOD.vod_play_from = VOD.vod_play_from.split('$$$').map(it => current_vod.type_name + '|' + it).join('$$$')
|
||||
}
|
||||
}
|
||||
}
|
||||
}),
|
||||
搜索: $js.toString(() => {
|
||||
VODS = [];
|
||||
if (rule.classes) {
|
||||
let canSearch = rule.classes.filter(it => it.searchable);
|
||||
let page = Number(MY_PAGE);
|
||||
page = (MY_PAGE - 1) % Math.ceil(canSearch.length / rule.search_limit) + 1;
|
||||
let truePage = Math.ceil(MY_PAGE / Math.ceil(canSearch.length / rule.search_limit));
|
||||
if (rule.search_limit) {
|
||||
let start = (page - 1) * rule.search_limit;
|
||||
let end = page * rule.search_limit;
|
||||
let t1 = new Date().getTime();
|
||||
let searchMode = typeof(batchFetch) === 'function' ? '批量' : '单个';
|
||||
log('start:' + start);
|
||||
log('end:' + end);
|
||||
log('搜索模式:' + searchMode);
|
||||
log('精准搜索:' + rule.search_match);
|
||||
log('强制获取图片:' + rule.search_pic);
|
||||
if (start < canSearch.length) {
|
||||
let search_classes = canSearch.slice(start, end);
|
||||
let urls = [];
|
||||
search_classes.forEach(it => {
|
||||
let _url = urljoin(it.type_id, input);
|
||||
if (it.api) {
|
||||
_url = _url.replace('/api.php/provide/vod/', it.api)
|
||||
}
|
||||
_url = _url.replace("#TruePage#", "" + truePage);
|
||||
urls.push(_url);
|
||||
});
|
||||
let results_list = [];
|
||||
let results = [];
|
||||
if (typeof(batchFetch) === 'function') {
|
||||
let reqUrls = urls.map(it => {
|
||||
return {
|
||||
url: it,
|
||||
options: {
|
||||
timeout: rule.timeout
|
||||
}
|
||||
}
|
||||
});
|
||||
let rets = batchFetch(reqUrls);
|
||||
let detailUrls = [];
|
||||
let detailUrlCount = 0;
|
||||
rets.forEach((ret, idx) => {
|
||||
let it = search_classes[idx];
|
||||
if (ret) {
|
||||
try {
|
||||
let json = JSON.parse(ret);
|
||||
let data = json.list;
|
||||
data.forEach(i => {
|
||||
i.site_name = it.type_name;
|
||||
i.vod_id = it.type_id + '$' + i.vod_id;
|
||||
i.vod_remarks = i.vod_remarks + '|' + it.type_name;
|
||||
});
|
||||
if (rule.search_match) {
|
||||
data = data.filter(item => item.vod_name && (new RegExp(KEY, 'i')).test(item.vod_name))
|
||||
}
|
||||
if (data.length > 0) {
|
||||
if (rule.search_pic && !data[0].vod_pic) {
|
||||
log(`当前搜索站点【${it.type_name}】没图片,尝试访问二级去获取图片`);
|
||||
let detailUrl = urls[idx].split('wd=')[0] + 'ac=detail&ids=' + data.map(k => k.vod_id.split('$')[1]).join(',');
|
||||
detailUrls.push(detailUrl);
|
||||
results_list.push({
|
||||
data: data,
|
||||
has_pic: false,
|
||||
detailUrlCount: detailUrlCount
|
||||
});
|
||||
detailUrlCount++;
|
||||
} else {
|
||||
results_list.push({
|
||||
data: data,
|
||||
has_pic: true
|
||||
});
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
log(`请求:${it.type_id}发生错误:${e.message}`)
|
||||
}
|
||||
}
|
||||
});
|
||||
let reqUrls2 = detailUrls.map(it => {
|
||||
return {
|
||||
url: it,
|
||||
options: {
|
||||
timeout: rule.timeout
|
||||
}
|
||||
}
|
||||
});
|
||||
let rets2 = reqUrls2.length > 0 ? batchFetch(reqUrls2) : [];
|
||||
for (let k = 0; k < results_list.length; k++) {
|
||||
let result_data = results_list[k].data;
|
||||
if (!results_list[k].has_pic) {
|
||||
try {
|
||||
let detailJson = JSON.parse(rets2[results_list[k].detailUrlCount]);
|
||||
log('二级数据列表元素数:' + detailJson.list.length);
|
||||
result_data.forEach((d, _seq) => {
|
||||
let detailVodPic = detailJson.list.find(vod => vod.vod_id.toString() === d.vod_id.split('$')[1]);
|
||||
if (detailVodPic) {
|
||||
Object.assign(d, {
|
||||
vod_pic: detailVodPic.vod_pic
|
||||
});
|
||||
}
|
||||
});
|
||||
} catch (e) {
|
||||
log(`强制获取网站${result_data[0].site_name}的搜索图片失败:${e.message}`);
|
||||
}
|
||||
}
|
||||
results = results.concat(result_data);
|
||||
}
|
||||
} else {
|
||||
urls.forEach((_url, idx) => {
|
||||
let it = search_classes[idx];
|
||||
try {
|
||||
let html = request(_url);
|
||||
let json = JSON.parse(html);
|
||||
let data = json.list;
|
||||
data.forEach(i => {
|
||||
i.vod_id = it.type_id + '$' + i.vod_id;
|
||||
i.vod_remarks = i.vod_remarks + '|' + it.type_name;
|
||||
});
|
||||
if (rule.search_match) {
|
||||
data = data.filter(item => item.vod_name && (new RegExp(KEY, 'i')).test(item.vod_name))
|
||||
}
|
||||
if (data.length > 0) {
|
||||
if (rule.search_pic && !data[0].vod_pic) {
|
||||
log(`当前搜索站点【${it.type_name}】没图片,尝试访问二级去获取图片`);
|
||||
let detailUrl = urls[idx].split('wd=')[0] + 'ac=detail&ids=' + data.map(k => k.vod_id.split('$')[1]).join(',');
|
||||
try {
|
||||
let detailJson = JSON.parse(request(detailUrl));
|
||||
log('二级数据列表元素数:' + detailJson.list.length);
|
||||
data.forEach((d, _seq) => {
|
||||
let detailVodPic = detailJson.list.find(vod => vod.vod_id.toString() === d.vod_id.split('$')[1]);
|
||||
if (detailVodPic) {
|
||||
Object.assign(d, {
|
||||
vod_pic: detailVodPic.vod_pic
|
||||
});
|
||||
}
|
||||
});
|
||||
} catch (e) {
|
||||
log(`强制获取网站${it.type_id}的搜索图片失败:${e.message}`);
|
||||
}
|
||||
}
|
||||
results = results.concat(data);
|
||||
}
|
||||
results = results.concat(data);
|
||||
} catch (e) {
|
||||
log(`请求:${it.type_id}发生错误:${e.message}`)
|
||||
}
|
||||
});
|
||||
}
|
||||
VODS = results;
|
||||
let t2 = new Date().getTime();
|
||||
log(`${searchMode}搜索:${urls.length}个站耗时:${(Number(t2) - Number(t1))}ms`)
|
||||
}
|
||||
}
|
||||
}
|
||||
}),
|
||||
lazy: $js.toString(() => {
|
||||
let parse_url = '';
|
||||
if (flag && flag.includes('|')) {
|
||||
let type_name = flag.split('|')[0];
|
||||
let current_vod = rule.classes.find(item => item.type_name === type_name);
|
||||
if (current_vod && current_vod.parse_url) {
|
||||
parse_url = current_vod.parse_url
|
||||
}
|
||||
}
|
||||
if (/\.(m3u8|mp4)/.test(input)) {
|
||||
input = {
|
||||
parse: 0,
|
||||
url: input
|
||||
}
|
||||
} else {
|
||||
if (parse_url.startsWith('json:')) {
|
||||
let purl = parse_url.replace('json:', '') + input;
|
||||
let html = request(purl);
|
||||
input = {
|
||||
parse: 0,
|
||||
url: JSON.parse(html).url
|
||||
}
|
||||
} else {
|
||||
input = parse_url + input;
|
||||
}
|
||||
}
|
||||
}),
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
@header({
|
||||
searchable: 0,
|
||||
filterable: 0,
|
||||
quickSearch: 0,
|
||||
title: '开眼视频',
|
||||
'类型': '影视',
|
||||
lang: 'ds'
|
||||
})
|
||||
*/
|
||||
|
||||
var rule = {
|
||||
title: '开眼视频',
|
||||
host: 'http://baobab.kaiyanapp.com:80',
|
||||
url: '/api/v5/index/tab/feed?udid=ecab2cc100f540e482c5f7db5542a33cc5a908bc&vc=591&vn=6.2.1&size=1080X2340&deviceModel=HLK-AL00&first_channel=eyepetizer_zhihuiyun_market&last_channel=eyepetizer_zhihuiyun_market&system_version_code=29',
|
||||
searchUrl: '',
|
||||
searchable: 0,
|
||||
quickSearch: 0,
|
||||
filterable: 0,
|
||||
headers: {
|
||||
'User-Agent': MOBILE_UA
|
||||
},
|
||||
class_name: '今日开眼精选',//静态分类名称拼接
|
||||
class_url: '/',//静态分类标识拼接
|
||||
timeout: 5000,
|
||||
play_parse: true,
|
||||
pagecount: {"/": 1},
|
||||
lazy: $js.toString(async () => {
|
||||
input = JSON.parse(await request(input)).playUrl + '&_t=.m3u8'
|
||||
return input
|
||||
}),
|
||||
|
||||
limit: 6,
|
||||
推荐: '',
|
||||
一级: $js.toString(async () => {
|
||||
var s = await request(input);
|
||||
var json = {};
|
||||
eval('json=' + s);
|
||||
var next = json.nextPageUrl;
|
||||
var s2 = await request(next, {});
|
||||
var j2 = {};
|
||||
eval('j2=' + s2);
|
||||
for (var i = 0; i < j2.itemList.length; i++) {
|
||||
json.itemList.push(j2.itemList[i])
|
||||
}
|
||||
var d = [];
|
||||
for (var i = 0; i < json.itemList.length; i++) {
|
||||
var j = json.itemList[i];
|
||||
if (j.type != 'followCard') continue;
|
||||
var r = {};
|
||||
r.pic_url = j.data.content.data.cover.feed;
|
||||
r.title = j.data.content.data.title;
|
||||
r.desc = j.data.header.description;
|
||||
r.url = 'https://baobab.kaiyanapp.com/api/v1/video/' + j.data.header.id + '?f=web';
|
||||
d.push(r)
|
||||
}
|
||||
return setResult(d)
|
||||
}),
|
||||
二级: '*',
|
||||
搜索: '',
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# @Author : Doubebly
|
||||
# @Time : 2025/5/19 21:19
|
||||
|
||||
import sys
|
||||
import requests
|
||||
import base64
|
||||
import os
|
||||
import time
|
||||
sys.path.append('..')
|
||||
from base.spider import Spider
|
||||
|
||||
|
||||
class Spider(Spider):
|
||||
def getName(self):
|
||||
return "BeeSport"
|
||||
|
||||
def init(self, extend):
|
||||
self.ext_time = 120
|
||||
self.cache_path = '/storage/emulated/0/TV/cache_BeeSport'
|
||||
if not os.path.exists(self.cache_path):
|
||||
os.mkdir(self.cache_path, 0o755)
|
||||
pass
|
||||
|
||||
def getDependence(self):
|
||||
return []
|
||||
|
||||
def isVideoFormat(self, url):
|
||||
pass
|
||||
|
||||
def manualVideoCheck(self):
|
||||
pass
|
||||
|
||||
|
||||
def liveContent(self, url):
|
||||
data_list = [{'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/TNT_SPORTS_1.png', 'group-title': 'BeeSport', 'name': 'TNT SPORTS 1', 'fun': 'beesport', 'pid': 'TNT_Sports_1'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/TNT_SPORTS_2.png', 'group-title': 'BeeSport', 'name': 'TNT SPORTS 2', 'fun': 'beesport', 'pid': 'TNT_Sports_2'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/TNT_SPORTS_3.png', 'group-title': 'BeeSport', 'name': 'TNT SPORTS 3', 'fun': 'beesport', 'pid': 'TNT_Sports_3'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/TNT_SPORTS_4.png', 'group-title': 'BeeSport', 'name': 'TNT SPORTS 4', 'fun': 'beesport', 'pid': 'TNT_Sports_4'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/SKY_SPORTS_FOOTBALL.png', 'group-title': 'BeeSport', 'name': 'SKY SPORTS FOOTBALL', 'fun': 'beesport', 'pid': 'Sky_Sports_Football_Live_TV'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/SKY_SPORTS_MAIN_EVENT.png', 'group-title': 'BeeSport', 'name': 'SKY SPORTS MAIN EVENT', 'fun': 'beesport', 'pid': 'Sky_Sports_Main_Event'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/SKY_SPORTS_PREMIER_LEAGUE.png', 'group-title': 'BeeSport', 'name': 'SKY SPORTS PREMIER LEAGUE', 'fun': 'beesport', 'pid': 'Sky_Sports_Premier_League'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/SKY_SPORTS_ACTION.png', 'group-title': 'BeeSport', 'name': 'SKY SPORTS ACTION', 'fun': 'beesport', 'pid': 'Sky_Sports_Action_Live_TV'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/SKY_SPORTS_MIX.png', 'group-title': 'BeeSport', 'name': 'SKY SPORTS MIX', 'fun': 'beesport', 'pid': 'Sky_Sports_Mix_Live_TV'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/SKY_SPORTS_ARENA.png', 'group-title': 'BeeSport', 'name': 'SKY SPORTS ARENA', 'fun': 'beesport', 'pid': 'Sky_Sports_Arena_Live_TV'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/SKY_SPORTS_NEWS.png', 'group-title': 'BeeSport', 'name': 'SKY SPORTS NEWS', 'fun': 'beesport', 'pid': 'Sky_Sports_News_Live_TV'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/SKY_SPORTS_CRICKET.png', 'group-title': 'BeeSport', 'name': 'SKY SPORTS CRICKET', 'fun': 'beesport', 'pid': 'Sky_Sports_Cricket_Live_TV'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/Sky_Sports_Tennis.png', 'group-title': 'BeeSport', 'name': 'Sky Sports Tennis', 'fun': 'beesport', 'pid': 'Sky_Sports_Tennis'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/SKY_SPORTS_F1.png', 'group-title': 'BeeSport', 'name': 'SKY SPORTS F1', 'fun': 'beesport', 'pid': 'Sky_Sports_F1_Live_TV'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/SKY_SPORTS_GOLF.png', 'group-title': 'BeeSport', 'name': 'SKY SPORTS GOLF', 'fun': 'beesport', 'pid': 'Sky_Sports_Golf_Live_TV'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/SKY_SPORTS_RACING.png', 'group-title': 'BeeSport', 'name': 'SKY SPORTS RACING', 'fun': 'beesport', 'pid': 'Sky_Sports_Racing_Live_TV'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/Sky_Sports_Darts.png', 'group-title': 'BeeSport', 'name': 'Sky Sports Darts', 'fun': 'beesport', 'pid': 'Sky_Sports_Darts'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/BEIN_SPORTS_USA.png', 'group-title': 'BeeSport', 'name': 'BEIN SPORTS USA', 'fun': 'beesport', 'pid': 'Bein_Sports_USA_Live_TV'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/TENNIS_CHANNEL.png', 'group-title': 'BeeSport', 'name': 'TENNIS CHANNEL', 'fun': 'beesport', 'pid': 'Tennis_Channel_Live_TV'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/LALIGA_TV_HD.png', 'group-title': 'BeeSport', 'name': 'LALIGA TV HD', 'fun': 'beesport', 'pid': 'La_Liga_TV_Live_TV'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/HBO_1.png', 'group-title': 'BeeSport', 'name': 'HBO 1', 'fun': 'beesport', 'pid': 'HBO_Live_TV'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/HBO_2.png', 'group-title': 'BeeSport', 'name': 'HBO 2', 'fun': 'beesport', 'pid': 'HBO_2_Live_TV'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/Discovery_Channel.png', 'group-title': 'BeeSport', 'name': 'Discovery Channel', 'fun': 'beesport', 'pid': 'Discovery_Channel_Live_TV'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/Discovery_Life.png', 'group-title': 'BeeSport', 'name': 'Discovery Life', 'fun': 'beesport', 'pid': 'Discovery_Life_Live_TV'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/Cinemax_West.png', 'group-title': 'BeeSport', 'name': 'Cinemax West', 'fun': 'beesport', 'pid': 'Cinemax_West_Live_TV'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/Great_Movies.png', 'group-title': 'BeeSport', 'name': 'Great Movies', 'fun': 'beesport', 'pid': 'UK_Great_Movies_Live_TV'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/Sky_Cinema_Comedy.png', 'group-title': 'BeeSport', 'name': 'Sky Cinema Comedy', 'fun': 'beesport', 'pid': 'UK_Sky_Cinema_Comedy_Live_TV'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/Sky_Cinema_Family.png', 'group-title': 'BeeSport', 'name': 'Sky Cinema Family', 'fun': 'beesport', 'pid': 'UK_Sky_Cinema_Family_Live_TV'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/Cartoon_Network.png', 'group-title': 'BeeSport', 'name': 'Cartoon Network', 'fun': 'beesport', 'pid': 'UK_Cartoon_Network_Live_TV'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/Virgin_2.png', 'group-title': 'BeeSport', 'name': 'Virgin 2', 'fun': 'beesport', 'pid': 'UK_Virgin_2'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/Virgin_3.png', 'group-title': 'BeeSport', 'name': 'Virgin 3', 'fun': 'beesport', 'pid': 'UK_Virgin_3'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/Virgin_1.png', 'group-title': 'BeeSport', 'name': 'Virgin 1', 'fun': 'beesport', 'pid': 'UK_Virgin_1'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/Bein_Sports_English_2.png', 'group-title': 'BeeSport', 'name': 'Bein Sports English 2', 'fun': 'beesport', 'pid': 'Bein_Sports_English_2_Live_TV'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/SuperSport_Premier_League.png', 'group-title': 'BeeSport', 'name': 'SuperSport Premier League', 'fun': 'beesport', 'pid': 'SuperSport_Premier_League_Live_TV'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/SuperSport_LaLiga.png', 'group-title': 'BeeSport', 'name': 'SuperSport LaLiga', 'fun': 'beesport', 'pid': 'SuperSport_LaLiga_Live_TV'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/SuperSport_Action.png', 'group-title': 'BeeSport', 'name': 'SuperSport Action', 'fun': 'beesport', 'pid': 'SuperSport_Action_Live_TV'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/SuperSport_Blitz.png', 'group-title': 'BeeSport', 'name': 'SuperSport Blitz', 'fun': 'beesport', 'pid': 'SuperSport_Blitz_Live_TV'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/SuperSport_Cricket.png', 'group-title': 'BeeSport', 'name': 'SuperSport Cricket', 'fun': 'beesport', 'pid': 'SuperSport_Cricket_Live_TV'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/SuperSport_Football.png', 'group-title': 'BeeSport', 'name': 'SuperSport Football', 'fun': 'beesport', 'pid': 'SuperSport_Football_Live_TV'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/SuperSport_Golf.png', 'group-title': 'BeeSport', 'name': 'SuperSport Golf', 'fun': 'beesport', 'pid': 'SuperSport_Golf_Live_TV'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/SuperSport_Rugby.png', 'group-title': 'BeeSport', 'name': 'SuperSport Rugby', 'fun': 'beesport', 'pid': 'SuperSport_Rugby_Live_TV'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/SuperSport_Tennis.png', 'group-title': 'BeeSport', 'name': 'SuperSport Tennis', 'fun': 'beesport', 'pid': 'SuperSport_Tennis_Live_TV'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/Variety_1.png', 'group-title': 'BeeSport', 'name': 'Variety 1', 'fun': 'beesport', 'pid': 'Variety_1_Live_TV'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/Variety_2.png', 'group-title': 'BeeSport', 'name': 'Variety 2', 'fun': 'beesport', 'pid': 'Variety_2_Live_TV'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/Variety_3.png', 'group-title': 'BeeSport', 'name': 'Variety 3', 'fun': 'beesport', 'pid': 'Variety_3_Live_TV'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/Variety_4.png', 'group-title': 'BeeSport', 'name': 'Variety 4', 'fun': 'beesport', 'pid': 'Variety_4_Live_TV'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/Eurosport_1.png', 'group-title': 'BeeSport', 'name': 'Eurosport 1', 'fun': 'beesport', 'pid': 'Eurosport_1_Live_TV'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/Eurosport_2.png', 'group-title': 'BeeSport', 'name': 'Eurosport 2', 'fun': 'beesport', 'pid': 'Eurosport_2_Live_TV'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/Premier_Sports_1.png', 'group-title': 'BeeSport', 'name': 'Premier Sports 1', 'fun': 'beesport', 'pid': 'Premier_Sports_1'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/Premier_Sports_2.png', 'group-title': 'BeeSport', 'name': 'Premier Sports 2', 'fun': 'beesport', 'pid': 'Premier_Sports_2'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/Golf_Channel.png', 'group-title': 'BeeSport', 'name': 'Golf Channel', 'fun': 'beesport', 'pid': 'Golf_Channel_Live_TV'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/MLB_Network.png', 'group-title': 'BeeSport', 'name': 'MLB Network', 'fun': 'beesport', 'pid': 'MLB_Network_Live_TV'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/NBA_TV.png', 'group-title': 'BeeSport', 'name': 'NBA TV', 'fun': 'beesport', 'pid': 'NBA_TV_Live_TV'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/NFL_Network.png', 'group-title': 'BeeSport', 'name': 'NFL Network', 'fun': 'beesport', 'pid': 'NFL_Network_Live_TV'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/NFL_REDZONE.png', 'group-title': 'BeeSport', 'name': 'NFL REDZONE', 'fun': 'beesport', 'pid': 'NFL_REDZONE_Live_TV'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/NHL_Network.png', 'group-title': 'BeeSport', 'name': 'NHL Network', 'fun': 'beesport', 'pid': 'NHL_Network_Live_TV'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/WWE.png', 'group-title': 'BeeSport', 'name': 'WWE', 'fun': 'beesport', 'pid': 'WWE_Live_TV'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/Willow_Cricket.png', 'group-title': 'BeeSport', 'name': 'Willow Cricket', 'fun': 'beesport', 'pid': 'Willow_Cricket_Live_TV'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/Willow_Extra.png', 'group-title': 'BeeSport', 'name': 'Willow Extra', 'fun': 'beesport', 'pid': 'Willow_Extra_Live_TV'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/World_Fishing_Network.png', 'group-title': 'BeeSport', 'name': 'World Fishing Network', 'fun': 'beesport', 'pid': 'World_Fishing_Network_Live_TV'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/ESPN.png', 'group-title': 'BeeSport', 'name': 'ESPN', 'fun': 'beesport', 'pid': 'ESPN_Live_TV'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/ESPN_2.png', 'group-title': 'BeeSport', 'name': 'ESPN 2', 'fun': 'beesport', 'pid': 'ESPN_2_Live_TV'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/ESPN_News.png', 'group-title': 'BeeSport', 'name': 'ESPN News', 'fun': 'beesport', 'pid': 'ESPN_News_Live_TV'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/ESPN_U.png', 'group-title': 'BeeSport', 'name': 'ESPN U', 'fun': 'beesport', 'pid': 'ESPN_U_Live_TV'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/ITV_1.png', 'group-title': 'BeeSport', 'name': 'ITV 1', 'fun': 'beesport', 'pid': 'ITV_1'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/ITV_2.png', 'group-title': 'BeeSport', 'name': 'ITV 2', 'fun': 'beesport', 'pid': 'ITV_2'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/ITV_3.png', 'group-title': 'BeeSport', 'name': 'ITV 3', 'fun': 'beesport', 'pid': 'ITV_3'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/ITV_4.png', 'group-title': 'BeeSport', 'name': 'ITV 4', 'fun': 'beesport', 'pid': 'ITV_4'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/MUTV.png', 'group-title': 'BeeSport', 'name': 'MUTV', 'fun': 'beesport', 'pid': 'MUTV_Live_TV'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/LFC_TV.png', 'group-title': 'BeeSport', 'name': 'LFC TV', 'fun': 'beesport', 'pid': 'LFC_TV_Live_TV'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/FOX_NEWS.png', 'group-title': 'BeeSport', 'name': 'FOX NEWS', 'fun': 'beesport', 'pid': 'FOX_NEWS_Live_TV'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/ACC_Network.png', 'group-title': 'BeeSport', 'name': 'ACC Network', 'fun': 'beesport', 'pid': 'ACC_Network_Live_TV'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/Fight_Network.png', 'group-title': 'BeeSport', 'name': 'Fight Network', 'fun': 'beesport', 'pid': 'Fight_Network_Live_TV'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/CBS_Sports_Network.png', 'group-title': 'BeeSport', 'name': 'CBS Sports Network', 'fun': 'beesport', 'pid': 'CBS_Sports_Network_Live_TV'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/CNBC.png', 'group-title': 'BeeSport', 'name': 'CNBC', 'fun': 'beesport', 'pid': 'CNBC_Live_TV'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/Fox_Sports_1.png', 'group-title': 'BeeSport', 'name': 'Fox Sports 1', 'fun': 'beesport', 'pid': 'Fox_Sports_1_Live_TV'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/Fox_Sports_2.png', 'group-title': 'BeeSport', 'name': 'Fox Sports 2', 'fun': 'beesport', 'pid': 'Fox_Sports_2_Live_TV'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/Nat_Geo_Wild_HD.png', 'group-title': 'BeeSport', 'name': 'Nat Geo Wild HD', 'fun': 'beesport', 'pid': 'Nat_Geo_Wild_HD'}, {'tvg-id': '', 'tvg-name': '', 'tvg-logo': 'https://logo.doube.eu.org/beesport/ABC_Channel.png', 'group-title': 'BeeSport', 'name': 'ABC Channel', 'fun': 'beesport', 'pid': 'ABC'}]
|
||||
|
||||
tv_list = ['#EXTM3U']
|
||||
for i in data_list:
|
||||
tvg_id = i['tvg-id']
|
||||
tvg_name = i['tvg-name']
|
||||
tvg_logo = i['tvg-logo']
|
||||
group_name = i['group-title']
|
||||
name = i['name']
|
||||
fun = i['fun']
|
||||
pid = i['pid']
|
||||
tv_list.append(f'#EXTINF:-1 tvg-id="{tvg_id}" tvg-name="{tvg_name}" tvg-logo="{tvg_logo}" group-title="{group_name}",{name}')
|
||||
tv_list.append(f'{self.getProxyUrl()}&fun={fun}&pid={pid}&Author=Doubebly&TG=t.me/doubebly001')
|
||||
|
||||
return '\n'.join(tv_list)
|
||||
|
||||
def homeContent(self, filter):
|
||||
return {}
|
||||
|
||||
def homeVideoContent(self):
|
||||
return {}
|
||||
|
||||
def categoryContent(self, cid, page, filter, ext):
|
||||
return {}
|
||||
|
||||
def detailContent(self, did):
|
||||
return {}
|
||||
|
||||
def searchContent(self, key, quick, page='1'):
|
||||
return {}
|
||||
|
||||
def searchContentPage(self, keywords, quick, page):
|
||||
return {}
|
||||
|
||||
def playerContent(self, flag, pid, vipFlags):
|
||||
return {}
|
||||
|
||||
def localProxy(self, params):
|
||||
_fun = params.get('fun', None)
|
||||
_type = params.get('type', None)
|
||||
if _fun is not None:
|
||||
fun = getattr(self, f'fun_{_fun}')
|
||||
return fun(params)
|
||||
return [302, "text/plain", None, {'Location': 'https://sf1-cdn-tos.huoshanstatic.com/obj/media-fe/xgplayer_doc_video/mp4/xgplayer-demo-720p.mp4'}]
|
||||
|
||||
|
||||
def fun_beesport(self, params):
|
||||
pid = params['pid']
|
||||
cache_play_url = self.cache_get(pid)
|
||||
if cache_play_url != 'False':
|
||||
return [302, "text/plain", None, {'Location': cache_play_url}]
|
||||
headers = {
|
||||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36',
|
||||
'Accept': 'application/json, text/plain, */*',
|
||||
'Content-Type': 'application/json',
|
||||
'accept-language': 'zh-CN,zh;q=0.9',
|
||||
'cache-control': 'no-cache',
|
||||
'origin': 'https://beesports.net',
|
||||
'referer': 'https://beesports.net/live-tv',
|
||||
}
|
||||
|
||||
json_data = {
|
||||
'channel': f'https://live_tv.starcdnup.com/{pid}/index.m3u8',
|
||||
}
|
||||
try:
|
||||
response = requests.post('https://beesports.net/authorize-channel', headers=headers, json=json_data)
|
||||
url = response.json()['channels'][0]
|
||||
self.cache_set(pid, url)
|
||||
return [302, "text/plain", None, {'Location': url}]
|
||||
except Exception as e:
|
||||
return [302, "text/plain", None, {'Location': 'https://sf1-cdn-tos.huoshanstatic.com/obj/media-fe/xgplayer_doc_video/mp4/xgplayer-demo-720p.mp4'}]
|
||||
|
||||
def destroy(self):
|
||||
files_and_dirs = os.listdir(self.cache_path)
|
||||
if len(files_and_dirs) > 0:
|
||||
for file in files_and_dirs:
|
||||
os.remove(os.path.join(self.cache_path, file))
|
||||
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')
|
||||
|
||||
|
||||
def cache_get(self, key):
|
||||
t = time.time()
|
||||
path = self.cache_getkey(key)
|
||||
if not os.path.exists(path):
|
||||
return 'False'
|
||||
if t - os.path.getmtime(path) > self.ext_time:
|
||||
return 'False'
|
||||
with open(path, 'r', encoding='utf-8') as f:
|
||||
data = f.read()
|
||||
return data
|
||||
|
||||
def cache_set(self, key, data):
|
||||
path = self.cache_getkey(key)
|
||||
with open(path, 'w', encoding='utf-8') as f:
|
||||
f.write(data)
|
||||
return True
|
||||
|
||||
def cache_getkey(self, key):
|
||||
return self.cache_path + '/' + key + '.txt'
|
||||
|
||||
if __name__ == '__main__':
|
||||
pass
|
||||
@@ -0,0 +1 @@
|
||||
qz2VfkB3O9fqiff5MjJa/NOxIkzNuMv7K54K23vKJOSw++yJ8kLPZGH7bSG3+EXPJY4dOis9/GmHOYeyeMy//PyKssixOko3oIgwnF/Wvp6XlI3OCc7zhBgQ8xOn0n9oLPbSEExGIWgGxvOR/ODV4I1v0wmPMgyW00MzdLsv1c63MhvJ4u0rn/PVTFAzjot5UYZX0CLITPyfYYFnXhgZbdWozbtXnCf8pWNvklRqA8dwmt99s4vDbQIdgP9FKzWoEEY8IpQLj6UUY5dCK3o5MsqTiR2cR0ElVNihHFn+0DKpFoo25ia/EOxuikIKEz/BmR2DPAZOwWpmkfgoRoUQokUyIT1MDpff9RnKfmDIWeavJ2xEdU67vXSOogoU1KJAVYtWM1Jz+HlFkkEDaJJUE8lrJioefdX2ydQHFfOvOLFkZhttXjEUw2WFB5DqUvRI4JLh/JgX4fXxAMthkI3uoA2Gr25j9rG0j+pcYURhM90/QSRvgwdAAH/kY/ZyXKAfcUA3hMGUSNfsW4lgFmXsG6MJ7NQB/CF2LS4odJHgyoTPewBdmrBS8UcorjNjQxbsxsLOfUQfp3TE/Sc49FqJbVIBuUyR2zcmb01RSDDHZCuWlESsifVgWdHp1y2htihLLytnk1bS5cnRSxZEDgR3Xp3X1Qe442pP6j+sOLtEh7vITquloxCzDUx1uDhVPyWVt4tvDYE3yE56XoDmCmbQCfRPlYrZSG04kctuUWjJa9XJLMgpsh71KCed+4c6KOOoXs/AzKwnpGqbjDF4g0pp/onRuX3f5SRhILLOVuSepTb9uuV6KZFZjMkNTTANF1aNan6nYnvaCKsJbuE2t+XBMdWtDspLek9kA3rtMO13fnYWrWDNJB6tnBN8Kl7yWmmpP1UzpudJpFG5BaREYJO3db7+ojE21P51TjlZj2a7Y0xzbx4KsbJWfcAViSIBy8ov32//IaCvunSNyTY/KyAJKPdSL4Ab8q/C1loBbw+aMpju6AQGzi+/mMtoG1exN8niMg0WF4sV5mUiaZm2rptIJ7KuY4IssB4NhyZz83MmEqgNdQcmJ0AiG1YY81MUXqM/Nse78Dnur4MjB4vlAqIgpU4l4GluOMKbzB3CbDGcHZAQi6a8iqha1TtccfrhBE2jacQ3Qy9//gNYMC+d119EMK3r8gkIuMPa9lbuvKuy9AgiiqpcqI4n3u09OAgCntLq74qjLQE6olqspABTcVUfeTV/10Ybsh6hR8+4aQcbkpU2pRdRQPZmO74qTO4xBChV8mjHwYluNHcuSxjOuniJ88Qxk2bJQcISafMnA5u65/PdQPr6AQhNz88czKCuiOMeuHJd7ZXOgNKN4y2NCf+gNZZiHgOxlQu5ENtBPK/qkRGHjy2BvONFhF56QdUeEWrudCUUQwfcPWy3HKR+32ZX8VjgXGtZAyHXszCJEWAbyBia6zRYVVmLV8P3ND7nAEqxShOFLbTQrYBDFKHxfwVgOiUyXpS3R7v591TJ1+tABKwsTddlf8zx6gmRQG5Evg4NSuRbBJPiU0b9xYWsjdCy5VMqzyDypj5kOEn3/coJVSg8fFnGgUNpaLycOd4NDy9kVT8h3eriDms/TJlp5FCb/SGAWQmbbUWchKCCyIw6sdzL9tveAwtGx+lsePJRKc1q/1VzgAX3OEOD3gXPzx01XC2GtBfYKw+NjYw+q/eGt3I=
|
||||
@@ -0,0 +1,790 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# 偷乐短剧爬虫
|
||||
|
||||
import sys
|
||||
import json
|
||||
import re
|
||||
import time
|
||||
import urllib.parse
|
||||
import requests
|
||||
from bs4 import BeautifulSoup
|
||||
|
||||
# 导入基础类
|
||||
sys.path.append('../../')
|
||||
try:
|
||||
from base.spider import Spider
|
||||
except ImportError:
|
||||
# 本地调试时的替代实现
|
||||
class Spider:
|
||||
def init(self, extend=""):
|
||||
pass
|
||||
|
||||
class Spider(Spider):
|
||||
def __init__(self):
|
||||
# 网站主URL
|
||||
self.siteUrl = "https://www.toule.top"
|
||||
|
||||
# 根据网站实际结构,分类链接格式为: /index.php/vod/show/class/分类名/id/1.html
|
||||
# 分类ID映射 - 从网站中提取的分类
|
||||
self.cateManual = {
|
||||
"男频": "/index.php/vod/show/class/%E7%94%B7%E9%A2%91/id/1.html",
|
||||
"女频": "/index.php/vod/show/class/%E5%A5%B3%E9%A2%91/id/1.html",
|
||||
"都市": "/index.php/vod/show/class/%E9%83%BD%E5%B8%82/id/1.html",
|
||||
"赘婿": "/index.php/vod/show/class/%E8%B5%98%E5%A9%BF/id/1.html",
|
||||
"战神": "/index.php/vod/show/class/%E6%88%98%E7%A5%9E/id/1.html",
|
||||
"古代言情": "/index.php/vod/show/class/%E5%8F%A4%E4%BB%A3%E8%A8%80%E6%83%85/id/1.html",
|
||||
"现代言情": "/index.php/vod/show/class/%E7%8E%B0%E4%BB%A3%E8%A8%80%E6%83%85/id/1.html",
|
||||
"历史": "/index.php/vod/show/class/%E5%8E%86%E5%8F%B2/id/1.html",
|
||||
"玄幻": "/index.php/vod/show/class/%E7%8E%84%E5%B9%BB/id/1.html",
|
||||
"搞笑": "/index.php/vod/show/class/%E6%90%9E%E7%AC%91/id/1.html",
|
||||
"甜宠": "/index.php/vod/show/class/%E7%94%9C%E5%AE%A0/id/1.html",
|
||||
"励志": "/index.php/vod/show/class/%E5%8A%B1%E5%BF%97/id/1.html",
|
||||
"逆袭": "/index.php/vod/show/class/%E9%80%86%E8%A2%AD/id/1.html",
|
||||
"穿越": "/index.php/vod/show/class/%E7%A9%BF%E8%B6%8A/id/1.html",
|
||||
"古装": "/index.php/vod/show/class/%E5%8F%A4%E8%A3%85/id/1.html"
|
||||
}
|
||||
|
||||
# 请求头
|
||||
self.headers = {
|
||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36",
|
||||
"Referer": "https://www.toule.top/",
|
||||
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
|
||||
"Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
|
||||
"Accept-Encoding": "gzip, deflate, br",
|
||||
"Connection": "keep-alive",
|
||||
}
|
||||
|
||||
|
||||
# 缓存
|
||||
self.cache = {}
|
||||
self.cache_timeout = {}
|
||||
|
||||
def getName(self):
|
||||
return "偷乐短剧"
|
||||
|
||||
def init(self, extend=""):
|
||||
# 初始化方法,可以留空
|
||||
return
|
||||
|
||||
def isVideoFormat(self, url):
|
||||
"""判断是否为视频格式"""
|
||||
video_formats = ['.mp4', '.m3u8', '.ts', '.flv', '.avi', '.mkv', '.mov', '.rmvb', '.3gp']
|
||||
for format in video_formats:
|
||||
if format in url.lower():
|
||||
return True
|
||||
return False
|
||||
|
||||
def manualVideoCheck(self):
|
||||
"""是否需要手动检查视频"""
|
||||
return False
|
||||
|
||||
# 工具方法 - 网络请求
|
||||
def fetch(self, url, headers=None, data=None, method="GET"):
|
||||
"""统一的网络请求方法"""
|
||||
try:
|
||||
if headers is None:
|
||||
headers = self.headers.copy()
|
||||
|
||||
if method.upper() == "GET":
|
||||
response = requests.get(url, headers=headers, params=data, timeout=10,verify=False)
|
||||
else: # POST
|
||||
response = requests.post(url, headers=headers, data=data, timeout=10,verify=False)
|
||||
|
||||
response.raise_for_status()
|
||||
response.encoding = response.apparent_encoding or 'utf-8'
|
||||
return response
|
||||
except Exception as e:
|
||||
self.log(f"请求失败: {url}, 错误: {str(e)}", "ERROR")
|
||||
return None
|
||||
|
||||
# 缓存方法
|
||||
def getCache(self, key, timeout=3600):
|
||||
"""获取缓存数据"""
|
||||
if key in self.cache and key in self.cache_timeout:
|
||||
if time.time() < self.cache_timeout[key]:
|
||||
return self.cache[key]
|
||||
else:
|
||||
del self.cache[key]
|
||||
del self.cache_timeout[key]
|
||||
return None
|
||||
|
||||
def setCache(self, key, value, timeout=3600):
|
||||
"""设置缓存数据"""
|
||||
self.cache[key] = value
|
||||
self.cache_timeout[key] = time.time() + timeout
|
||||
|
||||
# 日志方法
|
||||
def log(self, msg, level='INFO'):
|
||||
"""记录日志"""
|
||||
levels = {
|
||||
'DEBUG': 0,
|
||||
'INFO': 1,
|
||||
'WARNING': 2,
|
||||
'ERROR': 3
|
||||
}
|
||||
|
||||
current_level = 'INFO' # 可以设置为DEBUG以获取更多信息
|
||||
|
||||
if levels.get(level, 4) >= levels.get(current_level, 1):
|
||||
print(f"[{level}] {time.strftime('%Y-%m-%d %H:%M:%S')} - {msg}")
|
||||
|
||||
# 辅助方法 - 从URL中提取视频ID
|
||||
def extractVodId(self, url):
|
||||
"""从URL中提取视频ID"""
|
||||
# 路径格式: /index.php/vod/play/id/9024/sid/1/nid/1.html
|
||||
match = re.search(r'/id/(\d+)/', url)
|
||||
if match:
|
||||
return match.group(1)
|
||||
return ""
|
||||
|
||||
# 辅助方法 - 从网页内容中提取分类
|
||||
def extractCategories(self, text):
|
||||
"""从网页内容中提取分类标签"""
|
||||
cats = []
|
||||
# 匹配标签字符串,例如: "男频,逆袭,亲情,短剧"
|
||||
if "," in text:
|
||||
parts = text.split(",")
|
||||
for part in parts:
|
||||
part = part.strip()
|
||||
if part and part != "短剧":
|
||||
cats.append(part)
|
||||
return cats
|
||||
|
||||
# 主要接口实现
|
||||
def homeContent(self, filter):
|
||||
"""获取首页分类及内容"""
|
||||
result = {}
|
||||
classes = []
|
||||
|
||||
# 从缓存获取
|
||||
cache_key = 'home_classes'
|
||||
cached_classes = self.getCache(cache_key)
|
||||
if cached_classes:
|
||||
classes = cached_classes
|
||||
else:
|
||||
# 使用预定义的分类
|
||||
for k, v in self.cateManual.items():
|
||||
classes.append({
|
||||
'type_id': v, # 使用完整URL路径作为type_id
|
||||
'type_name': k
|
||||
})
|
||||
|
||||
# 保存到缓存
|
||||
self.setCache(cache_key, classes, 24*3600) # 缓存24小时
|
||||
|
||||
result['class'] = classes
|
||||
|
||||
# 获取首页推荐视频
|
||||
videos = self.homeVideoContent().get('list', [])
|
||||
result['list'] = videos
|
||||
|
||||
return result
|
||||
|
||||
def homeVideoContent(self):
|
||||
"""获取首页推荐视频内容"""
|
||||
result = {'list': []}
|
||||
videos = []
|
||||
|
||||
# 从缓存获取
|
||||
cache_key = 'home_videos'
|
||||
cached_videos = self.getCache(cache_key)
|
||||
if cached_videos:
|
||||
return {'list': cached_videos}
|
||||
|
||||
try:
|
||||
response = self.fetch(self.siteUrl)
|
||||
if response and response.status_code == 200:
|
||||
html = response.text
|
||||
soup = BeautifulSoup(html, 'html.parser')
|
||||
|
||||
# 查找最新更新区域
|
||||
latest_section = soup.find('h2', text=lambda t: t and '最新更新' in t)
|
||||
if latest_section:
|
||||
container = latest_section.parent # 获取容器
|
||||
if container:
|
||||
# 查找所有 li.item 元素
|
||||
items = container.find_all('li', class_='item')
|
||||
|
||||
for item in items:
|
||||
try:
|
||||
# 获取链接和标题
|
||||
title_link = item.find('h3')
|
||||
if not title_link:
|
||||
continue
|
||||
|
||||
title = title_link.text.strip()
|
||||
|
||||
# 获取第一个链接作为详情页链接
|
||||
link_tag = item.find('a')
|
||||
if not link_tag:
|
||||
continue
|
||||
|
||||
link = link_tag.get('href', '')
|
||||
if not link.startswith('http'):
|
||||
link = urllib.parse.urljoin(self.siteUrl, link)
|
||||
|
||||
# 提取ID
|
||||
vid = self.extractVodId(link)
|
||||
if not vid:
|
||||
continue
|
||||
|
||||
# 获取图片
|
||||
img_tag = item.find('img')
|
||||
img_url = ""
|
||||
if img_tag:
|
||||
img_url = img_tag.get('src', img_tag.get('data-src', ''))
|
||||
if img_url and not img_url.startswith('http'):
|
||||
img_url = urllib.parse.urljoin(self.siteUrl, img_url)
|
||||
|
||||
# 获取备注信息
|
||||
remarks = ""
|
||||
remarks_tag = item.find('span', class_='remarks')
|
||||
if remarks_tag:
|
||||
remarks = remarks_tag.text.strip()
|
||||
|
||||
# 获取标签信息
|
||||
tags = ""
|
||||
tags_tag = item.find('span', class_='tags')
|
||||
if tags_tag:
|
||||
tags = tags_tag.text.strip()
|
||||
|
||||
# 合并备注和标签
|
||||
if remarks and tags:
|
||||
remarks = f"{remarks} | {tags}"
|
||||
elif tags:
|
||||
remarks = tags
|
||||
|
||||
# 构建视频项
|
||||
videos.append({
|
||||
'vod_id': vid,
|
||||
'vod_name': title,
|
||||
'vod_pic': img_url,
|
||||
'vod_remarks': remarks
|
||||
})
|
||||
except Exception as e:
|
||||
self.log(f"处理视频项时出错: {str(e)}", "ERROR")
|
||||
continue
|
||||
|
||||
# 保存到缓存
|
||||
self.setCache(cache_key, videos, 3600) # 缓存1小时
|
||||
except Exception as e:
|
||||
self.log(f"获取首页视频内容发生错误: {str(e)}", "ERROR")
|
||||
|
||||
result['list'] = videos
|
||||
return result
|
||||
|
||||
def categoryContent(self, tid, pg, filter, extend):
|
||||
"""获取分类内容"""
|
||||
result = {}
|
||||
videos = []
|
||||
|
||||
# 处理页码
|
||||
if pg is None:
|
||||
pg = 1
|
||||
else:
|
||||
pg = int(pg)
|
||||
|
||||
# 构建分类URL - tid是完整的URL路径
|
||||
if tid.startswith("/"):
|
||||
# 替换页码,URL格式可能像: /index.php/vod/show/class/男频/id/1.html
|
||||
if pg > 1:
|
||||
if "html" in tid:
|
||||
category_url = tid.replace(".html", f"/page/{pg}.html")
|
||||
else:
|
||||
category_url = f"{tid}/page/{pg}.html"
|
||||
else:
|
||||
category_url = tid
|
||||
|
||||
full_url = urllib.parse.urljoin(self.siteUrl, category_url)
|
||||
else:
|
||||
# 如果tid不是URL路径,可能是旧版分类ID,尝试查找对应URL
|
||||
category_url = ""
|
||||
for name, url in self.cateManual.items():
|
||||
if name == tid:
|
||||
category_url = url
|
||||
break
|
||||
|
||||
if not category_url:
|
||||
self.log(f"未找到分类ID对应的URL: {tid}", "ERROR")
|
||||
result['list'] = []
|
||||
result['page'] = pg
|
||||
result['pagecount'] = 1
|
||||
result['limit'] = 0
|
||||
result['total'] = 0
|
||||
return result
|
||||
|
||||
# 处理页码
|
||||
if pg > 1:
|
||||
if "html" in category_url:
|
||||
category_url = category_url.replace(".html", f"/page/{pg}.html")
|
||||
else:
|
||||
category_url = f"{category_url}/page/{pg}.html"
|
||||
|
||||
full_url = urllib.parse.urljoin(self.siteUrl, category_url)
|
||||
|
||||
# 请求分类页
|
||||
try:
|
||||
response = self.fetch(full_url)
|
||||
if response and response.status_code == 200:
|
||||
html = response.text
|
||||
soup = BeautifulSoup(html, 'html.parser')
|
||||
|
||||
# 查找视频项,根据实际HTML结构调整
|
||||
items = soup.find_all('li', class_='item')
|
||||
|
||||
for item in items:
|
||||
try:
|
||||
# 获取链接和标题
|
||||
title_tag = item.find('h3')
|
||||
if not title_tag:
|
||||
continue
|
||||
|
||||
title = title_tag.text.strip()
|
||||
|
||||
# 获取链接
|
||||
link_tag = item.find('a')
|
||||
if not link_tag:
|
||||
continue
|
||||
|
||||
link = link_tag.get('href', '')
|
||||
if not link.startswith('http'):
|
||||
link = urllib.parse.urljoin(self.siteUrl, link)
|
||||
|
||||
# 提取ID
|
||||
vid = self.extractVodId(link)
|
||||
if not vid:
|
||||
continue
|
||||
|
||||
# 获取图片
|
||||
img_tag = item.find('img')
|
||||
img_url = ""
|
||||
if img_tag:
|
||||
img_url = img_tag.get('src', img_tag.get('data-src', ''))
|
||||
if img_url and not img_url.startswith('http'):
|
||||
img_url = urllib.parse.urljoin(self.siteUrl, img_url)
|
||||
|
||||
# 获取备注信息
|
||||
remarks = ""
|
||||
remarks_tag = item.find('span', class_='remarks')
|
||||
if remarks_tag:
|
||||
remarks = remarks_tag.text.strip()
|
||||
|
||||
# 获取标签信息
|
||||
tags = ""
|
||||
tags_tag = item.find('span', class_='tags')
|
||||
if tags_tag:
|
||||
tags = tags_tag.text.strip()
|
||||
|
||||
# 合并备注和标签
|
||||
if remarks and tags:
|
||||
remarks = f"{remarks} | {tags}"
|
||||
elif tags:
|
||||
remarks = tags
|
||||
|
||||
# 构建视频项
|
||||
videos.append({
|
||||
'vod_id': vid,
|
||||
'vod_name': title,
|
||||
'vod_pic': img_url,
|
||||
'vod_remarks': remarks
|
||||
})
|
||||
except Exception as e:
|
||||
self.log(f"处理分类视频项时出错: {str(e)}", "ERROR")
|
||||
continue
|
||||
|
||||
# 查找分页信息
|
||||
# 默认值
|
||||
total = len(videos)
|
||||
pagecount = 1
|
||||
limit = 20
|
||||
|
||||
# 尝试查找分页元素
|
||||
pagination = soup.find('ul', class_='page')
|
||||
if pagination:
|
||||
# 查找最后一页的链接
|
||||
last_page_links = pagination.find_all('a')
|
||||
for link in last_page_links:
|
||||
page_text = link.text.strip()
|
||||
if page_text.isdigit():
|
||||
pagecount = max(pagecount, int(page_text))
|
||||
except Exception as e:
|
||||
self.log(f"获取分类内容发生错误: {str(e)}", "ERROR")
|
||||
|
||||
result['list'] = videos
|
||||
result['page'] = pg
|
||||
result['pagecount'] = pagecount
|
||||
result['limit'] = limit
|
||||
result['total'] = total
|
||||
|
||||
return result
|
||||
|
||||
def detailContent(self, ids):
|
||||
"""获取详情内容"""
|
||||
result = {}
|
||||
|
||||
if not ids or len(ids) == 0:
|
||||
return result
|
||||
|
||||
# 视频ID
|
||||
vid = ids[0]
|
||||
|
||||
# 构建播放页URL
|
||||
play_url = f"{self.siteUrl}/index.php/vod/play/id/{vid}/sid/1/nid/1.html"
|
||||
|
||||
try:
|
||||
response = self.fetch(play_url)
|
||||
if not response or response.status_code != 200:
|
||||
return result
|
||||
|
||||
html = response.text
|
||||
soup = BeautifulSoup(html, 'html.parser')
|
||||
|
||||
# 提取视频基本信息
|
||||
# 标题
|
||||
title = ""
|
||||
title_tag = soup.find('h1', class_='items-title')
|
||||
if title_tag:
|
||||
title = title_tag.text.strip()
|
||||
|
||||
# 图片
|
||||
pic = ""
|
||||
pic_tag = soup.find('img', class_='thumb')
|
||||
if pic_tag:
|
||||
pic = pic_tag.get('src', '')
|
||||
if pic and not pic.startswith('http'):
|
||||
pic = urllib.parse.urljoin(self.siteUrl, pic)
|
||||
|
||||
# 简介
|
||||
desc = ""
|
||||
desc_tag = soup.find('div', class_='text-content')
|
||||
if desc_tag:
|
||||
desc = desc_tag.text.strip()
|
||||
|
||||
# 标签/分类
|
||||
tags = []
|
||||
tags_container = soup.find('span', class_='items-tags')
|
||||
if tags_container:
|
||||
tag_links = tags_container.find_all('a')
|
||||
for tag in tag_links:
|
||||
tag_text = tag.text.strip()
|
||||
if tag_text:
|
||||
tags.append(tag_text)
|
||||
|
||||
# 提取播放列表
|
||||
play_from = "偷乐短剧"
|
||||
play_list = []
|
||||
|
||||
# 查找播放列表区域
|
||||
play_area = soup.find('div', class_='swiper-wrapper')
|
||||
if play_area:
|
||||
# 查找所有剧集链接
|
||||
episode_links = play_area.find_all('a')
|
||||
for ep in episode_links:
|
||||
ep_title = ep.text.strip()
|
||||
ep_url = ep.get('href', '')
|
||||
|
||||
if ep_url:
|
||||
# 直接使用URL作为ID
|
||||
if not ep_url.startswith('http'):
|
||||
ep_url = urllib.parse.urljoin(self.siteUrl, ep_url)
|
||||
|
||||
# 提取集数信息
|
||||
ep_num = ep_title
|
||||
if ep_num.isdigit():
|
||||
ep_num = f"第{ep_num}集"
|
||||
|
||||
play_list.append(f"{ep_num}${ep_url}")
|
||||
|
||||
# 如果没有找到播放列表,查找播放按钮
|
||||
if not play_list:
|
||||
play_btn = soup.find('a', class_='btn-play')
|
||||
if play_btn:
|
||||
play_url = play_btn.get('href', '')
|
||||
if play_url:
|
||||
if not play_url.startswith('http'):
|
||||
play_url = urllib.parse.urljoin(self.siteUrl, play_url)
|
||||
|
||||
play_list.append(f"播放${play_url}")
|
||||
|
||||
# 如果仍然没有找到播放链接,使用播放页URL
|
||||
if not play_list:
|
||||
play_url = f"{self.siteUrl}/index.php/vod/play/id/{vid}/sid/1/nid/1.html"
|
||||
play_list.append(f"播放${play_url}")
|
||||
|
||||
# 提取更多信息(导演、演员等)
|
||||
director = ""
|
||||
actor = ""
|
||||
year = ""
|
||||
area = ""
|
||||
remarks = ""
|
||||
|
||||
# 查找备注信息
|
||||
meta_items = soup.find_all('div', class_='meta-item')
|
||||
for item in meta_items:
|
||||
item_title = item.find('span', class_='item-title')
|
||||
item_content = item.find('span', class_='item-content')
|
||||
|
||||
if item_title and item_content:
|
||||
title_text = item_title.text.strip()
|
||||
content_text = item_content.text.strip()
|
||||
|
||||
if "导演" in title_text:
|
||||
director = content_text
|
||||
elif "主演" in title_text:
|
||||
actor = content_text
|
||||
elif "年份" in title_text:
|
||||
year = content_text
|
||||
elif "地区" in title_text:
|
||||
area = content_text
|
||||
elif "简介" in title_text:
|
||||
if not desc:
|
||||
desc = content_text
|
||||
elif "状态" in title_text:
|
||||
remarks = content_text
|
||||
|
||||
# 如果没有从meta-item中获取到remarks
|
||||
if not remarks:
|
||||
remarks_tag = soup.find('span', class_='remarks')
|
||||
if remarks_tag:
|
||||
remarks = remarks_tag.text.strip()
|
||||
|
||||
# 构建标准数据结构
|
||||
vod = {
|
||||
"vod_id": vid,
|
||||
"vod_name": title,
|
||||
"vod_pic": pic,
|
||||
"vod_year": year,
|
||||
"vod_area": area,
|
||||
"vod_remarks": remarks,
|
||||
"vod_actor": actor,
|
||||
"vod_director": director,
|
||||
"vod_content": desc,
|
||||
"type_name": ",".join(tags),
|
||||
"vod_play_from": play_from,
|
||||
"vod_play_url": "#".join(play_list)
|
||||
}
|
||||
|
||||
result = {
|
||||
'list': [vod]
|
||||
}
|
||||
except Exception as e:
|
||||
self.log(f"获取详情内容时出错: {str(e)}", "ERROR")
|
||||
|
||||
return result
|
||||
|
||||
def searchContent(self, key, quick, pg=1):
|
||||
"""搜索功能"""
|
||||
result = {}
|
||||
videos = []
|
||||
|
||||
# 构建搜索URL和参数
|
||||
search_url = f"{self.siteUrl}/index.php/vod/search.html"
|
||||
params = {"wd": key}
|
||||
|
||||
try:
|
||||
response = self.fetch(search_url, data=params)
|
||||
if response and response.status_code == 200:
|
||||
html = response.text
|
||||
soup = BeautifulSoup(html, 'html.parser')
|
||||
|
||||
# 查找搜索结果项
|
||||
search_items = soup.find_all('li', class_='item')
|
||||
|
||||
for item in search_items:
|
||||
try:
|
||||
# 获取标题
|
||||
title_tag = item.find('h3')
|
||||
if not title_tag:
|
||||
continue
|
||||
|
||||
title = title_tag.text.strip()
|
||||
|
||||
# 获取链接
|
||||
link_tag = item.find('a')
|
||||
if not link_tag:
|
||||
continue
|
||||
|
||||
link = link_tag.get('href', '')
|
||||
if not link.startswith('http'):
|
||||
link = urllib.parse.urljoin(self.siteUrl, link)
|
||||
|
||||
# 提取视频ID
|
||||
vid = self.extractVodId(link)
|
||||
if not vid:
|
||||
continue
|
||||
|
||||
# 获取图片
|
||||
img_tag = item.find('img')
|
||||
img_url = ""
|
||||
if img_tag:
|
||||
img_url = img_tag.get('src', img_tag.get('data-src', ''))
|
||||
if img_url and not img_url.startswith('http'):
|
||||
img_url = urllib.parse.urljoin(self.siteUrl, img_url)
|
||||
|
||||
# 获取备注信息
|
||||
remarks = ""
|
||||
remarks_tag = item.find('span', class_='remarks')
|
||||
if remarks_tag:
|
||||
remarks = remarks_tag.text.strip()
|
||||
|
||||
# 获取标签信息
|
||||
tags = ""
|
||||
tags_tag = item.find('span', class_='tags')
|
||||
if tags_tag:
|
||||
tags = tags_tag.text.strip()
|
||||
|
||||
# 合并备注和标签
|
||||
if remarks and tags:
|
||||
remarks = f"{remarks} | {tags}"
|
||||
elif tags:
|
||||
remarks = tags
|
||||
|
||||
# 构建视频项
|
||||
videos.append({
|
||||
'vod_id': vid,
|
||||
'vod_name': title,
|
||||
'vod_pic': img_url,
|
||||
'vod_remarks': remarks
|
||||
})
|
||||
except Exception as e:
|
||||
self.log(f"处理搜索结果时出错: {str(e)}", "ERROR")
|
||||
continue
|
||||
except Exception as e:
|
||||
self.log(f"搜索功能发生错误: {str(e)}", "ERROR")
|
||||
|
||||
result['list'] = videos
|
||||
return result
|
||||
|
||||
def searchContentPage(self, key, quick, pg=1):
|
||||
return self.searchContent(key, quick, pg)
|
||||
|
||||
def playerContent(self, flag, id, vipFlags):
|
||||
"""获取播放内容"""
|
||||
result = {}
|
||||
|
||||
try:
|
||||
# 判断是否已经是视频URL
|
||||
if self.isVideoFormat(id):
|
||||
result["parse"] = 0
|
||||
result["url"] = id
|
||||
result["playUrl"] = ""
|
||||
result["header"] = json.dumps(self.headers)
|
||||
return result
|
||||
|
||||
# 判断是否是完整的页面URL
|
||||
if id.startswith(('http://', 'https://')):
|
||||
play_url = id
|
||||
# 尝试作为相对路径处理
|
||||
elif id.startswith('/'):
|
||||
play_url = urllib.parse.urljoin(self.siteUrl, id)
|
||||
# 假设是视频ID,构建播放页面URL
|
||||
else:
|
||||
# 检查是否是"视频ID_集数"格式
|
||||
parts = id.split('_')
|
||||
if len(parts) > 1 and parts[0].isdigit():
|
||||
vid = parts[0]
|
||||
nid = parts[1]
|
||||
play_url = f"{self.siteUrl}/index.php/vod/play/id/{vid}/sid/1/nid/{nid}.html"
|
||||
else:
|
||||
# 直接当作视频ID处理
|
||||
play_url = f"{self.siteUrl}/index.php/vod/play/id/{id}/sid/1/nid/1.html"
|
||||
|
||||
# 访问播放页获取真实播放地址
|
||||
try:
|
||||
self.log(f"正在解析播放页面: {play_url}")
|
||||
response = self.fetch(play_url)
|
||||
if response and response.status_code == 200:
|
||||
html = response.text
|
||||
|
||||
# 查找player_aaaa变量
|
||||
player_match = re.search(r'var\s+player_aaaa\s*=\s*({.*?});', html, re.DOTALL)
|
||||
if player_match:
|
||||
try:
|
||||
player_data = json.loads(player_match.group(1))
|
||||
if 'url' in player_data:
|
||||
video_url = player_data['url']
|
||||
if not video_url.startswith('http'):
|
||||
video_url = urllib.parse.urljoin(self.siteUrl, video_url)
|
||||
|
||||
self.log(f"从player_aaaa获取到视频地址: {video_url}")
|
||||
result["parse"] = 0
|
||||
result["url"] = video_url
|
||||
result["playUrl"] = ""
|
||||
result["header"] = json.dumps(self.headers)
|
||||
return result
|
||||
except json.JSONDecodeError as e:
|
||||
self.log(f"解析player_aaaa JSON出错: {str(e)}", "ERROR")
|
||||
|
||||
# 如果player_aaaa解析失败,尝试其他方式
|
||||
# 1. 查找video标签
|
||||
video_match = re.search(r'<video[^>]*src=["\'](.*?)["\']', html)
|
||||
if video_match:
|
||||
video_url = video_match.group(1)
|
||||
if not video_url.startswith('http'):
|
||||
video_url = urllib.parse.urljoin(self.siteUrl, video_url)
|
||||
|
||||
self.log(f"从video标签找到视频地址: {video_url}")
|
||||
result["parse"] = 0
|
||||
result["url"] = video_url
|
||||
result["playUrl"] = ""
|
||||
result["header"] = json.dumps(self.headers)
|
||||
return result
|
||||
|
||||
# 2. 查找iframe
|
||||
iframe_match = re.search(r'<iframe[^>]*src=["\'](.*?)["\']', html)
|
||||
if iframe_match:
|
||||
iframe_url = iframe_match.group(1)
|
||||
if not iframe_url.startswith('http'):
|
||||
iframe_url = urllib.parse.urljoin(self.siteUrl, iframe_url)
|
||||
|
||||
self.log(f"找到iframe,正在解析: {iframe_url}")
|
||||
# 访问iframe内容
|
||||
iframe_response = self.fetch(iframe_url)
|
||||
if iframe_response and iframe_response.status_code == 200:
|
||||
iframe_html = iframe_response.text
|
||||
|
||||
# 在iframe内容中查找视频地址
|
||||
iframe_video_match = re.search(r'(https?://[^\'"]+\.(mp4|m3u8|ts))', iframe_html)
|
||||
if iframe_video_match:
|
||||
video_url = iframe_video_match.group(1)
|
||||
|
||||
self.log(f"从iframe中找到视频地址: {video_url}")
|
||||
result["parse"] = 0
|
||||
result["url"] = video_url
|
||||
result["playUrl"] = ""
|
||||
result["header"] = json.dumps({
|
||||
"User-Agent": self.headers["User-Agent"],
|
||||
"Referer": iframe_url
|
||||
})
|
||||
return result
|
||||
|
||||
# 3. 查找任何可能的视频URL
|
||||
url_match = re.search(r'(https?://[^\'"]+\.(mp4|m3u8|ts))', html)
|
||||
if url_match:
|
||||
video_url = url_match.group(1)
|
||||
|
||||
self.log(f"找到可能的视频地址: {video_url}")
|
||||
result["parse"] = 0
|
||||
result["url"] = video_url
|
||||
result["playUrl"] = ""
|
||||
result["header"] = json.dumps(self.headers)
|
||||
return result
|
||||
except Exception as e:
|
||||
self.log(f"解析播放地址时出错: {str(e)}", "ERROR")
|
||||
|
||||
# 如果所有方式都失败,返回外部解析标志
|
||||
self.log("未找到直接可用的视频地址,需要外部解析", "WARNING")
|
||||
result["parse"] = 1 # 表示需要外部解析
|
||||
result["url"] = play_url # 返回播放页面URL
|
||||
result["playUrl"] = ""
|
||||
result["header"] = json.dumps(self.headers)
|
||||
|
||||
except Exception as e:
|
||||
self.log(f"获取播放内容时出错: {str(e)}", "ERROR")
|
||||
|
||||
return result
|
||||
|
||||
def localProxy(self, param):
|
||||
"""本地代理"""
|
||||
return [404, "text/plain", {}, "Not Found"]
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"请求头": "手机",
|
||||
"编码": "UTF-8",
|
||||
"简介": "简 介:&&</p>",
|
||||
"线路数组": "javascript:;\">&&</a>",
|
||||
"数组": "<li>&&</li>",
|
||||
"图片": "data-echo=\"&&\"",
|
||||
"分类url": "https://vip.wwgz.cn:5200/vod-list-id-{cateId}-pg-{catePg}-order--by-time-class-0-year-{year}-letter--area-{area}-lang-.html",
|
||||
"分类": "电影$1#电视剧$2#动漫$4#综艺$3#短剧$26"
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
H4sIAEIfMGcC/31Xe2/b1hX/e/kUmjroEVmiRIp62PAKPSxLlkTJsh60isKhyEuREl8iLymRroF0j6zp0i7pMqDduq0buiZA0aYBUjRI0va7DJXkfItdUoojp8EoQb73nN8597x8zyGG+eZ/ujN//Nvn//rWJ0CoGdsYNp1OY4rMWVyMVWXsisXoPt2UgG/Xd3rFhx4oQgls+4LzG58uvrkz//7h+b0bb/307OO3g1srPjM40YHCyAh0Gnz+9OPzrz8PIvzyyY/n3z34753Pglu+4OKjrxZ3f/g5+ekj9L1MPtvyYZigGnA7+IqJnGfi+lgP4Qu+3osNzIGx7bum6aICQ+XGUTu8IwGIfJelXR1MTGCsyFunAmA4oBvbp/6OAfRobggU6N+uN/KV2t5JJ3d2Ft658gtX1tBZFJuRocU0jhdCrqot/0Dl7ECA2QaTUCIcCAg64P3hd975/6g2mEG/q1bkQ79EamMGZHRo9EQohDzHguHwKaLvXngZjKDt2c7KHf/i/T/P3/vmp8dPUTq3/S4rvOM6s4tW11YRMHUJBQmzVC4qiQaMilyUt3lRgkCPuTYF3WD7LvHxqDaMJqKqjsIRjQ7sKBRlEGUlxjCi8agNGD2Kx3EiimIBXQSjAyYalRhlGPVUeueujmAGbuUktjBs8fGD+e0v5rcfLO/en793Y/nw6fKrvz2/fnNrA32yMvb0lJdiLANBhTs7c23hbY0Zgg2DPMTA9qm6z+8a50e4S/Z5AHeFGGszPdJqjYiezR7JXbko1/zgpjXIknLSqORePBG8T8ST7cOWXSLwnmX2R304otqEkVfqpVlnUDho1Q/34pXj1l7tcAgL8mRcOnIiYp/piaVKoTKoVPi+Ykp6qtRLq2kyVTiog1K1rvBZhWtwSi+rGlKk1+hkU6rDK1bNKvV6WGffxuqlfYzNjpmMzdayxyOHyI6xQta2ZlhVmKbx8iypmm22NTWhNZESYqGRjyjUyG7NNK6T1Xm+ehSX24eJBhQiHXlf7g0I6yDSLWl7anYvTifp8gEu1gdMRamlmuVuu0USVZ61akdMqSaokV6cqJYaJb4DpCOrFR/bmlHDpwbNTfZGTZagRLFMJnrHVaE/7cn72XI72cQUkuk1pZqRxma1PbldAUQKn1mtURofH037aaKrphsjsqbPjEbWGDW6BkVocZkulgdU0bHUsbEHDqvxVoIG7ZogGVy2uM+x0tDE1bRentahk5Jgn4A0zeFqitgHTLNdbA/agKDGk24qPsVzaa2lNhgaRAw1wx3kKBxmUulehDWJ8SQeV+UmJRE9RxlIrQkgspMETYyHNCSaqVGPVFSaY8SUrpWnDcdiLbHDi1mJIsVGM9/s1/rHcrXK282SkI20nSZG7vGNkjI2HbES6URYLeuI3Zld03I1W6YBOao1zU7JbFB8hQJs1QSVjOA4ZdDqk5LSnB6ZTDd5QNermT1d7oJC16lauWp2SA9LYDqYFqzKAZlHm8xUnxbM424y72JzulwCua5TuMDmuqm+kwKZ0iyjUZkhRc4mJClNhS7pKOMGm3TsWpPVyLxiltlWhHRqWqnmDLs2OaKHFDvTp/vmcSJZdJXndRzpS6SLVo7JCMqYAjnC2UebTWw3SdH1VGZfx/ug2E1TVn6SkZVxAhRph0EbEtLDBGvrU8bsb2Lz3XTJyk0yojLugjztejshJXrYdbFVV2+JrjOZgo4fXGAzHS7CUzYzY+ujnhLn8jLEmkVbxKV9jNOGRr1Yb/HZTsQ6rgwZPXsgj4x2PUslM2YcCnVT4zt2s0kOJ0UzmaLMGtlNt/LxOtNMyunDUSVutDr1biTj5OhcmmGOe44YSYwqBZAsGCyXbh+X22p9QiacutkXnDrgRMfosaIzplmbxJ3u1Di003K6PuiPBujH4RsDzeEaNTjjrCaGxwlclCMMW9QErUVnsT3VEoyZVeIJrGZiYL8t66w0kPS61pcG9Uk/QTcmk1S/yytVq92ygdmMz0yZQj8KFScthSLZShrvY9Mu1aYOBV1Mostpd/fS3XXCAX573b7dJ4E2qxsV3WoJt8PimxTcpRCbFMKlJDcpSU8qdUksFTzzjjhbnW2gC5cVOquOIyocmMWQz2/Ku253WTEDU2736tXgJn7VI/BXe8Tv788fXl/c/nT56N/rXr7uz75TDFt+f2f55SfLv/7u/MF3i4e/mX/+aGv+9a3FXx4t7j5Y3Hp3cfP64tObiL01f/x4/vgLk5l/dItV1bEIjIuYBF+2eXf+uGj0a+O8KcTndZUTjdENdwJ6A6qawlg+SdyWYCgZ3mFWPdz963b8ndhVLBS7+mZ43Vo9RSsVq/EouLz7LRqgAuc//mP59Kv5zXuB5dNn5zefBObv3188+zKw/KdLDKJYPP/7J4vr76465fz2B8t73yz++Gzx4X82VK66ZSKAB4hAMoCS8YrY4rM/nD+4sSGmSYz9wheom2Bln8Q49rbvVyMjBtUjiAaLYSgU9u3+eqN83KlHVER4MjLQ5HOtMRgBFsZQjYkKaOqqBnSIIhtCoRGHDFT1Ld8pOgvyqi6jdA0BmtNWKoNiU1AVEHSHqWs7F/pFRTPhxbz54llbmti6RPW89gQu00fumAd1+1RSUYGKqhJzM4KUcipryijJMTTs6fYRkJDtqp6TpJBf5HWUFn/4rcTbMTQy7ZwhSVYIAV0P+07PXi8Y8sck5LY/HGMlkR2Hwte2fm71CSoKnUHZCXhhM1hd1OBu0BfxAYVVOdBpVQqqrKFQoDFuwBggldzzGKF1mMPhl1rX/2NriiTKIopnarVbfHj//IPb6KDYUFIHjNQU2Roa49wKFRgjJMpDr0i9EX7nqvtZV+VPj68vn9x7neBOzGiLcF3YSEEg4IYmZuRVCFU5GgXy5aJ/ofDJLU/hyxz6vVP92z5/zFutxWLQ1kB0g+J/6aofnecJeAOfwAUCLwzYBHHAYD2UuzgRIZDdgZoIvzjgEjkZjkYNjVHWzFe4icvcy0z8EnPTAlZVoPd64BkBGVGKIpJP+zkSvRwZHkzgNsnurL2iK6bsBt497w2RC6ME+Dfv1NUN6ObJdHPUnkFUd+je5MWZm6urqwxxDGSiqzQVgbH5euEl/Ox/p5fXDfgNAAA=
|
||||
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"作者": "🐰兔爷🐇",
|
||||
"站名": "厂长资源",
|
||||
"编码": "UTF-8",
|
||||
"发布地址": "https://www.cz01.vip/",
|
||||
"请求头": "User-Agent$MOBILE_UA",
|
||||
"主页url": "https://www.czzymovie.com",
|
||||
"首页": "200",
|
||||
"起始页": "1",
|
||||
"分类url": "/{cateId}/page/{catePg};;rcRA",
|
||||
"分类": "豆瓣电影Top250$dbtop250#最新电影$zuixindianying#剧场版$dongmanjuchangban#电影$movie_bt/movie_bt_series/dyy#电视剧$movie_bt/movie_bt_series/dianshiju#俄罗斯电影$movie_bt/movie_bt_series/eluosidianying#加拿大电影$movie_bt/movie_bt_series/jianadadianying#动画$movie_bt/movie_bt_series/dohua#华语电影$movie_bt/movie_bt_series/huayudianying#印度电影$movie_bt/movie_bt_series/yindudianying#国产剧$movie_bt/movie_bt_series/guochanju#日剧$movie_bt/movie_bt_series/rj#日本电影$movie_bt/movie_bt_series/ribendianying#欧美电影$movie_bt/movie_bt_series/meiguodianying#海外剧(其他)$movie_bt/movie_bt_series/hwj#美剧$movie_bt/movie_bt_series/mj#韩剧$movie_bt/movie_bt_series/hj#韩国电影$movie_bt/movie_bt_series/hanguodianying#番剧$fanju",
|
||||
"数组": "<li><a&&</a></h",
|
||||
"图片": "data-original=\"&&\"",
|
||||
"标题": "alt=\"&&\"",
|
||||
"副标题": "jidi\"><span>&&<+-+furk\">&&<",
|
||||
"链接": "href=\"&&\"",
|
||||
"影片年代": "年份:&&</li",
|
||||
"影片地区": "地区:&&</li",
|
||||
"影片类型": "类型:&&</li",
|
||||
"状态": "上映:&&</li",
|
||||
"导演": "导演:&&</li",
|
||||
"主演": "主演:&&</li",
|
||||
"简介": "👶+yp_context\">&&</div",
|
||||
"线路数组": "<div class=\"ypxingq&&</div",
|
||||
"线路标题": "厂长专线",
|
||||
"播放数组": "<div class=\"paly_list_btn&&</div",
|
||||
"播放列表": "<a&&/a>",
|
||||
"播放标题": ">&&<",
|
||||
"播放链接": "href=\"&&\"",
|
||||
"搜索url": "/daoyongjiek0shibushiyoubing?q={wd}&f=_all&p={pg}",
|
||||
"搜索模式": "1",
|
||||
"筛选": "1"
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"分类": "短剧$1#电视剧$2",
|
||||
"分类url": "https://www.jjduanju.com/sort/{cateId}/page/{catePg}.html"
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"请求头": "User-Agent$MOBILE_UA",
|
||||
"编码": "UTF-8",
|
||||
"主页url": "https://dora.xiaoxinbk.com/",
|
||||
"数组": "class=\"card-img-bili\"&&</a>",
|
||||
"标题": "alt=\"&&\"",
|
||||
"图片": "data-url=\"&&\"",
|
||||
"链接": "href=\"&&\"",
|
||||
"线路标题": "mt-0\">&&</h3>",
|
||||
"播放数组": "class=\"card-body button-list\"&&</div>",
|
||||
"播放列表": "<a&&a>",
|
||||
"播放链接": "href=\"&&\"",
|
||||
"播放标题": ">&&</",
|
||||
"分类url": "https://www.dora-video.cn/search/sy/?niandai={year}&cat={class}&tag={cateId}&gaojijiansuo=1&zhuangtai={by}",
|
||||
"分类": "全部$0#动画$20#剧场版$21#MV$22#预告片$23#直播$27#同人$25#民间$26#目录$28#中篇$30",
|
||||
"剧情": "哆啦A梦新番$1#新哆啦A梦 台湾配音$2#哆啦A梦剧场版$3#最新预告片$6#剧场版集合$7#哆啦A梦MV$4#哆啦A梦七小子集合$11#生日特别篇$19#哆啦A梦生日特别篇$12#哆啦美生日特别篇$14#大雄生日特别篇$13#静香生日特别篇$15#胖虎生日特别篇$16#小夫生日特别篇$17#24小时直播$24#哆啦A梦中篇附映$29#哆啦A梦大山版 - 哆啦a梦1979版国语旧版 - 旧版$31#哆啦A梦大山修复&补档区$32#藤子·F·不二雄【其它动画】$33",
|
||||
"排序": "全部$0#完结$2#连载$1#待定$-1"
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
{
|
||||
"class": [
|
||||
{
|
||||
"type_name": "有声小说",
|
||||
"type_id": "有声小说"
|
||||
},
|
||||
{
|
||||
"type_name": "玄幻有声小说",
|
||||
"type_id": "玄幻有声小说"
|
||||
},
|
||||
{
|
||||
"type_name": "奇幻有声小说",
|
||||
"type_id": "奇幻有声小说"
|
||||
},
|
||||
{
|
||||
"type_name": "都市有声小说",
|
||||
"type_id": "都市有声小说"
|
||||
},
|
||||
{
|
||||
"type_name": "言情有声小说",
|
||||
"type_id": "言情有声小说"
|
||||
},
|
||||
{
|
||||
"type_name": "武侠有声小说",
|
||||
"type_id": "武侠有声小说"
|
||||
},
|
||||
{
|
||||
"type_name": "仙侠有声小说",
|
||||
"type_id": "仙侠有声小说"
|
||||
},
|
||||
{
|
||||
"type_name": "科幻有声小说",
|
||||
"type_id": "科幻有声小说"
|
||||
},
|
||||
{
|
||||
"type_name": "重生有声小说",
|
||||
"type_id": "重生有声小说"
|
||||
},
|
||||
{
|
||||
"type_name": "穿越有声小说",
|
||||
"type_id": "穿越有声小说"
|
||||
},
|
||||
{
|
||||
"type_name": "恐怖惊悚有声小说",
|
||||
"type_id": "恐怖惊悚有声小说"
|
||||
},
|
||||
{
|
||||
"type_name": "网游竞技有声小说",
|
||||
"type_id": "网游竞技有声小说"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
@header({
|
||||
searchable: 2,
|
||||
filterable: 1,
|
||||
quickSearch: 0,
|
||||
title: '天天影视',
|
||||
'类型': '影视',
|
||||
lang: 'ds'
|
||||
})
|
||||
*/
|
||||
|
||||
var rule = {
|
||||
类型: '影视',
|
||||
title: '天天影视',
|
||||
host: 'https://m.rvm2.com',
|
||||
url: '/ttgd/fyclass--------fypage---.html',
|
||||
searchUrl: '/ttsearch/**----------fypage---.html',
|
||||
searchable: 2,
|
||||
quickSearch: 0,
|
||||
filterable: 1,
|
||||
filter: '',
|
||||
filter_url: '',
|
||||
filter_def: {},
|
||||
headers: {
|
||||
'User-Agent': 'MOBILE_UA',
|
||||
},
|
||||
timeout: 5000,
|
||||
class_parse: '.hom_mob_list li;a&&Text;a&&href;.*/(.*?).html',
|
||||
cate_exclude: '',
|
||||
play_parse: true,
|
||||
lazy: "js:input = {parse: 1, url: input, js: ''}",
|
||||
double: true,
|
||||
推荐: '.vod_row .pannel;.vodlist_wi li;a&&title;a&&data-original;.pic_text&&Text;a&&href',
|
||||
一级: '.vodlist_wi li;a&&title;a&&data-original;.pic_text&&Text;a&&href;.vodlist_sub&&Text',
|
||||
二级: {
|
||||
title: 'h2&&Text',
|
||||
img: '.lazyload&&data-original',
|
||||
desc: '.pic_text&&Text;.content_min li&&target&&Text;.hidden_xs&&Text',
|
||||
content: '.content_desc',
|
||||
tabs: '.play_source_tab a',
|
||||
lists: '.content_playlist:eq(#id)&&a',
|
||||
tab_text: 'body&&Text',
|
||||
list_text: 'body&&Text',
|
||||
list_url: 'a&&href',
|
||||
list_url_prefix: '',
|
||||
},
|
||||
搜索: '.vodlist li;h4&&Text;.lazyload&&data-original;.pic_text&&Text;a&&href;.content_desc',
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
{
|
||||
|
||||
"作者":"荷城茶秀",
|
||||
|
||||
"站点":"奇优影院",
|
||||
|
||||
"主页url":"http://www.qiyoudy1.com/",
|
||||
|
||||
"简介":"简介:&&</div>",
|
||||
|
||||
"主演":"主演:&&</p>",
|
||||
|
||||
"导演":"导演:&&</p>",
|
||||
|
||||
"影片类型":"类型:&&立即播放",
|
||||
|
||||
"影片状态":"更新:&&</p>",
|
||||
|
||||
"数组":"<div class=\"stui-vodlist__box\">&&</a>",
|
||||
|
||||
"图片":"data-original=\"&&\"",
|
||||
|
||||
"标题":"title=\"&&\"",
|
||||
|
||||
"副标题":"text-right\">&&</span>",
|
||||
|
||||
"链接":"href=\"&&\"",
|
||||
|
||||
"搜索url":"/search.php;post;searchword={wd}",
|
||||
|
||||
"搜索数组":"v-thumb stui-vodlist__thumb&&</a>",
|
||||
|
||||
"搜索图片":"data-original=\"&&\"",
|
||||
|
||||
"搜索标题":"title=\"&&\"",
|
||||
|
||||
"搜索副标题":"text-right\">&&</span>",
|
||||
|
||||
"搜索链接":"href=\"&&\"",
|
||||
|
||||
"线路数组":"data-toggle=\"tab\"&&</li>[替换:播放源1>>线路①#播放源2>>线路②#播放源3>>线路③#播放源4>>线路④#播放源5>>线路⑤#播放源6>>线路⑥]",
|
||||
|
||||
"线路标题":">&&</a>",
|
||||
|
||||
"播放数组":"stui-content__playlist clearfix&&</ul>",
|
||||
|
||||
"播放列表":"<li>&&</li>",
|
||||
|
||||
"播放标题":">&&</a>",
|
||||
|
||||
"分类url":"http://www.qiyoudy1.com/list/{cateId}_{catePg}.html[http://www.qiyoudy1.com/list/{cateId}.html];;ak",
|
||||
|
||||
"分类":"电影$1#电视剧$2#动漫$3#综艺$4",
|
||||
|
||||
"筛选":{
|
||||
"1":[
|
||||
{"key":"by","name":"排序","value":[
|
||||
{"n":"时间排序","v":"time"},
|
||||
{"n":"人气排序","v":"score"},
|
||||
{"n":"评分排序","v":"hits"}
|
||||
]
|
||||
}
|
||||
],
|
||||
"2":[
|
||||
{"key":"by","name":"排序","value":[
|
||||
{"n":"时间排序","v":"time"},
|
||||
{"n":"人气排序","v":"score"},
|
||||
{"n":"评分排序","v":"hits"}
|
||||
]
|
||||
}
|
||||
],
|
||||
"3":[
|
||||
{"key":"by","name":"排序","value":[
|
||||
{"n":"时间排序","v":"time"},
|
||||
{"n":"人气排序","v":"score"},
|
||||
{"n":"评分排序","v":"hits"}
|
||||
]
|
||||
}
|
||||
],
|
||||
"4":[
|
||||
{"key":"by","name":"排序","value":[
|
||||
{"n":"时间排序","v":"time"},
|
||||
{"n":"人气排序","v":"score"},
|
||||
{"n":"评分排序","v":"hits"}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
var rule = {
|
||||
title:'有声小说吧',
|
||||
编码:'gb18030',
|
||||
host:'http://m.ysxs8.vip',
|
||||
url:'/downlist/fyclass_fypage.html',
|
||||
searchUrl:'/search.asp?page=fypage&searchword=**&searchtype=-1',
|
||||
searchable:2,
|
||||
quickSearch:0,
|
||||
headers:{
|
||||
'User-Agent':'MOBILE_UA'
|
||||
},
|
||||
timeout:5000,
|
||||
// homeUrl:'/fenlei/',
|
||||
// class_parse: '.pd-class:eq(0) dd;a&&Text;a&&href;.*/(.*?).html',
|
||||
class_name:'网络玄幻&恐怖悬疑&传统武侠&都市言情&官场刑侦&历史军事&探险盗墓&职场商战&明朝那些事儿&评书下载&相声戏曲&人物传记&广播剧&百家讲坛&外语读物&有声文学&儿童读物&管理营销',
|
||||
class_url:'r52&r17&r12&r13&r14&r15&r45&r81&r36&r3&r7&r16&r18&r32&r35&r41&r4&r6',
|
||||
play_parse:true,
|
||||
lazy:'',
|
||||
limit:6,
|
||||
// double:true,
|
||||
推荐:'.list-ul .list-li;.list-name&&Text;*;.module-slide-author&&Text;*',
|
||||
一级:'.book-ol&&li;h4&&Text;img&&data-original;.book-meta&&Text;a&&href',
|
||||
二级:{
|
||||
// title:'h2&&Text;.book-cell .book-rand-a:eq(2)&&Text',
|
||||
title:'h1&&Text;.book-cell .book-rand-a:eq(0)&&a&&Text',
|
||||
img:'.book img&&src',
|
||||
// desc:';;;;.book-des p&&Text',
|
||||
desc:';;;.book-rand-a:eq(2)&&Text;.book-des p&&Text',
|
||||
content:'.book-des--p&&Text',
|
||||
tabs:'.playlist-top&&h2',
|
||||
// lists:'js:pd=jsp.pd;let url=pd(html,".bookbutton&&a&&href");log(url);html=request(url);let v=pd(html,".booksite&&script&&Html");var document={};var VideoListJson;VideoListJson=eval(v.split("VideoListJson=")[1].split(",urlinfo")[0]);log(typeof VideoListJson);let list1=VideoListJson[0][1];LISTS=[list1];log(LISTS);',
|
||||
// 有声小说有防盗链,我服了(上面的列表数据正常拿到了,没法播放)
|
||||
// lists:'#playlist:eq(#id)&&ul&&li',
|
||||
lists:'#playlist ul li',
|
||||
},
|
||||
搜索:'*',
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"请求头": "User-Agent$MOBILE_UA",
|
||||
"编码": "UTF-8",
|
||||
"分类": "电影$1#电视剧$2#综艺$3#动漫$4",
|
||||
"类型": "动作片$6#喜剧片$7#爱情片$8#科幻片$9#奇幻片$10#恐怖片$11#剧情片$12#战争片$20#动画片$26#悬疑片$22#冒险片$23#犯罪片$24#惊悚片$45#歌舞片$46#灾难片$47#网络片$48||国产剧$13#港台剧$14#日剧$15#韩剧$33#欧美剧$16#泰剧$34#新马剧$35#其他剧$25||内地综艺$27#港台综艺$28#日本综艺$29#韩国综艺$36#欧美综艺$30#新马泰综艺$37#其他综艺$38||国产动漫$31#日本动漫$32#韩国动漫$39#港台动漫$40#新马泰动漫$41#欧美动漫$42#其他动漫$43",
|
||||
"分类url": "https://www.ylys.tv/vodshow/{cateId}-{area}-{by}-{class}-{lang}-{letter}---{catePg}---{year}.html"
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
const host = 'https://www.haigui.tv';
|
||||
const headers = {
|
||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
|
||||
"Referer": host + "/"
|
||||
};
|
||||
|
||||
async function init(cfg) {}
|
||||
|
||||
const m = (s, r, i = 1) => (s.match(r) || [])[i] || "";
|
||||
const fixPic = p => p && p.startsWith('/') ? host + p : p;
|
||||
|
||||
function getList(html) {
|
||||
return pdfa(html, ".module-item").map(it => {
|
||||
let id = m(it, /href="\/video\/(.*?)\/"/);
|
||||
let name = m(it, /title="(.*?)"/);
|
||||
if (!id || !name) return null;
|
||||
return {
|
||||
vod_id: id,
|
||||
vod_name: name,
|
||||
vod_pic: fixPic(m(it, /data-original="(.*?)"/) || m(it, /src="(.*?)"/)),
|
||||
vod_remarks: m(it, /module-item-note">(.*?)<\/div>/).replace(/<.*?>/g, "")
|
||||
};
|
||||
}).filter(Boolean);
|
||||
}
|
||||
|
||||
async function home(filter) {
|
||||
const classes = [
|
||||
["dianying","电影"],["dianshiju","电视剧"],["zongyi","综艺"],
|
||||
["dongman","动漫"],["jilupian","纪录片"],["duanju","短剧"]
|
||||
].map(([id,name]) => ({type_id:id,type_name:name}));
|
||||
|
||||
const dict = {
|
||||
area: ["中国大陆","中国香港","中国台湾","美国","韩国","日本","泰国"],
|
||||
year: ["2025","2024","2023","2022","2021","2020"],
|
||||
lang: ["国语","英语","粤语","韩语","日语"]
|
||||
};
|
||||
|
||||
const filters = {};
|
||||
classes.forEach(c => {
|
||||
filters[c.type_id] = [
|
||||
{ key:"class", name:"类型", value:getSubClasses(c.type_id) },
|
||||
...Object.keys(dict).map(k => ({
|
||||
key:k,
|
||||
name:{area:"地区",year:"年份",lang:"语言"}[k],
|
||||
value:[{n:"全部",v:""}].concat(dict[k].map(v=>({n:v,v})))
|
||||
}))
|
||||
];
|
||||
});
|
||||
|
||||
return JSON.stringify({ class: classes, filters });
|
||||
}
|
||||
|
||||
function getSubClasses(tid) {
|
||||
const map = {
|
||||
dianying: [
|
||||
["dongzuopian","动作片"],["xijupian","喜剧片"],
|
||||
["aiqingpian","爱情片"],["kehuanpian","科幻片"],["kongbupian","恐怖片"]
|
||||
],
|
||||
dianshiju: [
|
||||
["guochanju","国产剧"],["gangtaiju","港台剧"],
|
||||
["rihanju","日韩剧"],["oumeiju","欧美剧"]
|
||||
]
|
||||
};
|
||||
return [{n:"全部",v:""}].concat((map[tid]||[]).map(([v,n])=>({n,v})));
|
||||
}
|
||||
|
||||
async function homeVod() {
|
||||
const r = await req(host,{headers});
|
||||
return JSON.stringify({ list:getList(r.content) });
|
||||
}
|
||||
|
||||
async function category(tid, pg, filter, extend={}) {
|
||||
let p = pg || 1;
|
||||
let id = extend.class || tid;
|
||||
let url = `${host}/filter/${id}`;
|
||||
["area","lang","year"].forEach(k=>{
|
||||
if (extend[k]) url += `/${k}/${encodeURIComponent(extend[k])}`;
|
||||
});
|
||||
url += `/page/${p}/`;
|
||||
const r = await req(url,{headers});
|
||||
return JSON.stringify({ page:p, list:getList(r.content) });
|
||||
}
|
||||
|
||||
async function detail(id) {
|
||||
const r = await req(`${host}/video/${id}/`,{headers});
|
||||
const h = r.content;
|
||||
|
||||
const playFrom = pdfa(h,".module-tab-item")
|
||||
.map(it=>m(it,/<span>(.*?)<\/span>/)||"播放源")
|
||||
.join("$$$");
|
||||
|
||||
const playUrl = pdfa(h,".module-player-list").map(l =>
|
||||
pdfa(l,".module-blocklist a").map(it=>{
|
||||
let pid = m(it,/href=\"\/play\/(.*?)\/\"/);
|
||||
if (!pid) return null;
|
||||
return `${m(it,/<span>(.*?)<\/span>/)||"正片"}$${pid}`;
|
||||
}).filter(Boolean).join("#")
|
||||
).join("$$$");
|
||||
|
||||
return JSON.stringify({
|
||||
list:[{
|
||||
vod_id:id,
|
||||
vod_name:m(h,/page-title\">(.*?)<\/h1>/),
|
||||
vod_pic:fixPic(m(h,/video-cover.*?data-src=\"(.*?)\"/)||m(h,/video-cover.*?src=\"(.*?)\"/)),
|
||||
type_name:(
|
||||
m(h,/tag-link[^>]*>[\s\S]*?icon-cate-[^<]*<\/i>\s*([^<\n]+)/) ||
|
||||
m(h,/icon-cate-[^<]*<\/i>\s*([^<\n]+)/)
|
||||
).trim(),
|
||||
vod_year:m(h,/year\/(\d+)\//),
|
||||
vod_area:m(h,/area\/.*?\/ \">(.*?)\t/s).trim(),
|
||||
vod_director:m(h,/导演:<\/span>.*?<div.*?>(.*?)<\/div>/s).replace(/<.*?>|\//g,"").trim(),
|
||||
vod_actor:m(h,/主演:<\/span>.*?<div.*?>(.*?)<\/div>/s).replace(/<.*?>|\//g,"").trim(),
|
||||
vod_remarks:m(h,/备注:<\/span>.*?<div.*?>(.*?)<\/div>/),
|
||||
vod_content:m(h,/vod_content.*?<span>(.*?)<\/span>/s)||"暂无简介",
|
||||
vod_play_from:playFrom,
|
||||
vod_play_url:playUrl
|
||||
}]
|
||||
});
|
||||
}
|
||||
|
||||
async function search(wd, quick, pg=1) {
|
||||
let url = `${host}/search/${encodeURIComponent(wd)}/${pg>1?`page/${pg}/`:""}`;
|
||||
const r = await req(url,{headers});
|
||||
const h = r.content;
|
||||
|
||||
const items = pdfa(h,".module-search-item") || pdfa(h,".module-item");
|
||||
|
||||
const list = items.map(it=>{
|
||||
let id = m(it,/\/video\/(.*?)\//);
|
||||
let name = m(it,/title=\"(.*?)\"/) || m(it,/alt=\"(.*?)\"/);
|
||||
if (!id || !name) return null;
|
||||
return {
|
||||
vod_id:id,
|
||||
vod_name:name,
|
||||
vod_pic:fixPic(m(it,/data-src=\"(.*?)\"/)||m(it,/data-original=\"(.*?)\"/)||m(it,/src=\"(.*?)\"/)),
|
||||
vod_remarks:m(it,/module-item-note\">(.*?)<\/div>/)||m(it,/video-serial\">(.*?)<\/span>/)
|
||||
};
|
||||
}).filter(Boolean);
|
||||
|
||||
return JSON.stringify({ page:pg, list });
|
||||
}
|
||||
|
||||
async function play(flag, id, flags) {
|
||||
const r = await req(`${host}/play/${id}/`,{headers});
|
||||
let u = m(r.content,/"url":"([^"]+\.m3u8[^"]*)"/);
|
||||
if (u) return JSON.stringify({ parse:0, url:u.replace(/\\/g,""), header:headers });
|
||||
return JSON.stringify({ parse:1, url:`${host}/play/${id}/`, header:headers });
|
||||
}
|
||||
|
||||
export default { init, home, homeVod, category, detail, search, play };
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
@header({
|
||||
searchable: 2,
|
||||
filterable: 1,
|
||||
quickSearch: 0,
|
||||
title: '热播之家',
|
||||
'类型': '影视',
|
||||
lang: 'ds'
|
||||
})
|
||||
*/
|
||||
|
||||
var rule = {
|
||||
title: '热播之家',
|
||||
host: 'https://rebozj.pro',
|
||||
//url: '/type/fyclass-fypage.html',
|
||||
url: '/show/fyfilter.html',
|
||||
filterable: 1,//是否启用分类筛选,
|
||||
filter_url: '{{fl.cateId}}-{{fl.area}}-{{fl.by or "time"}}-{{fl.class}}-{{fl.lang}}-{{fl.letter}}---fypage---{{fl.year}}',
|
||||
filter: 'H4sIAAAAAAAAA+1Z704bRxB/l/vMhzuDDeQN+gxVPrip1UalVAJaCUVIJMbUNsQ2UWOXQPmjYuwUDAZSEmxsXsZ7Z79Fz97dmVlymV6x2yqSv/n3m9u9mdmd3d+cn1mO9ejLZ9Z3iWXrkfUkvpT44mtrwpqPf5/wsbuZ8S6aYm/Dp36Kz/2YGDw771tEqtpLVvu0DxxrZULR2WqntavoGNLFXZGpKHoaaC994SZTip5BurIlbpqKngXafV5wV4v6lTZOnqngLA764qZ/7TQymo9YK4/7FhXoXHxx0YgTZ/l0nMGvVCAwVgUC06NAYDIUgFCSWffFG2VTIDAtCsCc2XOv9YeeUwIY9+LUK27pcRKAn+uvettvtZ8SBK6OAjCu/DPaFAhcDgVg3Nm1aNT0OAnAllsX+UttkwBs+aPu77AOEmhb5/age1ZXNgXAl9pxp32gfZFA23r7V52bgrIpoG3du4K/asqmAM652U3vwZwDAOPKd7iLFIB8Pm/33rR1PiWgWzW+kIibO3W3LjYbYXfqUaW3va4zJAFEerztfjjXkUqAma27N23I7ACAx+2c2GlpjyWALFy9RpsCkIWNC7QpAONKZXf3VI+TAFfkLY5TAPxsv0ebAuhLnfpSN8a9rIvGsR4nAYxby/uZEmldAIjJenr5mpfZxiVVGCv9wN2484dBsWsMT6SuO01dtwrQdV9OxBfMdb9512m2Qq57xI5MKW7wk/CTyE9SPoJ8hPIO8g7lbeRtwjuzwDuzlJ9Bfoby08hPUz6GfIzyUeSjlMd4HRqvg/E6NF4H43VovA7G69B4HYy3f/mQlZqLz39jrFT3vNatroat0J2W/7zeBxKQikGbAlCFl0doUwAqptQSL0toRkxqipglILWINgVIfRObBKQWSSQSkN0uzpK42/uA5vCrZZLB3CvRyH+UPrd03Su9U1MsPfUfhaO+0XDrvyjLt0+XFjGB52sirY+/xSc/LCT6b308YUWGVz0RuoSdRgVvfbLP/DPVPz2JaYqmuX+YoQl3s/vne3FUJKbYKNULpzQ4ZcPdF6zSYG5+ToVwyoa7+bnbnVM2nDrjlA2n+Djl9lDVwyqwwVbE06QPwJfTin9ba18kGPb+lTtVj5Mg1P0bpC9Gp3rWU/7zsMoDECaahyoiLnu8Wvp0hli1VKz7gkL8dqiHAh6ri7G6sD5bdfGPVMJm5r8QCpPDC4XJUV7efhsrWq/1okkQpuXlLpSHtrzePuyQfbJ1OCkA2sL4vMF9GuA+Rfy7rTNziUhZpz2WwNR1uMH7gL2Cx8fyqI7lQcVODV+xmDol7bNV9/ZEv+ojCW9Yo/c2iWmN3dsKpnV6lCdFgHMGxYRoUIzDBsWEbVD3mhzjOUqFkuycLOc+tnIS+oEfd9m2ipP6a3feSVnbJAjTHgWfvuwnSqYZ4e4ArhFjz26mSWNvCaaB4z6zsk1TMy9SH/T7JIA5C3veKWRZgjDS3g/XLZYw9j4A28Gh2AGZIwH4kqx1D1e1LxJADIWcOIM6lCBMA2fW771KS6a6mUtY9wGAcfUtUb7S4yQAP0/23Cz4KQHMedl019J6TgnAlqt6BS2mFBjhvcy1uNxqcdkbt0vWuF0at0tDt0vR4cUX7iP5f5XXvO1mGspIdqUUFaZ1hubNz6RhJZUhy9+0OiMQX9G/myPEQRcdnzyfz8kDvI3x2jReG+O1abw2xmvTeG2M16bx2hivTeO1MV57ahQn4f/2p8zKXyGn+e2MIgAA',
|
||||
filter_def: {
|
||||
1: {cateId: '1'},
|
||||
2: {cateId: '2'},
|
||||
3: {cateId: '3'},
|
||||
4: {cateId: '4'},
|
||||
5: {cateId: '5'}
|
||||
},
|
||||
searchUrl: '/type/id-.html?wd=**',
|
||||
searchable: 2,//是否启用全局搜索,
|
||||
quickSearch: 0,//是否启用快速搜索,
|
||||
headers: {
|
||||
'User-Agent': 'UC_UA',
|
||||
},
|
||||
class_parse: '.stui-header__menu li:lt(6);a&&Text;a&&href;.*/(.*?).html',
|
||||
play_parse: true,
|
||||
tab_remove:['蓝光专享1','夸克4K','极速有广①','极速有广②'],
|
||||
lazy: '',
|
||||
limit: 6,
|
||||
推荐: 'ul.stui-vodlist.clearfix;li;a&&title;.lazyload&&data-original;.pic-text&&Text;a&&href',
|
||||
double: true, // 推荐内容是否双层定位
|
||||
一级: '.stui-vodlist li;a&&title;a&&data-original;.pic-text&&Text;a&&href',
|
||||
二级: {
|
||||
"title": ".stui-content__detail .title&&Text;.stui-content__detail p:eq(-2)&&Text",
|
||||
"img": ".stui-content__thumb .lazyload&&data-original",
|
||||
"desc": ".stui-content__detail p:eq(0)&&Text;.stui-content__detail p:eq(1)&&Text;.stui-content__detail p:eq(2)&&Text",
|
||||
"content": ".detail&&Text",
|
||||
"tabs": ".nav.nav-tabs li",
|
||||
"lists": ".stui-content__playlist:eq(#id) li"
|
||||
},
|
||||
搜索: '*',
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
var rule = {
|
||||
title:'爱上你听书网',
|
||||
host:'https://www.230ts.net',
|
||||
url:'/sort/fyclass/fypage.html',
|
||||
searchUrl:'/search.html?searchtype=name&searchword=**&page=fypage',
|
||||
searchable:2,
|
||||
quickSearch:0,
|
||||
headers:{
|
||||
'User-Agent':'PC_UA'
|
||||
},
|
||||
timeout:5000,
|
||||
class_parse: '.nav-ol&&li:gt(0):lt(6);a&&Text;a&&href;.*/(\\w+).html',
|
||||
play_parse:true,
|
||||
lazy:'js:input=input.replace("www","wap")',
|
||||
limit:6,
|
||||
推荐:'#myTab_Content1&&li;.tab-book-title&&Text;*;.tab-book-author&&Text;*',
|
||||
一级:'ul.list-works&&li;.list-book-dt--span&&Text;.lazy&&data-original;.book-author:eq(2)&&a&&Text;a&&href',
|
||||
二级:{
|
||||
title:'.book-cover&&alt;.book-info&&dd--span:eq(1)&&Text',
|
||||
img:'.book-cover&&src',
|
||||
desc:'.book-info&&dd:eq(4)&&Text;;;.book-info&&dd--span:eq(3)&&Text;.book-info&&dd--span:eq(2)&&Text',
|
||||
content:'.book-des&&Text',
|
||||
tabs:'.playlist-top&&h2',
|
||||
lists:'#playlist:eq(#id)&&li',
|
||||
},
|
||||
搜索:'*',
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"请求头": "User-Agent$MOBILE_UA",
|
||||
"主页url": "https://www.aiwodj.com",
|
||||
"数组": "lazy lazyloaded&&</a[替换:amp;>>]",
|
||||
"图片": "data-src=\"&&\"",
|
||||
"标题": "title=\"&&\"",
|
||||
"链接": "href=\"&&\"",
|
||||
"副标题": "+module-item-caption\">&&</div",
|
||||
"简介": "description\" content=\"&&,这里",
|
||||
"线路数组": "module-tab-item tab-item&&</div",
|
||||
"线路标题": "+span>&&</span",
|
||||
"播放数组": "module-blocklist&&</div>",
|
||||
"播放列表": "<a&&</a>",
|
||||
"播放标题": "span>&&</span>",
|
||||
"播放链接": "href=\"&&\"",
|
||||
"跳转播放链接": "urlDecode(var player_*\"url\":\"&&\")",
|
||||
"搜索url": "https://www.aiwodj.com/vodsearch/{wd}----------{pg}---.html",
|
||||
"搜索数组": "lazy lazyload&&</a[替换:amp;>>]",
|
||||
"搜索图片": "data-src=\"&&\"",
|
||||
"搜索标题": "+title=\"&&\"",
|
||||
"搜索链接": "href=\"&&\"",
|
||||
"分类url": "https://www.aiwodj.com/vodshow/{cateId}--{by}-{class}-{lang}----{catePg}---{year}.html",
|
||||
"分类": "穿越&战神&重生&爱情&萌娃&神医&古代&玄幻&言情",
|
||||
"分类值": "fenle&fenlei2&fenlei3&fenlei4&guda&shenyi&gudai&xuanhuan&yanqing"
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
@header({
|
||||
searchable: 2,
|
||||
filterable: 1,
|
||||
quickSearch: 0,
|
||||
title: '爱看机器人[虫]',
|
||||
lang: 'dr2'
|
||||
})
|
||||
*/
|
||||
|
||||
var rule = {
|
||||
title:'爱看机器人[虫]',
|
||||
// host:'https://v.ikanbot.com',
|
||||
host:'https://v.aikanbot.com',
|
||||
url:'/hot/index-fyclass-fyfilter-p-fypage.html[/hot/index-fyclass-fyfilter.html]',
|
||||
//https://www.ikanbot.com/search?q=%E6%96%97%E7%BD%97%E5%A4%A7&p=2
|
||||
// searchUrl:'/search?q=**&p=fypage',
|
||||
searchUrl:'/search?q=**&p=fypage[/search?q=**]',
|
||||
searchable:2,
|
||||
quickSearch:0,
|
||||
filterable:1,
|
||||
filter_url:'{{fl.tag}}',
|
||||
//图片来源:'@Referer=https://v.ikanbot.com/@User-Agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36',
|
||||
filter:{
|
||||
"movie":[{"key":"tag","name":"标签","value":[{"n":"热门","v":"热门"},{"n":"最新","v":"最新"},{"n":"经典","v":"经典"},{"n":"豆瓣高分","v":"豆瓣高分"},{"n":"冷门佳片","v":"冷门佳片"},{"n":"华语","v":"华语"},{"n":"欧美","v":"欧美"},{"n":"韩国","v":"韩国"},{"n":"日本","v":"日本"},{"n":"动作","v":"动作"},{"n":"喜剧","v":"喜剧"},{"n":"爱情","v":"爱情"},{"n":"科幻","v":"科幻"},{"n":"悬疑","v":"悬疑"},{"n":"恐怖","v":"恐怖"},{"n":"治愈","v":"治愈"},{"n":"豆瓣top250","v":"豆瓣top250"}]}]
|
||||
,"tv":[{"key":"tag","name":"标签","value":[{"n":"热门","v":"热门"},{"n":"美剧","v":"美剧"},{"n":"英剧","v":"英剧"},{"n":"韩剧","v":"韩剧"},{"n":"日剧","v":"日剧"},{"n":"国产剧","v":"国产剧"},{"n":"港剧","v":"港剧"},{"n":"日本动画","v":"日本动画"},{"n":"综艺","v":"综艺"},{"n":"纪录片","v":"纪录片"}]}]
|
||||
},
|
||||
filter_def:{
|
||||
movie:{tag:'热门'},
|
||||
tv:{tag:'国产剧'},
|
||||
},
|
||||
filter获取方法:`
|
||||
let value = [];
|
||||
$('ul').eq(2).find('li').each(function() {
|
||||
// console.log($(this).text());
|
||||
let n = $(this).text().trim();
|
||||
value.push({
|
||||
'n': n, 'v': n
|
||||
});
|
||||
});
|
||||
// 电影执行:
|
||||
let data = {'movie': [{'key': 'tag', 'name': '标签', 'value': value}]};
|
||||
console.log(JSON.stringify(data));
|
||||
|
||||
//剧集执行:
|
||||
let data = {'tv': [{'key': 'tag', 'name': '标签', 'value': value}]};
|
||||
console.log(JSON.stringify(data));
|
||||
`,
|
||||
headers:{'User-Agent':'PC_UA',},
|
||||
class_name:'电影&剧集',
|
||||
class_url:'movie&tv',
|
||||
play_parse:true,
|
||||
double:true,
|
||||
tab_remove:['wjm3u8','ikm3u8','sdm3u8','M3U8','jinyingm3u8','fsm3u8','ukm3u8'],//移除某个线路及相关的选集
|
||||
tab_order:['bfzym3u8','1080zyk','kuaikan','lzm3u8','ffm3u8','snm3u8','qhm3u8','gsm3u8','zuidam3u8','bjm3u8','wolong','xlm3u8','yhm3u8'],//线路顺序,按里面的顺序优先,没写的依次排后面
|
||||
tab_rename:{'bfzym3u8':'暴风','1080zyk':'优质','kuaikan':'快看','lzm3u8':'量子','ffm3u8':'非凡','snm3u8':'索尼','qhm3u8':'奇虎','haiwaikan':'海外看','gsm3u8':'光速','zuidam3u8':'最大','bjm3u8':'八戒','wolong':'卧龙','xlm3u8':'新浪','yhm3u8':'樱花','tkm3u8':'天空','jsm3u8':'极速','wjm3u8':'无尽','sdm3u8':'闪电','kcm3u8':'快车','jinyingm3u8':'金鹰','fsm3u8':'飞速','tpm3u8':'淘片','lem3u8':'鱼乐','dbm3u8':'百度','tomm3u8':'番茄','ukm3u8':'U酷','ikm3u8':'爱坤','hnzym3u8':'红牛资源','hnm3u8':'红牛','68zy_m3u8':'68','kdm3u8':'酷点','bdxm3u8':'北斗星','hhm3u8':'豪华','kbm3u8':'快播'},//线路名替换如:lzm3u8替换为量子资源
|
||||
推荐:'.v-list;div.item;*;*;*;*', //这里可以为空,这样点播不会有内容
|
||||
// 一级:'.v-list&&div.item;p&&Text;img&&src;;a&&href', //一级的内容是推荐或者点播时候的一级匹配
|
||||
一级:'.v-list&&div.item;p&&Text;img&&data-src;;a&&href', //一级的内容是推荐或者点播时候的一级匹配
|
||||
// 二级:二级,
|
||||
二级:'js:eval(unescape(base64Decode("anM6CiAgICAgICAgcGRmaCA9IGpzcC5wZGZoOwogICAgICAgIGZ1bmN0aW9uIGdldFRva2VuKGh0bWwxKSB7CiAgICAgICAgICAgIGxldCBjdXJyZW50SWQgPSBwZGZoKGh0bWwxLCAnI2N1cnJlbnRfaWQmJnZhbHVlJyk7CiAgICAgICAgICAgIGxldCBlVG9rZW4gPSBwZGZoKGh0bWwxLCAnI2VfdG9rZW4mJnZhbHVlJyk7CiAgICAgICAgICAgIGlmICghY3VycmVudElkIHx8ICFlVG9rZW4pIHJldHVybiAnJzsKICAgICAgICAgICAgbGV0IGlkTGVuZ3RoID0gY3VycmVudElkLmxlbmd0aDsKICAgICAgICAgICAgbGV0IHN1YklkID0gY3VycmVudElkLnN1YnN0cmluZyhpZExlbmd0aCAtIDQsIGlkTGVuZ3RoKTsKICAgICAgICAgICAgbGV0IGtleXMgPSBbXTsKICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzdWJJZC5sZW5ndGg7IGkrKykgewogICAgICAgICAgICAgICAgbGV0IGN1ckludCA9IHBhcnNlSW50KHN1YklkW2ldKTsKICAgICAgICAgICAgICAgIGxldCBzcGxpdFBvcyA9IGN1ckludCAlIDMgKyAxOwogICAgICAgICAgICAgICAga2V5c1tpXSA9IGVUb2tlbi5zdWJzdHJpbmcoc3BsaXRQb3MsIHNwbGl0UG9zICsgOCk7CiAgICAgICAgICAgICAgICBlVG9rZW4gPSBlVG9rZW4uc3Vic3RyaW5nKHNwbGl0UG9zICsgOCwgZVRva2VuLmxlbmd0aCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIGtleXMuam9pbignJyk7CiAgICAgICAgfQogICAgICAgIHRyeSB7CiAgICAgICAgICAgIFZPRD17fTsKICAgICAgICAgICAgbGV0IGh0bWwxID0gcmVxdWVzdChpbnB1dCk7CiAgICAgICAgICAgIFZPRC52b2RfaWQgPSBwZGZoKGh0bWwxLCAnI2N1cnJlbnRfaWQmJnZhbHVlJyk7CiAgICAgICAgICAgIFZPRC52b2RfbmFtZSA9IHBkZmgoaHRtbDEsICdoMiYmVGV4dCcpOwogICAgICAgICAgICBWT0Qudm9kX3BpYyA9IHBkZmgoaHRtbDEsICcuaXRlbS1yb290JiZpbWcmJmRhdGEtc3JjJyk7CiAgICAgICAgICAgIFZPRC52b2RfYWN0b3IgPSBwZGZoKGh0bWwxLCAnLm1ldGE6ZXEoNCkmJlRleHQnKTsKICAgICAgICAgICAgVk9ELnZvZF9hcmVhID0gcGRmaChodG1sMSwgJy5tZXRhOmVxKDMpJiZUZXh0Jyk7CiAgICAgICAgICAgIFZPRC52b2RfeWVhciA9IHBkZmgoaHRtbDEsICcubWV0YTplcSgyKSYmVGV4dCcpOwogICAgICAgICAgICBWT0Qudm9kX3JlbWFya3MgPSAnJzsKICAgICAgICAgICAgVk9ELnZvZF9kaXJlY3RvciA9ICcnOwogICAgICAgICAgICBWT0Qudm9kX2NvbnRlbnQgPSBwZGZoKGh0bWwxLCAnI2xpbmUtdGlwcyYmVGV4dCcpOwogICAgICAgICAgICAvLyBsb2coVk9EKTsKICAgICAgICAgICAgdmFyIHZfdGtzID0gZ2V0VG9rZW4oaHRtbDEpOwogICAgICAgICAgICBsb2coJ3ZfdGtzID09PT4gJyArIHZfdGtzKTsKICAgICAgICAgICAgaW5wdXQgPSBIT1NUICsgJy9hcGkvZ2V0UmVzTj92aWRlb0lkPScgKyBpbnB1dC5zcGxpdCgnLycpLnBvcCgpICsgJyZtdHlwZT0yJnRva2VuPScrdl90a3M7CiAgICAgICAgICAgIGxldCBodG1sID0gcmVxdWVzdChpbnB1dCwgewogICAgICAgICAgICAgICAgaGVhZGVyczogewogICAgICAgICAgICAgICAgICAgICdVc2VyLUFnZW50JzonTW96aWxsYS81LjAgKGlQaG9uZTsgQ1BVIGlQaG9uZSBPUyAxM18yXzMgbGlrZSBNYWMgT1MgWCkgQXBwbGVXZWJLaXQvNjA1LjEuMTUgKEtIVE1MLCBsaWtlIEdlY2tvKSBWZXJzaW9uLzEzLjAuMyBNb2JpbGUvMTVFMTQ4IFNhZmFyaS82MDQuMScsCiAgICAgICAgICAgICAgICAgICAgJ1JlZmVyZXInOiBNWV9VUkwsCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0pOwogICAgICAgICAgICBwcmludChodG1sKTsKICAgICAgICAgICAgaHRtbCA9IEpTT04ucGFyc2UoaHRtbCk7CiAgICAgICAgICAgIGxldCBlcGlzb2RlcyA9IGh0bWwuZGF0YS5saXN0OwogICAgICAgICAgICBsZXQgcGxheU1hcCA9IHt9OwogICAgICAgICAgICBpZiAodHlwZW9mIHBsYXlfdXJsID09PSAndW5kZWZpbmVkJykgewogICAgICAgICAgICAgICAgdmFyIHBsYXlfdXJsID0gJycKICAgICAgICAgICAgfQogICAgICAgICAgICBsZXQgbWFwID0ge30KICAgICAgICAgICAgbGV0IGFyciA9IFtdCiAgICAgICAgICAgIGxldCBuYW1lID0gewogICAgICAgICAgICAgICAgJ2JmenltM3U4JzogJ+aatOmjjicsCiAgICAgICAgICAgICAgICAnMTA4MHp5ayc6ICfkvJjotKgnLAogICAgICAgICAgICAgICAgJ2t1YWlrYW4nOiAn5b+r55yLJywKICAgICAgICAgICAgICAgICdsem0zdTgnOiAn6YeP5a2QJywKICAgICAgICAgICAgICAgICdmZm0zdTgnOiAn6Z2e5YehJywKICAgICAgICAgICAgICAgICdoYWl3YWlrYW4nOiAn5rW35aSW55yLJywKICAgICAgICAgICAgICAgICdnc20zdTgnOiAn5YWJ6YCfJywKICAgICAgICAgICAgICAgICd6dWlkYW0zdTgnOiAn5pyA5aSnJywKICAgICAgICAgICAgICAgICdiam0zdTgnOiAn5YWr5oiSJywKICAgICAgICAgICAgICAgICdzbm0zdTgnOiAn57Si5bC8JywKICAgICAgICAgICAgICAgICd3b2xvbmcnOiAn5Y2n6b6ZJywKICAgICAgICAgICAgICAgICd4bG0zdTgnOiAn5paw5rWqJywKICAgICAgICAgICAgICAgICd5aG0zdTgnOiAn5qix6IqxJywKICAgICAgICAgICAgICAgICd0a20zdTgnOiAn5aSp56m6JywKICAgICAgICAgICAgICAgICdqc20zdTgnOiAn5p6B6YCfJywKICAgICAgICAgICAgICAgICd3am0zdTgnOiAn5peg5bC9JywKICAgICAgICAgICAgICAgICdzZG0zdTgnOiAn6Zeq55S1JywKICAgICAgICAgICAgICAgICdrY20zdTgnOiAn5b+r6L2mJywKICAgICAgICAgICAgICAgICdqaW55aW5nbTN1OCc6ICfph5HpubAnLAogICAgICAgICAgICAgICAgJ2ZzbTN1OCc6ICfpo57pgJ8nLAogICAgICAgICAgICAgICAgJ3RwbTN1OCc6ICfmt5jniYcnLAogICAgICAgICAgICAgICAgJ2xlbTN1OCc6ICfpsbzkuZAnLAogICAgICAgICAgICAgICAgJ2RibTN1OCc6ICfnmb7luqYnLAogICAgICAgICAgICAgICAgJ3RvbW0zdTgnOiAn55Wq6IyEJywKICAgICAgICAgICAgICAgICd1a20zdTgnOiAnVemFtycsCiAgICAgICAgICAgICAgICAnaWttM3U4JzogJ+eIseWdpCcsCiAgICAgICAgICAgICAgICAnaG56eW0zdTgnOiAn57qi54mb6LWE5rqQJywKICAgICAgICAgICAgICAgICdobm0zdTgnOiAn57qi54mbJywKICAgICAgICAgICAgICAgICc2OHp5X20zdTgnOiAnNjgnLAogICAgICAgICAgICAgICAgJ2tkbTN1OCc6ICfphbfngrknLAogICAgICAgICAgICAgICAgJ2JkeG0zdTgnOiAn5YyX5paX5pifJywKICAgICAgICAgICAgICAgICdxaG0zdTgnOiAn5aWH6JmOJywKICAgICAgICAgICAgICAgICdoaG0zdTgnOiAn6LGq5Y2OJwogICAgICAgICAgICB9OwogICAgICAgICAgICBlcGlzb2Rlcy5mb3JFYWNoKGZ1bmN0aW9uKGVwKSB7CiAgICAgICAgICAgICAgICBsZXQgZGF0YSA9IEpTT04ucGFyc2UoZXBbJ3Jlc0RhdGEnXSk7CiAgICAgICAgICAgICAgICBkYXRhLm1hcCh2YWwgPT4gewogICAgICAgICAgICAgICAgICAgIGlmKCFtYXBbdmFsLmZsYWddKXsKICAgICAgICAgICAgICAgICAgICAgICAgbWFwW3ZhbC5mbGFnXSA9IFt2YWwudXJsLnJlcGxhY2VBbGwoJyMjJywnIycpXQogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIG1hcFt2YWwuZmxhZ10ucHVzaCh2YWwudXJsLnJlcGxhY2VBbGwoJyMjJywnIycpKQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0pCiAgICAgICAgICAgIH0pOwogICAgICAgICAgICBmb3IgKHZhciBrZXkgaW4gbWFwKSB7CiAgICAgICAgICAgICAgICBpZiAoJ2JmenltM3U4JyA9PSBrZXkpIHsKICAgICAgICAgICAgICAgICAgICBhcnIucHVzaCh7CiAgICAgICAgICAgICAgICAgICAgICAgIGZsYWc6IG5hbWVba2V5XSwKICAgICAgICAgICAgICAgICAgICAgICAgdXJsOiBtYXBba2V5XSwKICAgICAgICAgICAgICAgICAgICAgICAgc29ydDogMQogICAgICAgICAgICAgICAgICAgIH0pCiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCcxMDgwenlrJyA9PSBrZXkpIHsKICAgICAgICAgICAgICAgICAgICBhcnIucHVzaCh7CiAgICAgICAgICAgICAgICAgICAgICAgIGZsYWc6IG5hbWVba2V5XSwKICAgICAgICAgICAgICAgICAgICAgICAgdXJsOiBtYXBba2V5XSwKICAgICAgICAgICAgICAgICAgICAgICAgc29ydDogMgogICAgICAgICAgICAgICAgICAgIH0pCiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCdrdWFpa2FuJyA9PSBrZXkpIHsKICAgICAgICAgICAgICAgICAgICBhcnIucHVzaCh7CiAgICAgICAgICAgICAgICAgICAgICAgIGZsYWc6IG5hbWVba2V5XSwKICAgICAgICAgICAgICAgICAgICAgICAgdXJsOiBtYXBba2V5XSwKICAgICAgICAgICAgICAgICAgICAgICAgc29ydDogMwogICAgICAgICAgICAgICAgICAgIH0pCiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCdsem0zdTgnID09IGtleSkgewogICAgICAgICAgICAgICAgICAgIGFyci5wdXNoKHsKICAgICAgICAgICAgICAgICAgICAgICAgZmxhZzogbmFtZVtrZXldLAogICAgICAgICAgICAgICAgICAgICAgICB1cmw6IG1hcFtrZXldLAogICAgICAgICAgICAgICAgICAgICAgICBzb3J0OiA0CiAgICAgICAgICAgICAgICAgICAgfSkKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoJ2ZmbTN1OCcgPT0ga2V5KSB7CiAgICAgICAgICAgICAgICAgICAgYXJyLnB1c2goewogICAgICAgICAgICAgICAgICAgICAgICBmbGFnOiBuYW1lW2tleV0sCiAgICAgICAgICAgICAgICAgICAgICAgIHVybDogbWFwW2tleV0sCiAgICAgICAgICAgICAgICAgICAgICAgIHNvcnQ6IDUKICAgICAgICAgICAgICAgICAgICB9KQogICAgICAgICAgICAgICAgfSBlbHNlIGlmICgnc25tM3U4JyA9PSBrZXkpIHsKICAgICAgICAgICAgICAgICAgICBhcnIucHVzaCh7CiAgICAgICAgICAgICAgICAgICAgICAgIGZsYWc6IG5hbWVba2V5XSwKICAgICAgICAgICAgICAgICAgICAgICAgdXJsOiBtYXBba2V5XSwKICAgICAgICAgICAgICAgICAgICAgICAgc29ydDogNgogICAgICAgICAgICAgICAgICAgIH0pCiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCdxaG0zdTgnID09IGtleSkgewogICAgICAgICAgICAgICAgICAgIGFyci5wdXNoKHsKICAgICAgICAgICAgICAgICAgICAgICAgZmxhZzogbmFtZVtrZXldLAogICAgICAgICAgICAgICAgICAgICAgICB1cmw6IG1hcFtrZXldLAogICAgICAgICAgICAgICAgICAgICAgICBzb3J0OiA3CiAgICAgICAgICAgICAgICAgICAgfSkKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgYXJyLnB1c2goewogICAgICAgICAgICAgICAgICAgICAgICBmbGFnOiAobmFtZVtrZXldKSA/IG5hbWVba2V5XSA6IGtleSwKICAgICAgICAgICAgICAgICAgICAgICAgdXJsOiBtYXBba2V5XSwKICAgICAgICAgICAgICAgICAgICAgICAgc29ydDogOAogICAgICAgICAgICAgICAgICAgIH0pCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYXJyLnNvcnQoKGEsIGIpID0+IGEuc29ydCAtIGIuc29ydCk7CiAgICAgICAgICAgIGxldCBwbGF5RnJvbSA9IFtdOwogICAgICAgICAgICBsZXQgcGxheUxpc3QgPSBbXTsKICAgICAgICAgICAgYXJyLm1hcCh2YWwgPT4gewogICAgICAgICAgICAgICAgaWYgKCEvdW5kZWZpbmVkLy50ZXN0KHZhbC5mbGFnKSkgewogICAgICAgICAgICAgICAgICAgIHBsYXlGcm9tLnB1c2godmFsLmZsYWcpOwogICAgICAgICAgICAgICAgICAgIHBsYXlMaXN0LnB1c2godmFsLnVybCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0pCiAgICAgICAgICAgIGxldCB2b2RfcGxheV9mcm9tID0gcGxheUZyb20uam9pbignJCQkJyk7CiAgICAgICAgICAgIGxldCB2b2RfcGxheV91cmwgPSBwbGF5TGlzdC5qb2luKCckJCQnKTsKICAgICAgICAgICAgVk9EWyd2b2RfcGxheV9mcm9tJ10gPSB2b2RfcGxheV9mcm9tOwogICAgICAgICAgICBWT0RbJ3ZvZF9wbGF5X3VybCddID0gdm9kX3BsYXlfdXJsOwogICAgICAgICAgICAvLyBsb2coVk9EKTsKICAgICAgICB9IGNhdGNoIChlKSB7CiAgICAgICAgICAgIGxvZygn6I635Y+W5LqM57qn6K+m5oOF6aG15Y+R55Sf6ZSZ6K+vOicgKyBlLm1lc3NhZ2UpCiAgICAgICAgfQ==")))',
|
||||
// 搜索:'#search-result&&.media;h5&&a&&Text;a&&img&&data-src;.label&&Text;a&&href',//第三个是描述,一般显示更新或者完结
|
||||
搜索:'.col-md-8&&.media;h5&&a&&Text;a&&img&&data-src;.label&&Text;a&&href',//第三个是描述,一般显示更新或者完结
|
||||
lazy:`
|
||||
if(/\\.m3u8$/.test(input)){
|
||||
input = {
|
||||
parse:0,
|
||||
url:getProxyUrl()+'&url='+input,
|
||||
jx:0
|
||||
}
|
||||
}
|
||||
`,
|
||||
proxy_rule: `js:
|
||||
let url = input.url;
|
||||
let m3u8 = fixAdM3u8Ai(url);
|
||||
input = [200,'application/vnd.apple.mpegurl',m3u8]
|
||||
`
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
H4sIAEIfMGcC/4VRy0oDMRTd+xWzmmjVmSroIqX4ABeCIqh1ozLE6Z0mmNgxybSOUnCngkr36kbwsXAjuJCCfo22foYzzYyoCN5Nck/OuY+TBpGWjDhYZetgwEpCM80Bo97x48fL7eLa+nv7YRON9J9oXWmMqNahwq7bbDYd5lMQDceviy+KgIrkGLmi4WZYlOdB7HOilBfEIamBQ7XgGUUBkT41QnN3QhpObUNcLhTslK3KRvVDQLaSUccNshsxf3ulD+OigUy3kEiVLORwYF7AbZuzErHtVdjT6UklBCWn4A5ubFSHh7yx71NRIFWQChtj0kAVBXJ0pgY7GmG0uDQ7vzDnVWZQn9AayQwUUI80nigWszlCTuJsDC0jMCAn+zFGWSfOBNN40iTVepTuFRCuMu77xWvv5Kh7ddPttDGaXoYAJMjy3z+R2949v/84S+iFLH97Pux17rCFHNHwOFM6t6L/4yUmarZdJZqMKumXcmtybec01X7V6rYve0/Xiakq/LeUo9hODeRvyynTymBJzdbAJ4hAe0OIAgAA
|
||||
@@ -0,0 +1,156 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# by @嗷呜
|
||||
import sys
|
||||
sys.path.append('..')
|
||||
from base.spider import Spider
|
||||
|
||||
class Spider(Spider):
|
||||
|
||||
def init(self, extend=""):
|
||||
pass
|
||||
|
||||
def getName(self):
|
||||
return "甜圈短剧"
|
||||
|
||||
def isVideoFormat(self, url):
|
||||
return True
|
||||
|
||||
def manualVideoCheck(self):
|
||||
return False
|
||||
|
||||
def destroy(self):
|
||||
pass
|
||||
|
||||
# 更新为新的域名
|
||||
ahost = 'https://mov.cenguigui.cn'
|
||||
|
||||
headers = {
|
||||
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36',
|
||||
'sec-ch-ua-platform': '"macOS"',
|
||||
'sec-ch-ua': '"Not/A)Brand";v="8", "Chromium";v="134", "Google Chrome";v="134"',
|
||||
'DNT': '1',
|
||||
'sec-ch-ua-mobile': '?0',
|
||||
'Sec-Fetch-Site': 'cross-site',
|
||||
'Sec-Fetch-Mode': 'no-cors',
|
||||
'Sec-Fetch-Dest': 'video',
|
||||
'Sec-Fetch-Storage-Access': 'active',
|
||||
'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
|
||||
}
|
||||
|
||||
def homeContent(self, filter):
|
||||
result = {'class': [{'type_id': '推荐榜', 'type_name': '🔥 推荐榜'},
|
||||
{'type_id': '新剧', 'type_name': '🎬 新剧'},
|
||||
{'type_id': '逆袭', 'type_name': '🎬 逆袭'},
|
||||
{'type_id': '霸总', 'type_name': '🎬 霸总'},
|
||||
{'type_id': '现代言情', 'type_name': '🎬 现代言情'},
|
||||
{'type_id': '打脸虐渣', 'type_name': '🎬 打脸虐渣'},
|
||||
{'type_id': '豪门恩怨', 'type_name': '🎬 豪门恩怨'},
|
||||
{'type_id': '神豪', 'type_name': '🎬 神豪'},
|
||||
{'type_id': '马甲', 'type_name': '🎬 马甲'},
|
||||
{'type_id': '都市日常', 'type_name': '🎬 都市日常'},
|
||||
{'type_id': '战神归来', 'type_name': '🎬 战神归来'},
|
||||
{'type_id': '小人物', 'type_name': '🎬 小人物'},
|
||||
{'type_id': '女性成长', 'type_name': '🎬 女性成长'},
|
||||
{'type_id': '大女主', 'type_name': '🎬 大女主'},
|
||||
{'type_id': '穿越', 'type_name': '🎬 穿越'},
|
||||
{'type_id': '都市修仙', 'type_name': '🎬 都市修仙'},
|
||||
{'type_id': '强者回归', 'type_name': '🎬 强者回归'},
|
||||
{'type_id': '亲情', 'type_name': '🎬 亲情'},
|
||||
{'type_id': '古装', 'type_name': '🎬 古装'},
|
||||
{'type_id': '重生', 'type_name': '🎬 重生'},
|
||||
{'type_id': '闪婚', 'type_name': '🎬 闪婚'},
|
||||
{'type_id': '赘婿逆袭', 'type_name': '🎬 赘婿逆袭'},
|
||||
{'type_id': '虐恋', 'type_name': '🎬 虐恋'},
|
||||
{'type_id': '追妻', 'type_name': '🎬 追妻'},
|
||||
{'type_id': '天下无敌', 'type_name': '🎬 天下无敌'},
|
||||
{'type_id': '家庭伦理', 'type_name': '🎬 家庭伦理'},
|
||||
{'type_id': '萌宝', 'type_name': '🎬 萌宝'},
|
||||
{'type_id': '古风权谋', 'type_name': '🎬 古风权谋'},
|
||||
{'type_id': '职场', 'type_name': '🎬 职场'},
|
||||
{'type_id': '奇幻脑洞', 'type_name': '🎬 奇幻脑洞'},
|
||||
{'type_id': '异能', 'type_name': '🎬 异能'},
|
||||
{'type_id': '无敌神医', 'type_name': '🎬 无敌神医'},
|
||||
{'type_id': '古风言情', 'type_name': '🎬 古风言情'},
|
||||
{'type_id': '传承觉醒', 'type_name': '🎬 传承觉醒'},
|
||||
{'type_id': '现言甜宠', 'type_name': '🎬 现言甜宠'},
|
||||
{'type_id': '奇幻爱情', 'type_name': '🎬 奇幻爱情'},
|
||||
{'type_id': '乡村', 'type_name': '🎬 乡村'},
|
||||
{'type_id': '历史古代', 'type_name': '🎬 历史古代'},
|
||||
{'type_id': '王妃', 'type_name': '🎬 王妃'},
|
||||
{'type_id': '高手下山', 'type_name': '🎬 高手下山'},
|
||||
{'type_id': '娱乐圈', 'type_name': '🎬 娱乐圈'},
|
||||
{'type_id': '强强联合', 'type_name': '🎬 强强联合'},
|
||||
{'type_id': '破镜重圆', 'type_name': '🎬 破镜重圆'},
|
||||
{'type_id': '暗恋成真', 'type_name': '🎬 暗恋成真'},
|
||||
{'type_id': '民国', 'type_name': '🎬 民国'},
|
||||
{'type_id': '欢喜冤家', 'type_name': '🎬 欢喜冤家'},
|
||||
{'type_id': '系统', 'type_name': '🎬 系统'},
|
||||
{'type_id': '真假千金', 'type_name': '🎬 真假千金'},
|
||||
{'type_id': '龙王', 'type_name': '🎬 龙王'},
|
||||
{'type_id': '校园', 'type_name': '🎬 校园'},
|
||||
{'type_id': '穿书', 'type_name': '🎬 穿书'},
|
||||
{'type_id': '女帝', 'type_name': '🎬 女帝'},
|
||||
{'type_id': '团宠', 'type_name': '🎬 团宠'},
|
||||
{'type_id': '年代爱情', 'type_name': '🎬 年代爱情'},
|
||||
{'type_id': '玄幻仙侠', 'type_name': '🎬 玄幻仙侠'},
|
||||
{'type_id': '青梅竹马', 'type_name': '🎬 青梅竹马'},
|
||||
{'type_id': '悬疑推理', 'type_name': '🎬 悬疑推理'},
|
||||
{'type_id': '皇后', 'type_name': '🎬 皇后'},
|
||||
{'type_id': '替身', 'type_name': '🎬 替身'},
|
||||
{'type_id': '大叔', 'type_name': '🎬 大叔'},
|
||||
{'type_id': '喜剧', 'type_name': '🎬 喜剧'},
|
||||
{'type_id': '剧情', 'type_name': '🎬 剧情'}]}
|
||||
return result
|
||||
|
||||
def homeVideoContent(self):
|
||||
return []
|
||||
|
||||
def categoryContent(self, tid, pg, filter, extend):
|
||||
params = {
|
||||
'classname': tid,
|
||||
'offset': str((int(pg) - 1)),
|
||||
}
|
||||
# 更新请求路径为 /duanju/api.php
|
||||
data = self.fetch(f'{self.ahost}/duanju/api.php', params=params, headers=self.headers).json()
|
||||
videos = []
|
||||
for k in data['data']:
|
||||
videos.append({
|
||||
'vod_id': k.get('book_id'),
|
||||
'vod_name': k.get('title'),
|
||||
'vod_pic': k.get('cover'),
|
||||
'vod_year': k.get('score'),
|
||||
'vod_remarks': f"{k.get('sub_title')}|{k.get('episode_cnt')}"
|
||||
})
|
||||
result = {}
|
||||
result['list'] = videos
|
||||
result['page'] = pg
|
||||
result['pagecount'] = 9999
|
||||
result['limit'] = 90
|
||||
result['total'] = 999999
|
||||
return result
|
||||
|
||||
def detailContent(self, ids):
|
||||
# 更新请求路径为 /duanju/api.php
|
||||
v = self.fetch(f'{self.ahost}/duanju/api.php', params={'book_id': ids[0]}, headers=self.headers).json()
|
||||
vod = {
|
||||
'vod_id': ids[0],
|
||||
'vod_name': v.get('title'),
|
||||
'type_name': v.get('category'),
|
||||
'vod_year': v.get('time'),
|
||||
'vod_remarks': v.get('duration'),
|
||||
'vod_content': v.get('desc'),
|
||||
'vod_play_from': '爱看短剧',
|
||||
'vod_play_url': '#'.join([f"{i['title']}${i['video_id']}" for i in v['data']])
|
||||
}
|
||||
return {'list': [vod]}
|
||||
|
||||
def searchContent(self, key, quick, pg="1"):
|
||||
return self.categoryContent(key, pg, True, {})
|
||||
|
||||
def playerContent(self, flag, id, vipFlags):
|
||||
# 更新请求路径为 /duanju/api.php
|
||||
data = self.fetch(f'{self.ahost}/duanju/api.php', params={'video_id': id}, headers=self.headers).json()
|
||||
return {'parse': 0, 'url': data['data']['url'], 'header': self.headers}
|
||||
|
||||
def localProxy(self, param):
|
||||
pass
|
||||
@@ -0,0 +1,166 @@
|
||||
import 'assets://js/lib/crypto-js.js';
|
||||
const [HOST, KEY, USER_AGENT] = [
|
||||
"https://www.hkybqufgh.com",
|
||||
"cb808529bae6b6be45ecfab29a4889bc",
|
||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36"
|
||||
];
|
||||
let currentHost = '';
|
||||
const guid = () => 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => ((c === 'x' ? Math.random() * 16 | 0 : Math.random() * 16 | 0 & 0x3 | 0x8)).toString(16));
|
||||
const md5 = s => CryptoJS.MD5(s).toString();
|
||||
const sha1 = s => CryptoJS.SHA1(s).toString();
|
||||
const toQueryString = obj => Object.keys(obj).filter(k => obj[k] != null && obj[k] !== '').map(k => `${k}=${obj[k]}`).join('&');
|
||||
const getHeaders = (params = {}) => {
|
||||
const t = Date.now().toString();
|
||||
const sign = sha1(md5(toQueryString({ ...params, key: KEY, t })));
|
||||
return {
|
||||
'User-Agent': USER_AGENT,
|
||||
'Accept': 'application/json, text/plain, */*',
|
||||
'sign': sign,
|
||||
't': t,
|
||||
'deviceid': guid()
|
||||
};
|
||||
};
|
||||
|
||||
const normalizeFieldName = k => {
|
||||
const l = k.toLowerCase();
|
||||
if (l.startsWith('vod') && l.length > 3) return 'vod_' + l.slice(3);
|
||||
if (l.startsWith('type') && l.length > 4) return 'type_' + l.slice(4);
|
||||
return l;
|
||||
};
|
||||
|
||||
const normalizeVodList = list => (list || []).map(item => {
|
||||
const res = {};
|
||||
for (const [k, v] of Object.entries(item || {})) if (v != null) res[normalizeFieldName(k)] = v;
|
||||
return res;
|
||||
});
|
||||
|
||||
async function reqSafe(url, options = {}) {
|
||||
try {
|
||||
const res = await req(url, options);
|
||||
return JSON.parse(res.content);
|
||||
} catch (e) {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
async function init() {
|
||||
currentHost = HOST;
|
||||
return true;
|
||||
}
|
||||
|
||||
async function home() {
|
||||
const [cRes, fRes] = await Promise.all([
|
||||
reqSafe(`${currentHost}/api/mw-movie/anonymous/get/filer/type`, { headers: getHeaders() }),
|
||||
reqSafe(`${currentHost}/api/mw-movie/anonymous/v1/get/filer/list`, { headers: getHeaders() })
|
||||
]);
|
||||
|
||||
const classes = (cRes.data || []).map(k => ({ type_name: k.typeName, type_id: k.typeId.toString() }));
|
||||
const fData = fRes.data || {};
|
||||
const baseSort = [{ n: "最近更新", v: "2" }, { n: "人气高低", v: "3" }, { n: "评分高低", v: "4" }];
|
||||
const filters = {};
|
||||
for (const [tid, d] of Object.entries(fData)) {
|
||||
const currentSortValues = tid === '1' ? baseSort.slice(1) : baseSort;
|
||||
const arr = [
|
||||
{ key: "type", name: "类型", value: (d.typeList || []).map(i => ({ n: i.itemText, v: i.itemValue })) }
|
||||
];
|
||||
if (d.plotList?.length) arr.push({ key: "v_class", name: "剧情", value: (d.plotList || []).map(i => ({ n: i.itemText, v: i.itemText })) });
|
||||
arr.push(
|
||||
{ key: "area", name: "地区", value: (d.districtList || []).map(i => ({ n: i.itemText, v: i.itemText })) },
|
||||
{ key: "year", name: "年份", value: (d.yearList || []).map(i => ({ n: i.itemText, v: i.itemText })) },
|
||||
{ key: "lang", name: "语言", value: (d.languageList || []).map(i => ({ n: i.itemText, v: i.itemText })) },
|
||||
{ key: "sort", name: "排序", value: currentSortValues }
|
||||
);
|
||||
filters[tid] = arr;
|
||||
}
|
||||
return JSON.stringify({ class: classes, filters });
|
||||
}
|
||||
|
||||
async function homeVod() {
|
||||
const [r1, r2] = await Promise.all([
|
||||
reqSafe(`${currentHost}/api/mw-movie/anonymous/v1/home/all/list`, { headers: getHeaders() }),
|
||||
reqSafe(`${currentHost}/api/mw-movie/anonymous/home/hotSearch`, { headers: getHeaders() })
|
||||
]);
|
||||
let list = [];
|
||||
const data1 = r1.data || {};
|
||||
for (const k in data1) if (data1[k]?.list) list.push(...data1[k].list);
|
||||
if (Array.isArray(r2.data)) list.push(...r2.data);
|
||||
return JSON.stringify({ list: normalizeVodList(list) });
|
||||
}
|
||||
|
||||
async function category(tid, pg, _, ext = {}) {
|
||||
const params = {
|
||||
area: ext.area || '',
|
||||
filterStatus: "1",
|
||||
lang: ext.lang || '',
|
||||
pageNum: pg,
|
||||
pageSize: "30",
|
||||
sort: ext.sort || '1',
|
||||
sortBy: "1",
|
||||
type: ext.type || '',
|
||||
type1: tid,
|
||||
v_class: ext.v_class || '',
|
||||
year: ext.year || ''
|
||||
};
|
||||
|
||||
const url = `${currentHost}/api/mw-movie/anonymous/video/list?${toQueryString(params)}`;
|
||||
const res = await reqSafe(url, { headers: getHeaders(params) });
|
||||
const vodList = normalizeVodList(res.data?.list || []);
|
||||
return JSON.stringify({
|
||||
list: vodList,
|
||||
page: +pg,
|
||||
pagecount: 9999,
|
||||
limit: 90,
|
||||
total: 999999
|
||||
});
|
||||
}
|
||||
|
||||
async function detail(id) {
|
||||
const res = await reqSafe(`${currentHost}/api/mw-movie/anonymous/video/detail?id=${id}`, {
|
||||
headers: getHeaders({ id })
|
||||
});
|
||||
const vod = normalizeVodList([res.data])[0];
|
||||
if (!vod) return JSON.stringify({ list: [{ vod_id: id, vod_name: '加载失败', vod_play_url: '' }] });
|
||||
vod.vod_play_from = '界影视';
|
||||
const eps = vod.episodelist || [];
|
||||
if (eps.length === 0) {
|
||||
vod.vod_play_url = `${vod.vod_name}$${id}-1`;
|
||||
} else if (eps.length === 1) {
|
||||
vod.vod_play_url = `${vod.vod_name}$${id}-${eps[0].nid}`;
|
||||
} else {
|
||||
vod.vod_play_url = eps.map(ep => {
|
||||
const name = ep.name?.trim() || `第${ep.nid}集`;
|
||||
return `${name}$${id}-${ep.nid}`;
|
||||
}).join('#');
|
||||
}
|
||||
|
||||
async function play(_, id) {
|
||||
const [vid, nid] = id.split('-');
|
||||
const url = `${currentHost}/api/mw-movie/anonymous/v2/video/episode/url?clientType=1&id=${vid}&nid=${nid}`;
|
||||
const res = await reqSafe(url, { headers: getHeaders({ clientType: '1', id: vid, nid: nid }) });
|
||||
const urls = (res.data?.list || []).flatMap(item => [item.resolutionName, item.url]);
|
||||
return JSON.stringify({
|
||||
parse: 0,
|
||||
url: urls,
|
||||
header: {
|
||||
'User-Agent': USER_AGENT,
|
||||
'sec-ch-ua-platform': '"Windows"',
|
||||
'DNT': '1',
|
||||
'sec-ch-ua': '"Not/A)Brand";v="8", "Chromium";v="131", "Google Chrome";v="131"',
|
||||
'sec-ch-ua-mobile': '?0',
|
||||
'Origin': currentHost,
|
||||
'Referer': currentHost + '/'
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async function search(wd, _, pg = "1") {
|
||||
const params = { keyword: wd, pageNum: pg, pageSize: "8", sourceCode: "1" };
|
||||
const url = `${currentHost}/api/mw-movie/anonymous/video/searchByWord?${toQueryString(params)}`;
|
||||
const res = await reqSafe(url, { headers: getHeaders(params) });
|
||||
const list = normalizeVodList(res.data?.result?.list || []);
|
||||
return JSON.stringify({ list, page: +pg });
|
||||
}
|
||||
|
||||
export function __jsEvalReturn() {
|
||||
return { init, home, homeVod, category, detail, play, proxy: null, search };
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
{
|
||||
"规则名": "短剧屋",
|
||||
"规则作者": "",
|
||||
"请求头参数": "手机",
|
||||
"网页编码格式": "UTF-8",
|
||||
"图片是否需要代理": "0",
|
||||
"是否开启获取首页数据": "1",
|
||||
"首页推荐链接": "http://www.metaysw.com",
|
||||
"首页列表数组规则": "body&&.vod-vodlist",
|
||||
"首页片单列表数组规则": "li",
|
||||
"首页片单是否Jsoup写法": "1",
|
||||
"分类起始页码": "1",
|
||||
"分类链接": "http://www.metaysw.com/type/{cateId}-{catePg}.html",
|
||||
"分类名称": "短剧",
|
||||
"分类名称替换词": "lianxuju",
|
||||
"筛选数据": {},
|
||||
//"筛选数据": "ext",
|
||||
//{cateId}
|
||||
"筛选子分类名称": "",
|
||||
"筛选子分类替换词": "",
|
||||
//{class}
|
||||
"筛选类型名称": "",
|
||||
"筛选类型替换词": "*",
|
||||
//{area}
|
||||
"筛选地区名称": "",
|
||||
"筛选地区替换词": "*",
|
||||
//{year}
|
||||
"筛选年份名称": "",
|
||||
"筛选年份替换词": "*",
|
||||
//{lang}
|
||||
"筛选语言名称": "",
|
||||
"筛选语言替换词": "*",
|
||||
//{by}
|
||||
"筛选排序名称": "时间&人气&评分",
|
||||
"筛选排序替换词": "time&hits&score",
|
||||
"分类截取模式": "1",
|
||||
"分类列表数组规则": ".vod-vodlist&&li",
|
||||
"分类片单是否Jsoup写法": "1",
|
||||
"分类片单标题": ".vod-vodlist__title&&Text",
|
||||
"分类片单链接": "a&&href",
|
||||
"分类片单图片": ".lazyload&&data-original",
|
||||
"分类片单副标题": ".pic-text&&Text",
|
||||
"分类片单链接加前缀": "http://www.metaysw.com",
|
||||
"分类片单链接加后缀": "",
|
||||
"搜索请求头参数": "User-Agent$手机",
|
||||
"搜索链接": "http://www.metaysw.com/search/page/{SearchPg}/wd/{wd}.html",
|
||||
"POST请求数据": "",
|
||||
"搜索截取模式": "1",
|
||||
"搜索列表数组规则": ".vod-vodlist&&li",
|
||||
"搜索片单是否Jsoup写法": "1",
|
||||
"搜索片单图片": ".lazyload&&data-original",
|
||||
"搜索片单标题": ".vod-vodlist__title&&Text",
|
||||
"搜索片单链接": "a&&href",
|
||||
"搜索片单副标题": ".pic-text&&Text",
|
||||
"搜索片单链接加前缀": "http://www.metaysw.com",
|
||||
"搜索片单链接加后缀": "",
|
||||
"链接是否直接播放": "0",
|
||||
"直接播放链接加前缀": "https://live.52sf.ga/huya/",
|
||||
"直接播放链接加后缀": "#isVideo=true#",
|
||||
"直接播放直链视频请求头": "authority$ku.peizq.online#Referer$https://play.peizq.online",
|
||||
"详情是否Jsoup写法": "1",
|
||||
"类型详情": "",
|
||||
"年代详情": "",
|
||||
"地区详情": "",
|
||||
"演员详情": ".vod-content__detail&&p,2&&Text!主演:",
|
||||
"简介详情": "",
|
||||
"线路列表数组规则": ".dropdown-menu&&li",
|
||||
"线路标题": "a&&Text",
|
||||
"播放列表数组规则": "body&&.vod-content__playlist",
|
||||
"选集列表数组规则": "li",
|
||||
"选集标题链接是否Jsoup写法": "1",
|
||||
"选集标题": "a&&Text",
|
||||
"选集链接": "a&&href",
|
||||
"是否反转选集序列": "0",
|
||||
"选集链接加前缀": "http://www.metaysw.com",
|
||||
"选集链接加后缀": "",
|
||||
"分析MacPlayer": "0",
|
||||
"是否开启手动嗅探": "0",
|
||||
"手动嗅探视频链接关键词": ".mp4#.m3u8#.flv#video/tos",
|
||||
"手动嗅探视频链接过滤词": ".html#=http"
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"分类": "短剧$duanju#电影$dianying#电视剧$dianshiju#动漫$dongman#综艺$zongyi",
|
||||
"分类url": "https://www.duanjuwang.cc/vodtype/{cateId}/page/{catePg}.html"
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
{
|
||||
"作者": "年少轻狂",
|
||||
"站名": "秀儿影视",
|
||||
"请求头": "User-Agent$MOBILE_UA",
|
||||
"编码": "UTF-8",
|
||||
"图片代理": "0",
|
||||
"主页url": "https://www.xiuer.pro/",
|
||||
"首页": "120",
|
||||
"起始页": "1",
|
||||
"分类url": "https://www.xiuer.pro/show/{cateId}/by/{by}/class/{class}/page/{catePg}/year/{year}/;;mrcd0",
|
||||
"分类":"电影$dianying#剧集$dianshiju#综艺$zongyi#动漫$dongman#短剧$duanju",
|
||||
"二次截取": "module-items\">&&id=\"page[替换:module-footer>>module-item\">]",
|
||||
"数组": "item-pic\"&&module-item\">",
|
||||
"标题": "title=\"&&\"",
|
||||
"图片": "data-src=\"&&\"",
|
||||
"副标题": "module-item-text\">&&<",
|
||||
"链接": "href=\"&&\"",
|
||||
"影片年代": "year/*>&&</a>",
|
||||
"影片地区": "area/*>&&</div>",
|
||||
"影片类型": "class/*>&&</div>",
|
||||
"状态": "集数:&&</div>",
|
||||
"导演": "导演:&&</div>",
|
||||
"主演": "主演:&&</div>",
|
||||
"简介": "👶+display: none;\">&&</div>",
|
||||
"线路二次截取": "",
|
||||
"线路数组": "module-tab-item tab-item&&/small>",
|
||||
"线路标题": "👶+>&&</span>+【共+<small>&&<+集】",
|
||||
"播放二次截取": "",
|
||||
"播放数组": "module-blocklist\">&&</div>",
|
||||
"播放列表": "<a&&/a>",
|
||||
"播放标题": ">&&</span",
|
||||
"播放链接": "href=\"&&\"",
|
||||
"解析": "",
|
||||
"直接播放": "0",
|
||||
"播放请求头": "",
|
||||
"嗅探词": ".mp4#.m3u8",
|
||||
"过滤词": "",
|
||||
"跳转播放链接": "var player_*url\":\"&&\"",
|
||||
"跳转解析": "",
|
||||
"搜索请求头": "User-Agent$MOBILE_UA",
|
||||
"搜索url": "https://www.xiuer.pro/vod/search/page/{pg}/wd/{wd}/",
|
||||
"搜索模式": "1",
|
||||
"搜索后缀": "",
|
||||
"搜索二次截取": "",
|
||||
"搜索数组": "module-item-cover\">&&</strong>",
|
||||
"搜索标题": "title=\"&&\"",
|
||||
"搜索图片": "data-src=\"&&\"",
|
||||
"搜索副标题": "title=\"*>&&</a",
|
||||
"搜索链接": "href=\"&&\"",
|
||||
"筛选": "1",
|
||||
"类型": "",
|
||||
"剧情": "",
|
||||
"剧情值": "*",
|
||||
"地区": "",
|
||||
"地区值": "*",
|
||||
"年份": "",
|
||||
"年份值": "*",
|
||||
"语言": "",
|
||||
"语言值": "*",
|
||||
"字母": "A&B&C&D&E&F&G&H&I&J&K&L&M&N&O&P&Q&R&S&T&U&V&W&X&Y&Z&0-9",
|
||||
"字母值": "*",
|
||||
"排序": "时间&人气&评分",
|
||||
"排序值": "time&hits&score"
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
dmFyIHJ1bGUgPSB7CiAgICB0aXRsZTogJ+enjeWtkOmfs+S5kFvlkKxdJywKICAgIGhvc3Q6ICdodHRwczovL3d3dy56ejEyMy5jb20nLAogICAgaG9tZVVybDogJy9saXN0L21zem0uaHRtP3BhZ2U9MScsCiAgICB1cmw6ICcvZnljbGFzcy5odG0/cGFnZT1meXBhZ2UnLAogICAgc2VhcmNoYWJsZTogMiwKICAgIHF1aWNrU2VhcmNoOiAwLAogICAgaGVhZGVyczogewogICAgICAgICdVc2VyLUFnZW50JzogJ01PQklMRV9VQScsCiAgICAgICAgJ3JlZmVyZXInOiAnaHR0cHM6Ly93d3cuenoxMjMuY29tLycsCiAgICB9LAogICAgY2xhc3NfcGFyc2U6ICcuYXNpZGUtbWVudS1saXN0LmNoYW5uZWwmJltocmVmKj1saXN0XTthJiZUZXh0O2EmJmhyZWY7LihsaXN0LiopLmh0bScsCiAgICBwbGF5X3BhcnNlOiB0cnVlLAogICAgbGF6eTogJGpzLnRvU3RyaW5nKCgpID0+IHsKICAgICAgICBpbnB1dCA9IGlucHV0LnJlcGxhY2UoL3BsYXlcLyhcdyspXC5odG0vLCAnYWpheC8/YWN0PXNvbmdpbmZvJmlkPSQxJmxhbmc9Jyk7CiAgICAgICAgbG9nKGlucHV0KTsKICAgICAgICBsZXQgbXAzID0gSlNPTi5wYXJzZShyZXF1ZXN0KGlucHV0KSkuZGF0YS5tcDM7CiAgICAgICAgaW5wdXQgPSB7cGFyc2U6IDAsIHVybDogbXAzLCBoZWFkZXI6IHJ1bGUuaGVhZGVyc307CiAgICB9KSwKICAgIGxpbWl0OiA2LAogICAgLy8gIOWbvueJh+adpea6kDonQFJlZmVyZXI9aHR0cHM6Ly93d3cuenoxMjMuY29tLycsCiAgICDmjqjojZA6ICIqIiwKICAgIOS4gOe6pzogJy5tb2JpbGUtbGlzdCYmLm1vYmlsZS1saXN0LWl0ZW07LnNvbmduYW1lJiZUZXh0Oy5sYXp5bG9hZCYmZGF0YS1zcmM7LmF1dGhvcm5hbWUmJlRleHQ7YSYmaHJlZicsCiAgICDkuoznuqc6ICcqJywKICAgIC8vIHNlYXJjaFVybDonL3NlYXJjaC8/a2V5PSoqJnBhZ2U9ZnlwYWdlJywKICAgIC8vIOaQnOe0ojonKicsCiAgICBzZWFyY2hVcmw6ICcvYWpheC8/YWN0PXNlYXJjaCZrZXk9KiombGFuZz0nLAogICAgZGV0YWlsVXJsOiAnL3BsYXkvZnlpZC5odG1sJywKICAgIOaQnOe0ojogJ2pzb246ZGF0YTttbmFtZTtwaWM7c25hbWU7aWQnLAp9
|
||||
@@ -0,0 +1 @@
|
||||
dmFyIHJ1bGUgPSB7CiAgICDnsbvlnos6ICflkKzkuaYnLAogICAgdGl0bGU6ICfphbfmiJHlkKzkuaZb5ZCsXScsCiAgICBob3N0OiAnaHR0cDovL3RpbmdzaHUua3V3by5jbicsCiAgICB1cmw6ICcvdjIvYXBpL3NlYXJjaC9maWx0ZXIvYWxidW1zP2NsYXNzaWZ5SWQ9ZnlmaWx0ZXImbm90cmFjZT0wJnNvdXJjZT1rd3BsYXllcl9hcl85LjEuOC4xX3R2aXZvLmFwayZwbGF0Zm9ybT0xJmt3ZWV4VmVyc2lvbj0xLjEuNSZ1aWQ9MjUxMTQ4MjAwNiZzb3J0VHlwZT1wbGF5Q250JmxvZ2luVWlkPTU0MDMzOTUxNiZia3NvdXJjZT1rd2Jvb2tfYXJfOS4xLjguMV90dml2by5hcGsmcm49MjEmY2F0ZWdvcnlJZD1meWNsYXNzJnBuPWZ5cGFnZScsCiAgICBzZWFyY2hVcmw6ICdodHRwOi8vc2VhcmNoLmt1d28uY24vci5zP2NsaWVudD1rdCZhbGw9KiomZnQ9YWxidW0mbmV3c2VhcmNoPTEmaXRlbXNldD13ZWJfMjAxMyZjbHVzdGVyPTAmcG49KGZ5cGFnZS0xKSZybj0yMSZyZm9ybWF0PWpzb24mZW5jb2Rpbmc9dXRmOCZzaG93X2NvcHlyaWdodF9vZmY9MSZ2aXB2ZXI9TVVTSUNfOC4wLjMuMF9CQ1M3NSZzaG93X3Nlcmllc19saXN0ZW49MSZ2ZXJzaW9uPTkuMS44LjEnLAogICAgc2VhcmNoYWJsZTogMiwKICAgIHF1aWNrU2VhcmNoOiAwLAogICAgZmlsdGVyYWJsZTogMSwKICAgIGZpbHRlcl91cmw6ICJ7e2ZsLmNsYXNzIG9yICc0NCd9fSIsCiAgICBmaWx0ZXI6ICdINHNJQUFBQUFBQUFBNVdWMjA3aVVCU0czNlhYWGtCYkVMeWV0NWg0WVl4WDQzaGpacEtKTVVFNWlEQVVjQkJGSEdSRURoNEtGWlFBdGZSbHV2YmVmWXZaQXZzQWswemlUWlB5OVYvN1g0ZTlPRkJVWmVQemdmSmw1NGV5b1d6dmJ1M3ZLMnZLM3RiWEhmcUtuMjJvWmVuNzk2M2RienV6Ny9iZWZ6WVNNTGFoZVVLZjc1RCtwT3ZLNGRxY0lyUGxUZXVlWGFGUFJpT2M0bnVYRERPb05zVDNrd1VOcVp6NmNRZEd4OTVibmZSZW1GWlEzQzdTRS9GakRXVmlUTHZPS1VVb1BpQ2RHSW9uRnpRWWpncHg5Z202UStoZVFYckk4SHBBcVBOM250MVlVcXNCS2JqelROb3BNRzVJOFlMaG9DWnlQbjdDNVNJeU9yaVFZcjVEUW15a0lOK0hWTldiWkpudnNEQm1XS3NuNjBGUmtkOW42TEtKNm4rZ2FqS3RpSXpLSjJDMm9KQVR0c0pVdTNtNHVhYUVQdDdYNmdnYUZpcGIzb1QxUmxWRitlR3REbGJSY3dvTHBra0ZnUFFsZnN6aVZwNHpNUkNrbC9ER0xiaHJRN0xEdzBxVnQvTHc2d2dLYVRJdGNoeVVJMFBTSXBrQml4d1FQU1Z1elJzNTBEcm1wd29kTGxtUXEzdmpVODZrYnViT0lkK1lwOHU3S1lXOVBmSXZTeWd0RXBYY21oVnZGT01nSkxVeGk0MG1HdHh5RnBiUG8zWkVEcXJrQmNkTi82S3o0a1c2THpOQU8weUhsK0dvc0lQN2Q2Um56aXZNRHBacm14d2dhMFNHU2M2RVlmLyt5VDkzeVpRWFNCV0d5ZXNydGwrSUlkaC9peGNNYVVLTG5DNmN0dmtWazNKQi9ZY2xJaXFPS2xtWnZHY3dtMkZ0L2NORGpESmwvMmFBbXpWVTdiT0NoYVNiR291aGl6YUpIU0h6SjhmU2pLZXJubk9OWFJ0S3p3eEwyd3ZvUGIrdWM1MHVydysvWVhBZzNmM2NGWFJ2b2RpQmRJYmxwNnVTSDZ0SXJBWW4wbkRqU1k4bTRvMExBZ29qMmlkY2VxVllNTkdndVlyMHByakQxazFRaXdSV09GMVdKRmZnanYvQjUwbXhyVlJkUktkYkNpVnVsdFc2Tk9vSkZ6ODJsNHlyZW5UUnp2REgvMnNXaTNmc29qTlRHaEU5SXBWNDlnbHBOMGpQRmx4YjRVdTdtM0poMmE4OGVFNmR1STRVWDR0S1Y5RE9RM0pFOWRMQTZ4RjFsdFBoWHh5UzBTTkFCd0FBJywKICAgIHRpbWVvdXQ6IDUwMDAsCiAgICBjbGFzc19uYW1lOiAn5pyJ5aOw5bCP6K+0Jumfs+S5kCbnm7jlo7Dor4TkuaYm5b2x6KeG5Y6f5aOwJywKICAgIGNsYXNzX3VybDogJzImMzcmNSY2MicsCiAgICBwbGF5X3BhcnNlOiB0cnVlLAogICAgbGF6eTogJGpzLnRvU3RyaW5nKCgpID0+IHsKICAgICAgICBsZXQgaHRtbCA9IHJlcXVlc3QoaW5wdXQpOwogICAgICAgIGxldCB1cmwgPSBKU09OLnBhcnNlKGh0bWwpLmRhdGEudXJsOwogICAgICAgIGlucHV0ID0ge3VybDogdXJsLCBwYXJzZTogMH07CiAgICB9KSwKICAgIGRvdWJsZTogdHJ1ZSwKICAgIOS4gOe6pzogJGpzLnRvU3RyaW5nKCgpID0+IHsKICAgICAgICBsZXQgZCA9IFtdOwogICAgICAgIGxldCBodG1sID0gcmVxdWVzdChpbnB1dCk7CiAgICAgICAgbGV0IGRhdGEgPSBKU09OLnBhcnNlKGh0bWwpLmRhdGEuZGF0YTsKICAgICAgICBkYXRhLmZvckVhY2goaXQgPT4gewogICAgICAgICAgICBsZXQgaWQgPSAnaHR0cDovL3NlYXJjaC5rdXdvLmNuL3Iucz9zdHlwZT1hbGJ1bWluZm8mdXNlcj04ZDM3OGQ3MnF3MjhmNWY0JnVpZD0yNTExNTUyMDA2JmxvZ2luVWlkPTU0MDEyOTUxNiZsb2dpblNpZD05NTg0Njc5NjAmcHJvZD1rd3BsYXllcl9hcl85LjEuOC4xJmJrcHJvZD1rd2Jvb2tfYXJfOS4xLjguMSZzb3VyY2U9a3dwbGF5ZXJfYXJfOS4xLjguMV90dml2by5hcGsmYmtzb3VyY2U9a3dib29rX2FyXzkuMS44LjFfdHZpdm8uYXBrJmNvcnA9a3V3byZhbGJ1bWlkPScgKyBpdC5hbGJ1bUlkICsgJyZwbj0wJnJuPTUwMDAmc2hvd19jb3B5cmlnaHRfb2ZmPTEmdmlwdmVyPU1VU0lDXzguMi4wLjBfQkNTMTcmbW9iaT0xJmlza3dib29rPTEnOwogICAgICAgICAgICBkLnB1c2goewogICAgICAgICAgICAgICAgdXJsOiBpZCwKICAgICAgICAgICAgICAgIHRpdGxlOiBpdC5hbGJ1bU5hbWUsCiAgICAgICAgICAgICAgICBpbWc6IGl0LmNvdmVySW1nLAogICAgICAgICAgICAgICAgZGVzYzogaXQudGl0bGUsCiAgICAgICAgICAgIH0pOwogICAgICAgIH0pOwogICAgICAgIHNldFJlc3VsdChkKTsKICAgIH0pLAogICAg5LqM57qnOiAkanMudG9TdHJpbmcoKCkgPT4gewogICAgICAgIGxldCB1cmxzID0gW107CiAgICAgICAgbGV0IGh0bWwgPSByZXF1ZXN0KGlucHV0KTsKICAgICAgICBsZXQgZGF0YSA9IEpTT04ucGFyc2UoaHRtbCkubXVzaWNsaXN0OwogICAgICAgIGRhdGEuZm9yRWFjaChpdCA9PiB7CiAgICAgICAgICAgIHVybHMucHVzaChpdC5uYW1lICsgJyQnICsgJ2h0dHA6Ly9tb2JpLmt1d28uY24vbW9iaS5zP2Y9d2ViJnNvdXJjZT1rd3BsYXllcmhkX2FyXzQuMy4wLjhfdGlhbmJhb19UMUFfcWlydWkuYXBrJnR5cGU9Y29udmVydF91cmxfd2l0aF9zaWduJnJpZD0nICsgaXQubXVzaWNyaWQgKyAnJmJyPTMyMGttcDMnKTsKICAgICAgICB9KTsKICAgICAgICBWT0QgPSB7CiAgICAgICAgICAgIHZvZF9wbGF5X2Zyb206ICfnkIPnkIPllaYnLAogICAgICAgICAgICB2b2RfcGxheV91cmw6IHVybHMuam9pbignIycpCiAgICAgICAgfTsKICAgIH0pLAogICAg5pCc57SiOiAkanMudG9TdHJpbmcoKCkgPT4gewogICAgICAgIGxldCBkID0gW107CiAgICAgICAgLy8gbG9nKGlucHV0KTsKICAgICAgICBsZXQgaHRtbCA9IHJlcXVlc3QoaW5wdXQpOwogICAgICAgIGxldCBkYXRhID0gSlNPTjUucGFyc2UoaHRtbCkuYWxidW1saXN0OwogICAgICAgIC8vIGxvZyhkYXRhKTsKICAgICAgICBkYXRhLmZvckVhY2goaXQgPT4gewogICAgICAgICAgICBsZXQgaWQgPSAnaHR0cDovL3NlYXJjaC5rdXdvLmNuL3Iucz9zdHlwZT1hbGJ1bWluZm8mdXNlcj04ZDM3OGQ3MnF3MjhmNWY0JnVpZD0yNTExNTUyMDA2JmxvZ2luVWlkPTU0MDEyOTUxNiZsb2dpblNpZD05NTg0Njc5NjAmcHJvZD1rd3BsYXllcl9hcl85LjEuOC4xJmJrcHJvZD1rd2Jvb2tfYXJfOS4xLjguMSZzb3VyY2U9a3dwbGF5ZXJfYXJfOS4xLjguMV90dml2by5hcGsmYmtzb3VyY2U9a3dib29rX2FyXzkuMS44LjFfdHZpdm8uYXBrJmNvcnA9a3V3byZhbGJ1bWlkPScgKyBpdC5EQ19UQVJHRVRJRCArICcmcG49MCZybj01MDAwJnNob3dfY29weXJpZ2h0X29mZj0xJnZpcHZlcj1NVVNJQ184LjIuMC4wX0JDUzE3Jm1vYmk9MSZpc2t3Ym9vaz0xJzsKICAgICAgICAgICAgZC5wdXNoKHsKICAgICAgICAgICAgICAgIHVybDogaWQsCiAgICAgICAgICAgICAgICB0aXRsZTogaXQubmFtZSwKICAgICAgICAgICAgICAgIGltZzogaXQuaW1nLAogICAgICAgICAgICB9KTsKICAgICAgICB9KTsKICAgICAgICBzZXRSZXN1bHQoZCk7CiAgICB9KQp9
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"请求头": "User-Agent$MOBILE_UA",
|
||||
"编码": "UTF-8",
|
||||
"分类url": "https://v.aiwule.com/vodshow/{cateId}-{area}-{by}-{class}-{lang}-{letter}---{catePg}---{year}.html",
|
||||
"分类": "电影$20#电视剧$21#动漫$23#综艺$22#短剧$47",
|
||||
"简介": "简介:&&"
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
@header({
|
||||
searchable: 2,
|
||||
filterable: 0,
|
||||
quickSearch: 0,
|
||||
title: '麦田影院',
|
||||
lang: 'ds'
|
||||
})
|
||||
*/
|
||||
|
||||
var rule = {
|
||||
类型: '影视',
|
||||
title: '麦田影院',
|
||||
desc: '源动力出品',
|
||||
host: 'https://www.mtyy1.com',
|
||||
url: '/vodtype/fyclass-fypage.html',
|
||||
searchUrl: '/vodsearch/**----------fypage---.html',
|
||||
searchable: 2,
|
||||
quickSearch: 0,
|
||||
timeout: 5000,
|
||||
play_parse: true,
|
||||
filterable: 0,
|
||||
class_name: '电视剧&电影&综艺&动漫&短剧&纪录片',
|
||||
class_url: '1&2&3&4&5&6',
|
||||
预处理: async () => {
|
||||
return []
|
||||
},
|
||||
推荐: async function (tid, pg, filter, extend) {
|
||||
const { input, pdfa, pdfh, pd } = this;
|
||||
const html = await request(input);
|
||||
const d = [];
|
||||
const data = pdfa(html, '.box-width .public-list-box');
|
||||
|
||||
data.forEach((it) => {
|
||||
d.push({
|
||||
title: pdfh(it, '.public-list-div a&&title'),
|
||||
pic_url: pdfh(it, '.public-list-div img&&data-src'),
|
||||
desc: pdfh(it, '.public-list-div .public-list-prb&&Text'),
|
||||
url: pdfh(it, '.public-list-div a&&href'),
|
||||
})
|
||||
});
|
||||
return setResult(d);
|
||||
},
|
||||
一级: async function (tid, pg, filter, extend) {
|
||||
const { input, pdfa, pdfh, pd } = this;
|
||||
const html = await request(input);
|
||||
const d = [];
|
||||
const data = pdfa(html, '.flex.wrap.border-box.public-r .public-list-box');
|
||||
|
||||
data.forEach((it) => {
|
||||
d.push({
|
||||
title: pdfh(it, '.public-list-button a.time-title&&Text'),
|
||||
pic_url: pdfh(it, '.public-list-bj img&&data-src'),
|
||||
desc: pdfh(it, '.public-list-bj .public-list-prb&&Text'),
|
||||
url: pdfh(it, '.public-list-button a.time-title&&href'),
|
||||
})
|
||||
});
|
||||
return setResult(d);
|
||||
},
|
||||
二级: async function (ids) {
|
||||
const { input, pdfa, pdfh, pd } = this;
|
||||
const html = await request(`${rule.host}${ids[0]}`);
|
||||
const vod = {
|
||||
vod_id: ids[0],
|
||||
vod_name: pdfh(html, '.slide-desc-box .this-desc-title&&Text'),
|
||||
vod_content: pdfh(html, '.slide-desc-box .this-desc .text&&Text'),
|
||||
};
|
||||
|
||||
let playFroms = [];
|
||||
let playUrls = [];
|
||||
|
||||
const playList = pdfa(html, '.vod-detail .anthology-tab .swiper-wrapper a');
|
||||
playList.forEach((it) => {
|
||||
playFroms.push(pdfh(it, 'a:not([strong])&&Text'));
|
||||
});
|
||||
|
||||
const indexList = pdfa(html, '.vod-detail .anthology-list .anthology-list-box');
|
||||
indexList.forEach((lines) => {
|
||||
const tmpUrls = [];
|
||||
const line = pdfa(lines, 'ul li');
|
||||
line.forEach((play) => {
|
||||
const index = pdfh(play, 'a&&Text');
|
||||
const url = pdfh(play, 'a&&href');
|
||||
tmpUrls.push(`${index}$${url}`);
|
||||
});
|
||||
playUrls.push(tmpUrls.join('#'));
|
||||
});
|
||||
|
||||
vod.vod_play_from = playFroms.join('$$$');
|
||||
vod.vod_play_url = playUrls.join('$$$');
|
||||
|
||||
return vod;
|
||||
},
|
||||
搜索: async function (wd, quick, pg) {
|
||||
const { input, pdfa, pdfh, pd } = this;
|
||||
const html = await request(input);
|
||||
const d = [];
|
||||
const data = pdfa(html, '.flex.wrap.border-box.public-r .public-list-box');
|
||||
|
||||
data.forEach((it) => {
|
||||
d.push({
|
||||
title: pdfh(it, '.public-list-button a.time-title&&Text'),
|
||||
pic_url: pdfh(it, '.public-list-bj img&&data-src'),
|
||||
desc: pdfh(it, '.public-list-bj .public-list-prb&&Text'),
|
||||
url: pdfh(it, '.public-list-button a.time-title&&href'),
|
||||
})
|
||||
});
|
||||
return setResult(d);
|
||||
},
|
||||
lazy: async function (flag, id, flags) {
|
||||
const { input, pdfa, pdfh, pd } = this;
|
||||
let url = `${rule.host}${id}`;
|
||||
const html = await request(url);
|
||||
const script = pdfa(html, '.player-top script');
|
||||
const scriptContent = script.filter((e) => e.includes("player_aaaa"))[0];
|
||||
|
||||
const scriptRegex = /var player_aaaa=({[^;]+})/;
|
||||
const match = scriptContent.match(scriptRegex);
|
||||
console.warn(match)
|
||||
if (match && match[1]) {
|
||||
try {
|
||||
const matchStr = match[1];
|
||||
const matchJson = JSON.parse(matchStr);
|
||||
url = matchJson.url;
|
||||
} catch (err) { }
|
||||
};
|
||||
|
||||
if (/m3u8|mp4|flv/.test(url)) {
|
||||
return { parse: 0, url }
|
||||
} else {
|
||||
return { parse: 1, url }
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user