上传文件至「js」

This commit is contained in:
2026-08-15 10:28:06 +02:00
parent e80e63704c
commit 3ad0ce688f
4 changed files with 898 additions and 0 deletions
+469
View File
@@ -0,0 +1,469 @@
import cheerio from 'assets://js/lib/cheerio.min.js';
const appConfig = {
siteName: "伦理专题影片",
siteUrl: "http://yoxayg.com"
};
const UA = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36";
async function init(ext) {
console.log("初始化爬虫:", appConfig.siteName);
}
const classList = [
{ type_id: "1", type_name: "电影" },
{ type_id: "2", type_name: "电视剧" },
{ type_id: "3", type_name: "综艺" },
{ type_id: "4", type_name: "动漫" },
{ type_id: "36", type_name: "短剧" },
{ type_id: "6", type_name: "动作片" },
{ type_id: "7", type_name: "喜剧片" },
{ type_id: "8", type_name: "爱情片" },
{ type_id: "9", type_name: "科幻片" },
{ type_id: "10", type_name: "恐怖片" },
{ type_id: "11", type_name: "剧情片" },
{ type_id: "12", type_name: "战争片" },
{ type_id: "20", type_name: "记录片" },
{ type_id: "34", type_name: "伦理片" },
{ type_id: "13", type_name: "国产剧" },
{ type_id: "14", type_name: "香港剧" },
{ type_id: "15", type_name: "韩国剧" },
{ type_id: "16", type_name: "欧美剧" },
{ type_id: "21", type_name: "台湾剧" },
{ type_id: "22", type_name: "日本剧" },
{ type_id: "23", type_name: "海外剧" },
{ type_id: "24", type_name: "泰国剧" },
{ type_id: "25", type_name: "大陆综艺" },
{ type_id: "26", type_name: "港台综艺" },
{ type_id: "27", type_name: "日韩综艺" },
{ type_id: "28", type_name: "欧美综艺" },
{ type_id: "29", type_name: "国产动漫" },
{ type_id: "30", type_name: "日韩动漫" },
{ type_id: "31", type_name: "欧美动漫" },
{ type_id: "32", type_name: "港台动漫" },
{ type_id: "33", type_name: "海外动漫" }
];
const typeSlugMap = {
"1": "dianying", "2": "dianshiju", "3": "zongyi", "4": "dongman", "6": "dongzuopian",
"7": "xijupian", "8": "aiqingpian", "9": "kehuanpian", "10": "kongbupian", "11": "juqingpian",
"12": "zhanzhengpian", "13": "guochanju", "14": "xianggangju", "15": "hanguoju", "16": "oumeiju",
"20": "jilupian", "21": "taiwanju", "22": "ribenju", "23": "haiwaiju", "24": "taiguoju",
"25": "daluzongyi", "26": "gangtaizongyi", "27": "rihanzongyi", "28": "oumeizongyi",
"29": "guochandongman", "30": "rihandongman", "31": "oumeidongman", "32": "gangtaidongman",
"33": "haiwaidongman", "34": "lunlipian", "36": "duanju"
};
const typeParentMap = {
"1": 0, "2": 0, "3": 0, "4": 0, "6": 1, "7": 1, "8": 1, "9": 1, "10": 1,
"11": 1, "12": 1, "13": 2, "14": 2, "15": 2, "16": 2, "20": 1, "21": 2, "22": 2,
"23": 2, "24": 2, "25": 3, "26": 3, "27": 3, "28": 3, "29": 4, "30": 4,
"31": 4, "32": 4, "33": 4, "34": 1, "36": 2
};
function topType(tid) {
tid = parseInt(tid || 0, 10);
if (tid === 36) return 36;
const p = parseInt(typeParentMap[String(tid)] || 0, 10);
return p > 0 ? p : tid;
}
function typeSlug(tid) {
return typeSlugMap[String(parseInt(tid || 0, 10))] || ('type' + parseInt(tid || 0, 10));
}
function getAreaFilter() {
return {
"key": "area", "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": "其他" }
]
};
}
function getYearFilter() {
let years = [{ "n": "全部", "v": "" }];
const currentYear = new Date().getFullYear();
for (let y = currentYear; y >= 2010; y--) {
years.push({ "n": String(y), "v": String(y) });
}
return { "key": "year", "name": "年份", "value": years };
}
const commonFilters = [getAreaFilter(), getYearFilter()];
const myFilters = {};
classList.forEach(item => {
myFilters[item.type_id] = commonFilters;
});
function fixUrl(u) {
if (!u) return '';
if (u.startsWith('http')) return u;
if (u.startsWith('//')) return 'http:' + u;
if (u.startsWith('/')) return appConfig.siteUrl + u;
return u;
}
async function home(filter) {
let list = [];
try {
const html = (await req(appConfig.siteUrl, {
method: "GET",
headers: { "User-Agent": UA }
})).content;
const $ = cheerio.load(html);
let seen = {};
$(".tpl-card[href]").each(function () {
let vod_id = $(this).attr("href");
if (!vod_id || seen[vod_id]) return;
let vod_name = $(this).attr("title") || $(this).find("strong").first().text().trim() || "";
vod_name = vod_name.replace(/免费在线观看$/, "");
let vod_pic = fixUrl($(this).find("img").first().attr("src") || "");
let vod_remarks = $(this).find("em").first().text().trim();
if (vod_name && vod_id) {
seen[vod_id] = true;
list.push({ vod_id, vod_name, vod_pic, vod_remarks });
}
});
} catch (e) {
console.error("首页推荐获取失败:", e.message);
}
return JSON.stringify({
class: classList,
filters: myFilters,
list: list.slice(0, 30)
});
}
function buildCategoryUrl(tid, pg, extend) {
extend = extend || {};
let top = topType(tid);
let topSlug = typeSlug(top);
let childSlug = (tid != top) ? typeSlug(tid) : '';
let path;
if (childSlug && tid != 36) {
path = `/${topSlug}/${childSlug}/`;
} else {
path = `/${topSlug}/`;
}
if (pg > 1) {
path += `page-${pg}.html`;
}
let area = extend.area || '';
let year = extend.year || '';
if (area || year) {
let params = [];
if (area) params.push('area=' + encodeURIComponent(area));
if (year) params.push('year=' + encodeURIComponent(year));
return appConfig.siteUrl + `/api_proxy.php?ac=list&t=${tid}&pg=${pg}&${params.join('&')}`;
}
return appConfig.siteUrl + path;
}
function parseListHtml(html) {
const $ = cheerio.load(html);
let list = [];
let vodIds = {};
$(".tpl-card.card-poster, .tpl-card.card-wide").each(function () {
let $a = $(this);
let vod_id = $a.attr("href");
if (!vod_id || vodIds[vod_id]) return;
let vod_name = $a.attr("title") || $a.find("strong").first().text().trim() || "";
vod_name = vod_name.replace(/免费在线观看$/, "");
let vod_pic = fixUrl($a.find("img").first().attr("src") || "");
let vod_remarks = $a.find("em").first().text().trim() || $a.find("small").first().text().trim();
if (vod_name && vod_id) {
vodIds[vod_id] = true;
list.push({ vod_id, vod_name, vod_pic, vod_remarks });
}
});
if (list.length === 0) {
try {
let data = JSON.parse(html);
if (data.list && Array.isArray(data.list)) {
data.list.forEach(item => {
let vod_id = `/${typeSlug(topType(item.type_id))}/${(item.vod_en || item.vod_name || '').toLowerCase().replace(/[^a-z0-9]+/g, '')}.html`;
let vod_name = item.vod_name || "";
let vod_pic = item.vod_pic || "";
let vod_remarks = item.vod_remarks || "";
if (vod_name) {
list.push({ vod_id, vod_name, vod_pic, vod_remarks });
}
});
}
} catch (e) {
}
}
let pagecount = 1;
$(".pagination a").each(function () {
let href = $(this).attr("href") || '';
let m = href.match(/page-(\d+)/);
if (m) {
let p = parseInt(m[1]);
if (p > pagecount) pagecount = p;
}
});
return { list, pagecount };
}
async function category(tid, pg, filter, extend) {
pg = pg || 1;
extend = extend || {};
let url = buildCategoryUrl(tid, pg, extend);
try {
const html = (await req(url, {
method: "GET",
headers: { "User-Agent": UA, "Referer": appConfig.siteUrl }
})).content;
const result = parseListHtml(html);
return JSON.stringify(result);
} catch (e) {
console.error("分类列表获取失败:", e.message);
return JSON.stringify({ list: [], pagecount: 0 });
}
}
async function search(wd, quick, page) {
page = page || 1;
try {
const url = `${appConfig.siteUrl}/search-${encodeURIComponent(wd)}${page > 1 ? '-page-' + page : ''}.html`;
const html = (await req(url, {
method: "GET",
headers: { "User-Agent": UA, "Referer": appConfig.siteUrl }
})).content;
const result = parseListHtml(html);
return JSON.stringify(result);
} catch (e) {
console.error("搜索失败:", e.message);
return JSON.stringify({ list: [], pagecount: 0 });
}
}
async function detail(id) {
try {
const html = (await req(appConfig.siteUrl + id, {
method: "GET",
headers: { "User-Agent": UA, "Referer": appConfig.siteUrl }
})).content;
const $ = cheerio.load(html);
let vod_name = $("h1").first().text().trim();
let vod_pic = fixUrl($(".detail-poster img").first().attr("src") || "");
let vod_director = "";
let vod_actor = "";
let vod_area = "";
let vod_year = "";
let vod_content = "";
let vod_class = "";
let vod_remarks = "";
$(".detail-tags span").each(function () {
let text = $(this).text().trim();
if (/^\d{4}$/.test(text) && !vod_year) vod_year = text;
else if (/大陆|香港|台湾|美国|日本|韩国|英国|法国|德国|泰国|印度|其他/.test(text) && !vod_area) vod_area = text;
else if (!vod_class && text !== vod_year && text !== vod_area && !/更新至|集|期|TC|HD|正片/.test(text)) vod_class = text;
});
vod_remarks = $(".detail-poster span").first().text().trim();
$(".detail-meta p").each(function () {
let text = $(this).text();
if (text.includes("主演:") && !vod_actor) {
vod_actor = text.replace("主演:", "").trim();
}
if (text.includes("导演:") && !vod_director) {
vod_director = text.replace("导演:", "").trim();
}
});
let $intro = $(".detail-intro");
if ($intro.length > 0) {
vod_content = $intro.first().text().replace("简介:", "").trim();
}
if (!vod_content) {
$intro = $(".article-text");
if ($intro.length > 0) {
vod_content = $intro.first().text().trim();
}
}
let lines = [];
let playlists = [];
let epArray = [];
$(".episode-grid a").each(function () {
let name = $(this).text().trim();
let href = $(this).attr('href') || '';
if (name && href) {
epArray.push({ name, href });
}
});
epArray.sort((a, b) => {
let numA = parseInt(a.name.match(/第(\d+)/)?.[1] || 0);
let numB = parseInt(b.name.match(/第(\d+)/)?.[1] || 0);
return numA - numB;
});
let episodes = epArray.map(ep => `${ep.name}$${ep.href}`);
if (episodes.length > 0) {
lines.push("默认");
playlists.push(episodes);
} else {
let playHref = $(".detail-actions a.btn-primary").attr("href") || "";
if (playHref) {
lines.push("默认");
playlists.push([`正片$${playHref}`]);
}
}
if (lines.length === 0) {
lines.push("默认");
playlists.push([`暂无播放地址$${id}`]);
}
const { vod_play_from, vod_play_url } = buildVodPlayData(lines, playlists);
return JSON.stringify({
list: [{
vod_id: id,
vod_name,
vod_pic,
vod_actor,
vod_director,
vod_remarks,
vod_year,
vod_area,
vod_content,
vod_class,
vod_play_from,
vod_play_url
}]
});
} catch (error) {
console.error(`解析详情页异常 [ID: ${id}]:`, error);
return JSON.stringify({ list: [] });
}
}
function buildVodPlayData(lines, playlists) {
const processedPlaylists = playlists.map(eps => eps.join('#'));
return {
vod_play_from: lines.filter(Boolean).join('$$$'),
vod_play_url: processedPlaylists.join('$$$')
};
}
async function play(flag, id, flags) {
try {
if (id.startsWith("http")) {
return JSON.stringify({
parse: 0,
Header: { "User-Agent": UA, "Referer": appConfig.siteUrl },
url: id
});
}
const html = (await req(`${appConfig.siteUrl}${id}`, {
method: "GET",
headers: { "User-Agent": UA, "Referer": appConfig.siteUrl }
})).content;
// 方式1:从 noscript 中提取 m3u8 URL
let noscriptMatch = html.match(/<noscript>.*?当前播放地址[:]\s*(https?:\/\/[^\s<"]+\.m3u8[^\s<"]*)/);
if (noscriptMatch) {
return JSON.stringify({
parse: 0,
Header: { "User-Agent": UA, "Referer": appConfig.siteUrl },
url: noscriptMatch[1]
});
}
// 方式2:从 JS 中提取 var src="..."
let srcMatch = html.match(/var\s+src\s*=\s*["'](https?:\/\/[^"']+\.m3u8[^"']*)/);
if (srcMatch) {
return JSON.stringify({
parse: 0,
Header: { "User-Agent": UA, "Referer": appConfig.siteUrl },
url: srcMatch[1]
});
}
// 方式3:直接匹配 m3u8 URL
let urlMatch = html.match(/(https?:\/\/[^"'\s<>]+\.m3u8[^"'\s<>]*)/);
if (urlMatch) {
return JSON.stringify({
parse: 0,
Header: { "User-Agent": UA, "Referer": appConfig.siteUrl },
url: urlMatch[1]
});
}
// 方式4player_aaaa
let playerMatch = html.match(/var player_aaaa\s*=\s*(\{.+?\});/);
if (playerMatch) {
try {
let playerData = JSON.parse(playerMatch[1]);
if (playerData.url) {
return JSON.stringify({
parse: 0,
Header: { "User-Agent": UA, "Referer": appConfig.siteUrl },
url: playerData.url
});
}
} catch (e) {}
}
// 方式5video 标签的 src
const $ = cheerio.load(html);
let videoSrc = $("video").attr("src") || $("video source").attr("src");
if (videoSrc) {
return JSON.stringify({
parse: 0,
Header: { "User-Agent": UA, "Referer": appConfig.siteUrl },
url: fixUrl(videoSrc)
});
}
return JSON.stringify({
parse: 1,
Header: { "User-Agent": UA, "Referer": appConfig.siteUrl },
url: appConfig.siteUrl + id
});
} catch (e) {
console.error("播放失败:", e);
return JSON.stringify({ parse: 0, url: "" });
}
}
export default {
init,
home,
category,
detail,
search,
play
};
+3
View File
@@ -0,0 +1,3 @@
//本资源来源于互联网公开渠道,仅可用于个人学习爬虫技术。
//严禁将其用于任何商业用途,下载后请于 24 小时内删除,搜索结果均来自源站,本人不承担任何责任。
import{load as n,Crypto as v}from"assets://js/lib/cat.js";let e="https://vip.wwgz.cn:5200",t=!1,i={"User-Agent":"Mozilla/5.0 (iPhone; CPU iPhone OS 13_3_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.5 Mobile/15E148 Snapchat/10.77.5.59 (like Safari/604.1)",Accept:"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7","accept-language":"zh-CN,zh;q=0.9","cache-control":"no-cache",pragma:"no-cache","upgrade-insecure-requests":"1"};async function a(n){let v=n.ext;"string"==typeof v&&v.startsWith("http")&&(e=v),e.endsWith("/")&&(e=e.slice(0,-1)),"function"==typeof js2Proxy&&"function"==typeof desX&&"function"!=typeof getProxy&&(t=!0)}async function r(n){let v={class:[{type_id:"1",type_name:"电影"},{type_id:"2",type_name:"连续剧"},{type_id:"3",type_name:"综艺"},{type_id:"4",type_name:"动漫"},{type_id:"26",type_name:"短剧"}],filters:{1:[{key:"id",name:"类型",init:"",value:[{n:"全部",v:""},{n:"动作片",v:"5"},{n:"喜剧片",v:"6"},{n:"爱情片",v:"7"},{n:"科幻片",v:"8"},{n:"恐怖片",v:"9"},{n:"剧情片",v:"10"},{n:"战争片",v:"11"},{n:"惊悚片",v:"16"},{n:"奇幻片",v:"17"}]},{key:"area",name:"地区",init:"",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:"其它",v:"其它"}]},{key:"year",name:"年份",init:"",value:[{n:"全部",v:""},{n:"2026",v:"2026"},{n:"2025",v:"2025"},{n:"2024",v:"2024"},{n:"2023",v:"2023"},{n:"2022",v:"2022"},{n:"2021",v:"2021"},{n:"2020",v:"2020"},{n:"2019",v:"2019"},{n:"2018",v:"2018"},{n:"2017",v:"2017"},{n:"2016",v:"2016"},{n:"2015",v:"2015"},{n:"2014",v:"2014"},{n:"2013",v:"2013"},{n:"2012",v:"2012"},{n:"2011",v:"2011"},{n:"2010",v:"2010"},{n:"2009",v:"2009"},{n:"2008",v:"2008"},{n:"2007",v:"2007"},{n:"2006",v:"2006"},{n:"2005",v:"2005"},{n:"2004",v:"2004"},{n:"2003",v:"2003"},{n:"2002",v:"2002"},{n:"2001",v:"2001"},{n:"2000",v:"2000"},{n:"1999",v:"1999"},{n:"1998",v:"1998"},{n:"1997",v:"1997"},{n:"1996",v:"1996"},{n:"1995",v:"1995"},{n:"1994",v:"1994"},{n:"1993",v:"1993"},{n:"1992",v:"1992"},{n:"1991",v:"1991"},{n:"1990",v:"1990"},{n:"1989",v:"1989"},{n:"1988",v:"1988"},{n:"1987",v:"1987"},{n:"1986",v:"1986"},{n:"1985",v:"1985"},{n:"1984",v:"1984"},{n:"1983",v:"1983"},{n:"1982",v:"1982"},{n:"1981",v:"1981"},{n:"1980",v:"1980"},{n:"1979",v:"1979"},{n:"1978",v:"1978"},{n:"1977",v:"1977"},{n:"1976",v:"1976"},{n:"1975",v:"1975"},{n:"1974",v:"1974"},{n:"1973",v:"1973"},{n:"1972",v:"1972"},{n:"1971",v:"1971"},{n:"1970",v:"1970"},{n:"1969",v:"1969"},{n:"1968",v:"1968"},{n:"1967",v:"1967"},{n:"1966",v:"1966"},{n:"1965",v:"1965"},{n:"1964",v:"1964"},{n:"1963",v:"1963"},{n:"1962",v:"1962"},{n:"1961",v:"1961"},{n:"1960",v:"1960"},{n:"1959",v:"1959"},{n:"1958",v:"1958"},{n:"1957",v:"1957"},{n:"1956",v:"1956"},{n:"1955",v:"1955"},{n:"1954",v:"1954"},{n:"1953",v:"1953"},{n:"1952",v:"1952"},{n:"1951",v:"1951"},{n:"1950",v:"1950"},{n:"1949",v:"1949"},{n:"1948",v:"1948"},{n:"1947",v:"1947"},{n:"1946",v:"1946"},{n:"1945",v:"1945"},{n:"1944",v:"1944"},{n:"1943",v:"1943"},{n:"1942",v:"1942"},{n:"1941",v:"1941"},{n:"1940",v:"1940"},{n:"1939",v:"1939"},{n:"1938",v:"1938"},{n:"1937",v:"1937"},{n:"1936",v:"1936"},{n:"1935",v:"1935"},{n:"1934",v:"1934"},{n:"1933",v:"1933"},{n:"1932",v:"1932"},{n:"1931",v:"1931"},{n:"1930",v:"1930"},{n:"1929",v:"1929"},{n:"1928",v:"1928"},{n:"1927",v:"1927"},{n:"1926",v:"1926"},{n:"1925",v:"1925"},{n:"1924",v:"1924"},{n:"1923",v:"1923"},{n:"1922",v:"1922"},{n:"1921",v:"1921"},{n:"1920",v:"1920"},{n:"1919",v:"1919"},{n:"1918",v:"1918"},{n:"1917",v:"1917"},{n:"1916",v:"1916"},{n:"1915",v:"1915"},{n:"1914",v:"1914"},{n:"1913",v:"1913"},{n:"1912",v:"1912"},{n:"1911",v:"1911"},{n:"1910",v:"1910"},{n:"1909",v:"1909"},{n:"1908",v:"1908"},{n:"1907",v:"1907"},{n:"1906",v:"1906"},{n:"1905",v:"1905"},{n:"1904",v:"1904"},{n:"1903",v:"1903"},{n:"1902",v:"1902"},{n:"1901",v:"1901"},{n:"1900",v:"1900"}]},{key:"by",name:"排序",init:"time",value:[{n:"全部",v:"time"},{n:"人气",v:"hits"},{n:"评分",v:"score"}]}],2:[{key:"id",name:"类型",init:"",value:[{n:"全部",v:""},{n:"国产剧",v:"12"},{n:"港台泰",v:"13"},{n:"日韩剧",v:"14"},{n:"欧美剧",v:"15"}]},{key:"area",name:"地区",init:"",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:"其它",v:"其它"}]},{key:"year",name:"年份",init:"",value:[{n:"全部",v:""},{n:"2026",v:"2026"},{n:"2025",v:"2025"},{n:"2024",v:"2024"},{n:"2023",v:"2023"},{n:"2022",v:"2022"},{n:"2021",v:"2021"},{n:"2020",v:"2020"},{n:"2019",v:"2019"},{n:"2018",v:"2018"},{n:"2017",v:"2017"},{n:"2016",v:"2016"},{n:"2015",v:"2015"},{n:"2014",v:"2014"},{n:"2013",v:"2013"},{n:"2012",v:"2012"},{n:"2011",v:"2011"},{n:"2010",v:"2010"},{n:"2009",v:"2009"},{n:"2008",v:"2008"},{n:"2007",v:"2007"},{n:"2006",v:"2006"},{n:"2005",v:"2005"},{n:"2004",v:"2004"},{n:"2003",v:"2003"},{n:"2002",v:"2002"},{n:"2001",v:"2001"},{n:"2000",v:"2000"},{n:"1999",v:"1999"},{n:"1998",v:"1998"},{n:"1997",v:"1997"},{n:"1996",v:"1996"},{n:"1995",v:"1995"},{n:"1994",v:"1994"},{n:"1993",v:"1993"},{n:"1992",v:"1992"},{n:"1991",v:"1991"},{n:"1990",v:"1990"},{n:"1989",v:"1989"},{n:"1988",v:"1988"},{n:"1987",v:"1987"},{n:"1986",v:"1986"},{n:"1985",v:"1985"},{n:"1984",v:"1984"},{n:"1983",v:"1983"},{n:"1982",v:"1982"},{n:"1981",v:"1981"},{n:"1980",v:"1980"},{n:"1979",v:"1979"},{n:"1978",v:"1978"},{n:"1977",v:"1977"},{n:"1976",v:"1976"},{n:"1975",v:"1975"},{n:"1974",v:"1974"},{n:"1973",v:"1973"},{n:"1972",v:"1972"},{n:"1971",v:"1971"},{n:"1970",v:"1970"},{n:"1969",v:"1969"},{n:"1968",v:"1968"},{n:"1967",v:"1967"},{n:"1966",v:"1966"},{n:"1965",v:"1965"},{n:"1964",v:"1964"},{n:"1963",v:"1963"},{n:"1962",v:"1962"},{n:"1961",v:"1961"},{n:"1960",v:"1960"},{n:"1959",v:"1959"},{n:"1958",v:"1958"},{n:"1957",v:"1957"},{n:"1956",v:"1956"},{n:"1955",v:"1955"},{n:"1954",v:"1954"},{n:"1953",v:"1953"},{n:"1952",v:"1952"},{n:"1951",v:"1951"},{n:"1950",v:"1950"},{n:"1949",v:"1949"},{n:"1948",v:"1948"},{n:"1947",v:"1947"},{n:"1946",v:"1946"},{n:"1945",v:"1945"},{n:"1944",v:"1944"},{n:"1943",v:"1943"},{n:"1942",v:"1942"},{n:"1941",v:"1941"},{n:"1940",v:"1940"},{n:"1939",v:"1939"},{n:"1938",v:"1938"},{n:"1937",v:"1937"},{n:"1936",v:"1936"},{n:"1935",v:"1935"},{n:"1934",v:"1934"},{n:"1933",v:"1933"},{n:"1932",v:"1932"},{n:"1931",v:"1931"},{n:"1930",v:"1930"},{n:"1929",v:"1929"},{n:"1928",v:"1928"},{n:"1927",v:"1927"},{n:"1926",v:"1926"},{n:"1925",v:"1925"},{n:"1924",v:"1924"},{n:"1923",v:"1923"},{n:"1922",v:"1922"},{n:"1921",v:"1921"},{n:"1920",v:"1920"},{n:"1919",v:"1919"},{n:"1918",v:"1918"},{n:"1917",v:"1917"},{n:"1916",v:"1916"},{n:"1915",v:"1915"},{n:"1914",v:"1914"},{n:"1913",v:"1913"},{n:"1912",v:"1912"},{n:"1911",v:"1911"},{n:"1910",v:"1910"},{n:"1909",v:"1909"},{n:"1908",v:"1908"},{n:"1907",v:"1907"},{n:"1906",v:"1906"},{n:"1905",v:"1905"},{n:"1904",v:"1904"},{n:"1903",v:"1903"},{n:"1902",v:"1902"},{n:"1901",v:"1901"},{n:"1900",v:"1900"}]},{key:"by",name:"排序",init:"time",value:[{n:"全部",v:"time"},{n:"人气",v:"hits"},{n:"评分",v:"score"}]}],3:[{key:"id",name:"类型",init:"",value:[{n:"全部",v:""}]},{key:"area",name:"地区",init:"",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:"其它",v:"其它"}]},{key:"year",name:"年份",init:"",value:[{n:"全部",v:""},{n:"2026",v:"2026"},{n:"2025",v:"2025"},{n:"2024",v:"2024"},{n:"2023",v:"2023"},{n:"2022",v:"2022"},{n:"2021",v:"2021"},{n:"2020",v:"2020"},{n:"2019",v:"2019"},{n:"2018",v:"2018"},{n:"2017",v:"2017"},{n:"2016",v:"2016"},{n:"2015",v:"2015"},{n:"2014",v:"2014"},{n:"2013",v:"2013"},{n:"2012",v:"2012"},{n:"2011",v:"2011"},{n:"2010",v:"2010"},{n:"2009",v:"2009"},{n:"2008",v:"2008"},{n:"2007",v:"2007"},{n:"2006",v:"2006"},{n:"2005",v:"2005"},{n:"2004",v:"2004"},{n:"2003",v:"2003"},{n:"2002",v:"2002"},{n:"2001",v:"2001"},{n:"2000",v:"2000"},{n:"1999",v:"1999"},{n:"1998",v:"1998"},{n:"1997",v:"1997"},{n:"1996",v:"1996"},{n:"1995",v:"1995"},{n:"1994",v:"1994"},{n:"1993",v:"1993"},{n:"1992",v:"1992"},{n:"1991",v:"1991"},{n:"1990",v:"1990"},{n:"1989",v:"1989"},{n:"1988",v:"1988"},{n:"1987",v:"1987"},{n:"1986",v:"1986"},{n:"1985",v:"1985"},{n:"1984",v:"1984"},{n:"1983",v:"1983"},{n:"1982",v:"1982"},{n:"1981",v:"1981"},{n:"1980",v:"1980"},{n:"1979",v:"1979"},{n:"1978",v:"1978"},{n:"1977",v:"1977"},{n:"1976",v:"1976"},{n:"1975",v:"1975"},{n:"1974",v:"1974"},{n:"1973",v:"1973"},{n:"1972",v:"1972"},{n:"1971",v:"1971"},{n:"1970",v:"1970"},{n:"1969",v:"1969"},{n:"1968",v:"1968"},{n:"1967",v:"1967"},{n:"1966",v:"1966"},{n:"1965",v:"1965"},{n:"1964",v:"1964"},{n:"1963",v:"1963"},{n:"1962",v:"1962"},{n:"1961",v:"1961"},{n:"1960",v:"1960"},{n:"1959",v:"1959"},{n:"1958",v:"1958"},{n:"1957",v:"1957"},{n:"1956",v:"1956"},{n:"1955",v:"1955"},{n:"1954",v:"1954"},{n:"1953",v:"1953"},{n:"1952",v:"1952"},{n:"1951",v:"1951"},{n:"1950",v:"1950"},{n:"1949",v:"1949"},{n:"1948",v:"1948"},{n:"1947",v:"1947"},{n:"1946",v:"1946"},{n:"1945",v:"1945"},{n:"1944",v:"1944"},{n:"1943",v:"1943"},{n:"1942",v:"1942"},{n:"1941",v:"1941"},{n:"1940",v:"1940"},{n:"1939",v:"1939"},{n:"1938",v:"1938"},{n:"1937",v:"1937"},{n:"1936",v:"1936"},{n:"1935",v:"1935"},{n:"1934",v:"1934"},{n:"1933",v:"1933"},{n:"1932",v:"1932"},{n:"1931",v:"1931"},{n:"1930",v:"1930"},{n:"1929",v:"1929"},{n:"1928",v:"1928"},{n:"1927",v:"1927"},{n:"1926",v:"1926"},{n:"1925",v:"1925"},{n:"1924",v:"1924"},{n:"1923",v:"1923"},{n:"1922",v:"1922"},{n:"1921",v:"1921"},{n:"1920",v:"1920"},{n:"1919",v:"1919"},{n:"1918",v:"1918"},{n:"1917",v:"1917"},{n:"1916",v:"1916"},{n:"1915",v:"1915"},{n:"1914",v:"1914"},{n:"1913",v:"1913"},{n:"1912",v:"1912"},{n:"1911",v:"1911"},{n:"1910",v:"1910"},{n:"1909",v:"1909"},{n:"1908",v:"1908"},{n:"1907",v:"1907"},{n:"1906",v:"1906"},{n:"1905",v:"1905"},{n:"1904",v:"1904"},{n:"1903",v:"1903"},{n:"1902",v:"1902"},{n:"1901",v:"1901"},{n:"1900",v:"1900"}]},{key:"by",name:"排序",init:"time",value:[{n:"全部",v:"time"},{n:"人气",v:"hits"},{n:"评分",v:"score"}]}],4:[{key:"id",name:"类型",init:"",value:[{n:"全部",v:""},{n:"动漫剧",v:"18"}]},{key:"area",name:"地区",init:"",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:"其它",v:"其它"}]},{key:"year",name:"年份",init:"",value:[{n:"全部",v:""},{n:"2026",v:"2026"},{n:"2025",v:"2025"},{n:"2024",v:"2024"},{n:"2023",v:"2023"},{n:"2022",v:"2022"},{n:"2021",v:"2021"},{n:"2020",v:"2020"},{n:"2019",v:"2019"},{n:"2018",v:"2018"},{n:"2017",v:"2017"},{n:"2016",v:"2016"},{n:"2015",v:"2015"},{n:"2014",v:"2014"},{n:"2013",v:"2013"},{n:"2012",v:"2012"},{n:"2011",v:"2011"},{n:"2010",v:"2010"},{n:"2009",v:"2009"},{n:"2008",v:"2008"},{n:"2007",v:"2007"},{n:"2006",v:"2006"},{n:"2005",v:"2005"},{n:"2004",v:"2004"},{n:"2003",v:"2003"},{n:"2002",v:"2002"},{n:"2001",v:"2001"},{n:"2000",v:"2000"},{n:"1999",v:"1999"},{n:"1998",v:"1998"},{n:"1997",v:"1997"},{n:"1996",v:"1996"},{n:"1995",v:"1995"},{n:"1994",v:"1994"},{n:"1993",v:"1993"},{n:"1992",v:"1992"},{n:"1991",v:"1991"},{n:"1990",v:"1990"},{n:"1989",v:"1989"},{n:"1988",v:"1988"},{n:"1987",v:"1987"},{n:"1986",v:"1986"},{n:"1985",v:"1985"},{n:"1984",v:"1984"},{n:"1983",v:"1983"},{n:"1982",v:"1982"},{n:"1981",v:"1981"},{n:"1980",v:"1980"},{n:"1979",v:"1979"},{n:"1978",v:"1978"},{n:"1977",v:"1977"},{n:"1976",v:"1976"},{n:"1975",v:"1975"},{n:"1974",v:"1974"},{n:"1973",v:"1973"},{n:"1972",v:"1972"},{n:"1971",v:"1971"},{n:"1970",v:"1970"},{n:"1969",v:"1969"},{n:"1968",v:"1968"},{n:"1967",v:"1967"},{n:"1966",v:"1966"},{n:"1965",v:"1965"},{n:"1964",v:"1964"},{n:"1963",v:"1963"},{n:"1962",v:"1962"},{n:"1961",v:"1961"},{n:"1960",v:"1960"},{n:"1959",v:"1959"},{n:"1958",v:"1958"},{n:"1957",v:"1957"},{n:"1956",v:"1956"},{n:"1955",v:"1955"},{n:"1954",v:"1954"},{n:"1953",v:"1953"},{n:"1952",v:"1952"},{n:"1951",v:"1951"},{n:"1950",v:"1950"},{n:"1949",v:"1949"},{n:"1948",v:"1948"},{n:"1947",v:"1947"},{n:"1946",v:"1946"},{n:"1945",v:"1945"},{n:"1944",v:"1944"},{n:"1943",v:"1943"},{n:"1942",v:"1942"},{n:"1941",v:"1941"},{n:"1940",v:"1940"},{n:"1939",v:"1939"},{n:"1938",v:"1938"},{n:"1937",v:"1937"},{n:"1936",v:"1936"},{n:"1935",v:"1935"},{n:"1934",v:"1934"},{n:"1933",v:"1933"},{n:"1932",v:"1932"},{n:"1931",v:"1931"},{n:"1930",v:"1930"},{n:"1929",v:"1929"},{n:"1928",v:"1928"},{n:"1927",v:"1927"},{n:"1926",v:"1926"},{n:"1925",v:"1925"},{n:"1924",v:"1924"},{n:"1923",v:"1923"},{n:"1922",v:"1922"},{n:"1921",v:"1921"},{n:"1920",v:"1920"},{n:"1919",v:"1919"},{n:"1918",v:"1918"},{n:"1917",v:"1917"},{n:"1916",v:"1916"},{n:"1915",v:"1915"},{n:"1914",v:"1914"},{n:"1913",v:"1913"},{n:"1912",v:"1912"},{n:"1911",v:"1911"},{n:"1910",v:"1910"},{n:"1909",v:"1909"},{n:"1908",v:"1908"},{n:"1907",v:"1907"},{n:"1906",v:"1906"},{n:"1905",v:"1905"},{n:"1904",v:"1904"},{n:"1903",v:"1903"},{n:"1902",v:"1902"},{n:"1901",v:"1901"},{n:"1900",v:"1900"}]},{key:"by",name:"排序",init:"time",value:[{n:"全部",v:"time"},{n:"人气",v:"hits"},{n:"评分",v:"score"}]}],26:[{key:"id",name:"类型",init:"",value:[{n:"全部",v:""}]},{key:"area",name:"地区",init:"",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:"其它",v:"其它"}]},{key:"year",name:"年份",init:"",value:[{n:"全部",v:""},{n:"2026",v:"2026"},{n:"2025",v:"2025"},{n:"2024",v:"2024"},{n:"2023",v:"2023"},{n:"2022",v:"2022"},{n:"2021",v:"2021"},{n:"2020",v:"2020"},{n:"2019",v:"2019"},{n:"2018",v:"2018"},{n:"2017",v:"2017"},{n:"2016",v:"2016"},{n:"2015",v:"2015"},{n:"2014",v:"2014"},{n:"2013",v:"2013"},{n:"2012",v:"2012"},{n:"2011",v:"2011"},{n:"2010",v:"2010"},{n:"2009",v:"2009"},{n:"2008",v:"2008"},{n:"2007",v:"2007"},{n:"2006",v:"2006"},{n:"2005",v:"2005"},{n:"2004",v:"2004"},{n:"2003",v:"2003"},{n:"2002",v:"2002"},{n:"2001",v:"2001"},{n:"2000",v:"2000"},{n:"1999",v:"1999"},{n:"1998",v:"1998"},{n:"1997",v:"1997"},{n:"1996",v:"1996"},{n:"1995",v:"1995"},{n:"1994",v:"1994"},{n:"1993",v:"1993"},{n:"1992",v:"1992"},{n:"1991",v:"1991"},{n:"1990",v:"1990"},{n:"1989",v:"1989"},{n:"1988",v:"1988"},{n:"1987",v:"1987"},{n:"1986",v:"1986"},{n:"1985",v:"1985"},{n:"1984",v:"1984"},{n:"1983",v:"1983"},{n:"1982",v:"1982"},{n:"1981",v:"1981"},{n:"1980",v:"1980"},{n:"1979",v:"1979"},{n:"1978",v:"1978"},{n:"1977",v:"1977"},{n:"1976",v:"1976"},{n:"1975",v:"1975"},{n:"1974",v:"1974"},{n:"1973",v:"1973"},{n:"1972",v:"1972"},{n:"1971",v:"1971"},{n:"1970",v:"1970"},{n:"1969",v:"1969"},{n:"1968",v:"1968"},{n:"1967",v:"1967"},{n:"1966",v:"1966"},{n:"1965",v:"1965"},{n:"1964",v:"1964"},{n:"1963",v:"1963"},{n:"1962",v:"1962"},{n:"1961",v:"1961"},{n:"1960",v:"1960"},{n:"1959",v:"1959"},{n:"1958",v:"1958"},{n:"1957",v:"1957"},{n:"1956",v:"1956"},{n:"1955",v:"1955"},{n:"1954",v:"1954"},{n:"1953",v:"1953"},{n:"1952",v:"1952"},{n:"1951",v:"1951"},{n:"1950",v:"1950"},{n:"1949",v:"1949"},{n:"1948",v:"1948"},{n:"1947",v:"1947"},{n:"1946",v:"1946"},{n:"1945",v:"1945"},{n:"1944",v:"1944"},{n:"1943",v:"1943"},{n:"1942",v:"1942"},{n:"1941",v:"1941"},{n:"1940",v:"1940"},{n:"1939",v:"1939"},{n:"1938",v:"1938"},{n:"1937",v:"1937"},{n:"1936",v:"1936"},{n:"1935",v:"1935"},{n:"1934",v:"1934"},{n:"1933",v:"1933"},{n:"1932",v:"1932"},{n:"1931",v:"1931"},{n:"1930",v:"1930"},{n:"1929",v:"1929"},{n:"1928",v:"1928"},{n:"1927",v:"1927"},{n:"1926",v:"1926"},{n:"1925",v:"1925"},{n:"1924",v:"1924"},{n:"1923",v:"1923"},{n:"1922",v:"1922"},{n:"1921",v:"1921"},{n:"1920",v:"1920"},{n:"1919",v:"1919"},{n:"1918",v:"1918"},{n:"1917",v:"1917"},{n:"1916",v:"1916"},{n:"1915",v:"1915"},{n:"1914",v:"1914"},{n:"1913",v:"1913"},{n:"1912",v:"1912"},{n:"1911",v:"1911"},{n:"1910",v:"1910"},{n:"1909",v:"1909"},{n:"1908",v:"1908"},{n:"1907",v:"1907"},{n:"1906",v:"1906"},{n:"1905",v:"1905"},{n:"1904",v:"1904"},{n:"1903",v:"1903"},{n:"1902",v:"1902"},{n:"1901",v:"1901"},{n:"1900",v:"1900"}]},{key:"by",name:"排序",init:"time",value:[{n:"全部",v:"time"},{n:"人气",v:"hits"},{n:"评分",v:"score"}]}]}};return t&&v.class.unshift({type_id:"home",type_name:"首页"}),JSON.stringify(v)}async function s(v,t,i,a){if("home"===v)return JSON.stringify({page:1,pagecount:1,list:m(n(await d(e+"/")))});let r=a||{},s=(r.id||v).match(/\d+/)?.[0]||"1";const o=n=>null==n||""===n?"":n;let l=`${e}/index.php?m=vod-list-id-${s}-pg-${t||1}-order--by-${r.by||"time"}-class-${o(r.class)}-year-${o(r.year)}-letter-${r.letter||""}-area-${encodeURIComponent(o(r.area))}-lang-${encodeURIComponent(o(r.lang))}.html`,c=m(n(await d(l)));return JSON.stringify({page:parseInt(t||1),pagecount:c.length>0?parseInt(t||1)+1:1,list:c})}async function o(v,a=!1,r=1){let s=`${e}/index.php?m=vod-search`,o=await req(s,{method:"POST",postType:"form",headers:{...i,Referer:`${e}/vod-search`},data:{wd:t?encodeURIComponent(v):v}}),l=n(o.content),c=[];return l("#data_list li").each((n,v)=>{let e=l(v).find(".pic a"),t=e.attr("href");if(t&&t.includes("vod-detail-id")){let n=e.find("img").attr("data-src")||e.find("img").attr("src"),i=l(v).find(".txt .sTit").text().trim(),a=l(v).find(".pic .sStyle").text().trim(),r=l(v).find('.txt .sDes:contains("评分")').text().replace(/评分[:]?\s*/,"").trim(),s=l(v).find('.txt .sDes:contains("主演")').text().replace(/主演[:]?\s*/,"").trim(),o=[];a&&o.push(a),r&&o.push(`${r}`),s&&o.push(s);let m=o.join(" | ");c.push({vod_id:t,vod_name:i,vod_pic:p(n),vod_remarks:m})}}),JSON.stringify({list:c})}async function l(v){let t=v.startsWith("http")?v:e+v,i=n(await d(t)),a={vod_id:v,vod_name:i(".page-bd h1.title").text().trim(),vod_pic:p(i(".page-hd img").attr("src")),vod_year:i('.desc_item:contains("年代:") a').text().trim(),vod_remarks:i('.desc_item:contains("状态:") font').text().trim(),vod_actor:i('.desc_item:contains("主演:") a').map((n,v)=>i(v).text()).get().join(" ").trim(),vod_content:i(".detail-con p").text().replace(/简[\s\S]*?介[:]\s*/,"").trim(),vod_play_from:"",vod_play_url:""},r=i(".page-btn a.greenBtn").attr("href");if(r){let n=await d(r.startsWith("http")?r:e+r,t),v=n.match(/mac_from='([^']+)'/)?.[1],i=n.match(/mac_url='([^']+)'/)?.[1];if(v&&i){a.vod_play_from=v;try{a.vod_play_url=unescape(i)}catch(n){a.vod_play_url=i}}}return JSON.stringify({list:[a]})}async function c(n,e,t){let a=0,r=function(n){if(!n)return"";if((n=n.replace(/#+$/,"")).length<66)return"";let e=n.substring(0,66),t=n.substring(66),i="";for(let n=0;n<e.length;n+=2)i+=e[n];let a=i+t.replace(/O0O0O/g,"=").replace(/oo00o/g,"/").replace(/o000o/g,"+");try{return v.enc.Utf8.stringify(v.enc.Base64.parse(a))}catch(n){return""}}(e);if(!r||!r.startsWith("http")){let n="https://api.nmvod.me:520/player/?url=",v=await d(`${n}${e}`);r=v.match(/"url"\s*:\s*"([^"]+)"/)?.[1]?.replace(/\\\//g,"/"),r||(r=`${n}${e}`,a=1)}return JSON.stringify({parse:a,url:r,header:{"User-Agent":i["User-Agent"]}})}function m(n){let v=[];return n(".globalPicList li, .resize_list li").each((e,t)=>{let i=n(t).find("a"),a=i.attr("href");if(a?.includes("vod-detail-id")){let n=i.find("img").attr("data-echo")||i.find("img").attr("src");v.push({vod_id:a,vod_name:i.attr("title")||i.find(".sTit").text().trim(),vod_pic:p(n),vod_remarks:i.find(".sBottom span").text().replace(/<em>.*<\/em>/g,"").trim()||i.find(".covericon").text().trim()})}}),v}function p(n){return n?(n.startsWith("//")?n="http:"+n:n.startsWith("/")&&(n=e+n),n):""}async function d(n,v){let t={...i,Referer:v||e+"/","sec-fetch-site":v?"same-origin":"none"};return(await req(n,{headers:t})).content}export function __jsEvalReturn(){return{init:a,home:r,homeVod:()=>s("home",1,0,{}),category:s,search:o,detail:l,play:c}}
+318
View File
@@ -0,0 +1,318 @@
/*
title: '星辰影院', author: '小可乐/v6.1.1'
说明:可以不写ext,也可以写ext,ext支持的参数和格式参数如下
"ext": {
"host": "xxxx", //站点网址
"timeout": 6000, //请求超时,单位毫秒
"catesSet": "电视剧&电影&综艺", //指定分类和顺序
"tabsSet": "土星&下载线1" //指定线路和顺序
}
*/
const MOBILE_UA = 'Mozilla/5.0 (Linux; Android 11; Pixel 5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.91 Mobile Safari/537.36';
const DefHeader = {'User-Agent': MOBILE_UA};
var HOST;
var KParams = {
headers: {'User-Agent': MOBILE_UA},
timeout: 5000
};
async function init(cfg) {
try {
HOST = (cfg.ext?.host?.trim() || 'https://www.xcyycn.com').replace(/\/$/, '');
KParams.headers['Referer'] = HOST;
let parseTimeout = parseInt(cfg.ext?.timeout?.trim(), 10);
if (parseTimeout > 0) {KParams.timeout = parseTimeout;}
KParams.catesSet = cfg.ext?.catesSet?.trim() || '';
KParams.tabsSet = cfg.ext?.tabsSet?.trim() || '';
KParams.resHtml = await request(HOST);
} catch (e) {
console.error('初始化参数失败:', e.message);
}
}
async function home(filter) {
try {
let resHtml = KParams.resHtml;
if (!resHtml) {throw new Error('源码为空');}
let typeArr = cutStr(resHtml, 'hl-nav-item£>', '</li>', '', false, 0, true).filter(flt => flt.includes('/v/'));
let classes = typeArr.map((it,idx) => {
let cName = cutStr(it, '>', '<', `分类${idx+1}`);
let cId = cutStr(it, '/v/', '.', `${idx+1}`);
return {type_name: cName, type_id: cId};
});
if (KParams.catesSet) {classes = ctSet(classes, KParams.catesSet);}
let filters = {};
try {
const nameObj = {class: 'class,剧情', area: 'area,地区', lang: 'lang,语言', year: 'year,年份', letter: 'letter,字母', by: 'by,排序'};
const regObj = {class: /\d+---([^-]+)-/, area: /\/\d+-([^-]+)-/, lang: /\d+----([^-]+)-/, year: /-([^-]+)\./, letter: /\d+-----([^-]+)-/, by: /\d+--([^-]+)-/};
let resHtmlList = await Promise.all(
classes.map(async (it) => {
try {return await request(`${HOST}/vs/${it.type_id}-----------.html`);} catch (sErr) {return '';}
})
);
classes.forEach((it,idx) => {
let resfHtml = resHtmlList[idx];
if (resfHtml) {
let flValArr = cutStr(resfHtml, 'hl-filter-list', '</ul>', '', false, 0, true).slice(1);
filters[it.type_id] = Object.entries(nameObj).map(([nObjk, nObjv]) => {
let [kkey, kname] = nObjv.split(',');
let tgVal = flValArr.find(fv => regObj[kkey].test(fv)) ?? '';
if (kkey === 'by') {tgVal = cutStr(resfHtml, 'hl-rb-title', '</div>', '', false);}
let tgValArr = cutStr(tgVal, '<a', '/a>', '', false, 0, true);
let tValArr = kkey !== 'by' ? tgValArr.slice(1) : tgValArr;
let kvalue = tValArr.map(el => {
let n = cutStr(el, '>', '<', '空白');
let v = n;
if (kkey === 'by') {v = el.match(regObj[kkey])?.[1] ?? '';}
return {n: n, v: v};
});
if (kkey !== 'by') {kvalue.unshift({n: '全部', v: ''});}
return {key: kkey, name: kname, value: kvalue};
}).filter(flt => flt.key && flt.value.length > 1);
}
});
} catch (e) {
filters = {}
}
return JSON.stringify({class: classes, filters: filters});
} catch (e) {
console.error('获取分类失败:', e.message);
return JSON.stringify({class: [], filters: {}});
}
}
async function homeVod() {
try {
let resHtml = KParams.resHtml;
let VODS = getVodList(resHtml);
return JSON.stringify({list: VODS});
} catch (e) {
console.error('推荐页获取失败:', e.message);
return JSON.stringify({list: []});
}
}
async function category(tid, pg, filter, extend) {
try {
pg = parseInt(pg, 10), pg = pg > 0 ? pg : 1;
let fl = extend || {};
let cateUrl = `${HOST}/vs/${fl.cateId || tid}-${fl.area ?? ''}-${fl.by ?? ''}-${fl.class ?? ''}-${fl.lang ?? ''}-${fl.letter ?? ''}---${pg}---${fl.year ?? ''}.html`;
let resHtml = await request(cateUrl);
let VODS = getVodList(resHtml);
let limit = VODS.length;
let pagecount = cutStr(resHtml, 'hl-page-total£/', '页', '1');
pagecount = Number(pagecount);
return JSON.stringify({list: VODS, page: pg, pagecount: pagecount, limit: limit, total: limit*pagecount});
} catch (e) {
console.error('类别页获取失败:', e.message);
return JSON.stringify({list: [], page: 1, pagecount: 0, limit: 30, total: 0});
}
}
async function search(wd, quick, pg) {
try {
pg = parseInt(pg, 10), pg = pg > 0 ? pg : 1;
let searchUrl = `${HOST}/s${wd}/page/${pg}.html`;
let resHtml = await request(searchUrl);
let VODS = getVodList(resHtml);
return JSON.stringify({list: VODS, page: pg, pagecount: 10, limit: 30, total: 300});
} catch (e) {
console.error('搜索页获取失败:', e.message);
return JSON.stringify({list: [], page: 1, pagecount: 0, limit: 30, total: 0});
}
}
function getVodList(khtml) {
try {
if (!khtml) {throw new Error('源码为空');}
let kvods = [];
let listArr = cutStr(khtml, 'hl-lazy', '</a>', '', false, 0, true).filter(flt => flt.includes('remarks'));
for (let it of listArr) {
let kname = cutStr(it, 'title="', '"', '名称');
let kpic = cutStr(it, 'data-original="', '"', '图片');
let kremarks = cutStr(it, 'remarks">', '</', '状态');
let kid = cutStr(it, 'href="', '"');
if (kid) {
kvods.push({
vod_name: kname,
vod_pic: kpic,
vod_remarks: kremarks,
vod_id: `${kid}@${kname}@${kpic}@${kremarks}`
});
}
}
return kvods;
} catch (e) {
console.error(`生成视频列表失败:`, e.message);
return [];
}
}
async function detail(ids) {
try {
let [id, kname, kpic, kremarks] = ids.split('@');
let detailUrl = !/^http/.test(id) ? `${HOST}${id}` : id;
let resHtml = await request(detailUrl);
if (!resHtml) {throw new Error('源码为空');}
let intros = cutStr(resHtml, '"clearfix">', '</ul>', '', false);
let [ktabs, kurls] = [[], []];
let zx_tabs = cutStr(resHtml, '<span class="hl-from', '/span>', '', false, 0, true).map((it,idx) => cutStr(it, '>', '<', `在线${idx+1}`) );
ktabs.push(...zx_tabs);
let zx_urls = cutStr(resHtml, 'hl-plays-list">', '</ul>', '', false, 0, true).map((item,idx) => cutStr(item, '<li', '</li>', '', false, 0, true).map(it => { return cutStr(it, '>', '</a>', 'noEpi') + '$' + HOST + cutStr(it, 'href="', '"', 'noUrl'); }).join('#') );
kurls.push(...zx_urls);
let xzArr = cutStr(resHtml, 'hl-downs-list hl', '</ul>', '', false, 0, true);
if (xzArr[0]) {
xzArr.forEach((item,idx) => {
let siglUrl = cutStr(item, 'down_url', '>', '', false, 0, true).map(it => `${cutStr(it, 'file_name="', '"', 'noEpi')}$${cutStr(it, 'value="', '"', 'noUrl')}` ).join('#');
ktabs.push(`下载线${idx+1}`);
kurls.push(siglUrl);
});
}
if (KParams.tabsSet) {
let ktus = ktabs.map((it, idx) => { return {type_name: it, type_value: kurls[idx]} });
ktus = ctSet(ktus, KParams.tabsSet);
ktabs = ktus.map(it => it.type_name);
kurls = ktus.map(it => it.type_value);
}
let VOD = {
vod_id: detailUrl,
vod_name: kname,
vod_pic: kpic,
vod_remarks: kremarks,
type_name: cutStr(intros, '类型:', '</li>', '类型'),
vod_year: cutStr(intros, '年份:', '</li>', '1000'),
vod_area: cutStr(intros, '地区:', '</li>', '地区'),
vod_lang: cutStr(intros, '语言:', '</li>', '语言'),
vod_director: cutStr(intros, '导演:', '</li>', '导演'),
vod_actor: cutStr(intros, '主演:', '</li>', '主演'),
vod_content: cutStr(intros, '简介:', '</li>', kname),
vod_play_from: ktabs.join('$$$'),
vod_play_url: kurls.join('$$$')
};
return JSON.stringify({list: [VOD]});
} catch (e) {
console.error('详情页获取失败:', e.message);
return JSON.stringify({list: []});
}
}
async function play(flag, ids, flags) {
try {
let kp = 0, kurl = '';
if (/下载/.test(flag)) {
kurl = ids;
} else {
let resHtml = await request(ids);
let codeObj = safeParseJSON(cutStr(resHtml, 'var player_£=', '<', '', false));
kurl = codeObj?.url ?? '';
if (!/^http/.test(kurl)) {
kurl = ids;
kp = 1;
}
}
return JSON.stringify({jx: 0, parse: kp, url: kurl, header: DefHeader});
} catch (e) {
console.error('播放失败:', e.message);
return JSON.stringify({jx: 0, parse: 0, url: '', header: {}});
}
}
function ctSet(kArr, setStr) {
try {
if (!Array.isArray(kArr) || kArr.length === 0 || typeof setStr !== 'string' || !setStr) { throw new Error('第一参数需为非空数组,第二参数需为非空字符串'); }
const set_arr = [...kArr];
const arrNames = setStr.split('&');
const filtered_arr = arrNames.map(item => set_arr.find(it => it.type_name === item)).filter(Boolean);
return filtered_arr.length? filtered_arr : [set_arr[0]];
} catch (e) {
console.error('ctSet 执行异常:', e.message);
return kArr;
}
}
function safeParseJSON(jStr){
try {return JSON.parse(jStr);} catch(e) {return null;}
}
function cutStr(str, prefix = '', suffix = '', defVal = '', clean = true, i = 0, all = false) {
try {
if (typeof str !== 'string') {throw new Error('被截取对象必须为字符串');}
const cleanStr = cs => String(cs).replace(/<[^>]*?>/g, ' ').replace(/(&nbsp;|[\u0020\u00A0\u3000\s])+/g, ' ').trim().replace(/\s+/g, ' ');
const esc = s => String(s).replace(/[.*+?${}()|[\]\\/^]/g, '\\$&');
let pre = esc(prefix).replace(/£/g, '[^]*?'), end = esc(suffix);
const regex = new RegExp(`${pre || '^'}([^]*?)${end || '$'}`, 'g');
const matchIter = str.matchAll(regex);
if (all) {
let matchArr = [...matchIter];
if (!matchArr.length) {return [defVal];}
return matchArr.map(ela => ela[1] !== undefined ? (clean ? cleanStr(ela[1]) : ela[1]) : defVal);
}
const idx = parseInt(i, 10);
if (isNaN(idx)) {throw new Error('序号必须为整数');}
let tgResult, matchIdx = 0;
if (idx >= 0) {
for (let elt of matchIter) {
if (matchIdx++ === idx) {
tgResult = elt[1];
break;
}
}
} else {
let absI = Math.abs(idx), ringBuf = new Array(absI), ringPtr = 0, ringCnt = 0;
for (let elt of matchIter) {
ringBuf[ringPtr] = elt[1];
ringPtr = (ringPtr + 1) % absI;
ringCnt = Math.min(ringCnt + 1, absI);
matchIdx++;
}
tgResult = (matchIdx >= absI && ringCnt > 0) ? ringBuf[ringPtr % ringCnt] : undefined;
}
return tgResult !== undefined ? (clean ? (cleanStr(tgResult) || defVal) : tgResult) : defVal;
} catch (e) {
console.error(`字符串截取错误:`, e.message);
return all ? ['cutErr'] : 'cutErr';
}
}
async function request(reqUrl, options = {}) {
try {
if (typeof reqUrl !== 'string' || !reqUrl.trim()) { throw new Error('reqUrl需为字符串且非空'); }
if (typeof options !== 'object' || Array.isArray(options) || options === null) { throw new Error('options类型需为非null对象'); }
options.method = options.method?.toUpperCase() || 'GET';
if (['GET', 'HEAD'].includes(options.method)) {
delete options.body;
delete options.data;
delete options.postType;
}
let {headers, timeout, ...restOpts} = options;
const optObj = {
headers: (typeof headers === 'object' && !Array.isArray(headers) && headers) ? headers : KParams.headers,
timeout: parseInt(timeout, 10) > 0 ? parseInt(timeout, 10) : KParams.timeout,
...restOpts
};
const res = await req(reqUrl, optObj);
if (options.withHeaders) {
const resHeaders = typeof res.headers === 'object' && !Array.isArray(res.headers) && res.headers ? res.headers : {};
const resWithHeaders = { ...resHeaders, body: res?.content ?? '' };
return JSON.stringify(resWithHeaders);
}
return res?.content ?? '';
} catch (e) {
console.error(`${reqUrl}→请求失败:`, e.message);
return options?.withHeaders ? JSON.stringify({ body: '' }) : '';
}
}
export function __jsEvalReturn() {
return {
init,
home,
homeVod,
category,
search,
detail,
play,
proxy: null
};
}
+108
View File
@@ -0,0 +1,108 @@
let host = 'https://www.ylys.tv';
let headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
"Referer": host + "/",
"Accept-Language": "zh-CN,zh;q=0.9"
};
const init = async () => {};
const extractVideos = html => {
if (!html) return [];
return pdfa(html, '.module-item,.module-card-item').map(it => {
const href = pdfh(it, 'a&&href') || '';
const id = href.match(/voddetail\/(\d+)/)?.[1];
const name = pdfh(it, 'a&&title') || pdfh(it, 'strong&&Text') || pdfh(it, '.module-item-title&&Text') || "";
const pic = pdfh(it, 'img&&data-original') || pdfh(it, 'img&&src') || "";
const remarks = pdfh(it, '.module-item-text&&Text') || pdfh(it, '.module-item-note&&Text') || "";
if (!id || !name) return null;
return {
vod_id: id,
vod_name: name.trim(),
vod_pic: pic.startsWith('/') ? host + pic : pic,
vod_remarks: remarks.trim()
};
}).filter(Boolean);
};
const generateFilters = () => {
const currentYear = new Date().getFullYear();
const years = [{n:"全部",v:""}, ...Array.from({length:15},(_,i)=>{const y=currentYear-i;return{n:y+"",v:y+""}})];
return {
"1": [{"key":"class","name":"类型","value":[{"n":"全部","v":""},{"n":"动作片","v":"6"},{"n":"喜剧片","v":"7"},{"n":"爱情片","v":"8"},{"n":"科幻片","v":"9"},{"n":"恐怖片","v":"11"}]},{"key":"year","name":"年份","value":years}],
"2": [{"key":"class","name":"类型","value":[{"n":"全部","v":""},{"n":"国产剧","v":"13"},{"n":"港台剧","v":"14"},{"n":"日剧","v":"15"},{"n":"韩剧","v":"33"},{"n":"欧美剧","v":"16"}]},{"key":"year","name":"年份","value":years}],
"3": [{"key":"class","name":"类型","value":[{"n":"全部","v":""},{"n":"内地综艺","v":"27"},{"n":"港台综艺","v":"28"},{"n":"日本综艺","v":"29"},{"n":"韩国综艺","v":"36"}]},{"key":"year","name":"年份","value":years}],
"4": [{"key":"class","name":"类型","value":[{"n":"全部","v":""},{"n":"国产动漫","v":"31"},{"n":"日本动漫","v":"32"},{"n":"欧美动漫","v":"42"},{"n":"其他动漫","v":"43"}]},{"key":"year","name":"年份","value":years}]
};
};
const homeVod = async () => {
const resp = await req(host, { headers });
return JSON.stringify({ list: extractVideos(resp?.content || '') });
};
const home = async () => {
const { list } = JSON.parse(await homeVod());
return JSON.stringify({
class: [
{type_id:"1",type_name:"电影"},
{type_id:"2",type_name:"剧集"},
{type_id:"3",type_name:"综艺"},
{type_id:"4",type_name:"动漫"}
],
filters: generateFilters(),
list
});
};
const category = async (tid, pg, _, extend) => {
const cat = extend?.class || tid;
const year = extend?.year || '';
const url = `${host}/vodshow/${cat}--------${pg}---${year}/`;
const html = (await req(url, { headers }))?.content || '';
const list = extractVideos(html);
const pagecount = html.match(/page\/(\d+)\/[^>]*>尾页/) ? +RegExp.$1 : 999;
return JSON.stringify({ list, page: +pg, pagecount, limit: 20 });
};
const detail = async id => {
const html = (await req(`${host}/voddetail/${id}/`, { headers }))?.content || '';
if (!html) return JSON.stringify({ list: [] });
let tabs = pdfa(html, '.module-tab-item');
const lists = pdfa(html, '.module-play-list-content');
if (tabs.length === 0 && lists.length > 0) tabs = ["默认"];
const playFrom = tabs.map(t => pdfh(t, 'span&&Text') || "线路").join('$$$');
const playUrl = lists.slice(0, tabs.length).map(l =>
pdfa(l, 'a').map(a => {
const name = pdfh(a, 'span&&Text') || "播放";
const vid = (pdfh(a, 'a&&href') || "").match(/play\/([^\/]+)/)?.[1];
return vid ? `${name}$${vid}` : null;
}).filter(Boolean).join('#')
).join('$$$');
if (!playFrom || !playUrl) return JSON.stringify({ list: [] });
return JSON.stringify({
list: [{
vod_id: id,
vod_name: (html.match(/<h1>(.*?)<\/h1>/) || ["", ""])[1],
vod_pic: (() => {
const pic = (html.match(/data-original="(.*?)"/) || ["", ""])[1];
return pic?.startsWith('/') ? host + pic : pic || "";
})(),
vod_content: ((html.match(/introduction-content">.*?<p>(.*?)<\/p>/s) || ["", ""])[1]?.replace(/<.*?>/g, "") || ""),
vod_year: (html.match(/href="\/vodshow\/\d+-----------(\d{4})\//) || ["", ""])[1] || "",
vod_director: (html.match(/导演:.*?<a[^>]*>([^<]+)<\/a>/) || ["", ""])[1] || "",
vod_actor: [...html.matchAll(/主演:.*?<a[^>]*>([^<]+)<\/a>/g)]
.map(m => m[1])
.filter(Boolean)
.join(" / "),
vod_play_from: playFrom,
vod_play_url: playUrl
}]
});
};
const search = async (wd, _, pg = 1) => {
const url = `${host}/vodsearch/${encodeURIComponent(wd)}----------${pg}---/`;
const resp = await req(url, { headers });
return JSON.stringify({ list: extractVideos(resp?.content || '') });
};
const play = async (_, id) => {
const url = `${host}/play/${id}/`;
const resp = await req(url, { headers });
const m3u8 = resp?.content?.match(/"url":"([^"]+\.m3u8)"/);
if (m3u8) return JSON.stringify({ parse: 0, url: m3u8[1].replace(/\\/g, ""), header: headers });
return JSON.stringify({ parse: 1, url, header: headers });
};
export default { init, home, homeVod, category, detail, search, play };