update all

This commit is contained in:
qist
2024-04-15 09:41:50 +08:00
parent 78d81a5a85
commit 888a30e219
33 changed files with 1498 additions and 458 deletions

View File

@@ -82,6 +82,15 @@
"timeout": 30,
"ext": "{\"box\": \"CatOpen\", \"danmu\": false}"
},
{
"key": "hanxiucao",
"name": "🔞┃含羞草┃🔞",
"playerType": 0,
"type": 3,
"api": "./js/hanxiucao.js",
"timeout": 30,
"ext": "{\"box\": \"CatOpen\", \"danmu\": false}"
},
{
"key": "push_agent",
"name": "┃推送┃",

View File

@@ -81,6 +81,15 @@
"timeout": 30,
"ext": "{\"box\": \"TVBox\", \"danmu\": false}"
},
{
"key": "hanxiucao",
"name": "🔞┃含羞草┃🔞",
"playerType": 0,
"type": 3,
"api": "./js/hanxiucao.js",
"timeout": 30,
"ext": "{\"box\": \"TVBox\", \"danmu\": false}"
},
{
"key": "push_agent",
"name": "┃推送┃",

View File

@@ -71,9 +71,10 @@ class BilibiliSpider extends Spider {
}
async init(cfg) {
await this.initCookie(cfg["ext"]["cookie"])
await super.init(cfg);
await this.initCookie(this.cfgObj["cookie"])
await this.spiderInit(null)
this.danmuStaus = true
}
getName() {
@@ -230,9 +231,14 @@ class BilibiliSpider extends Spider {
const playUrl = j + '$' + aid + '+' + cid + '+' + qualityList.join(':') + '+' + descriptionList.join(':');
playList.push(playUrl);
}
for (let quality of qualityList) {
treeMap[`dash - ${this.play_url_obj[quality]}`] = playList.join("#")
if (this.catOpenStatus) {
for (let quality of qualityList) {
treeMap[`dash - ${this.play_url_obj[quality]}`] = playList.join("#")
}
} else {
await this.jadeLog.warning("TV暂不支持Dash播放")
}
for (let quality of qualityList) {
treeMap[`mp4 - ${this.play_url_obj[quality]}`] = playList.join("#")
}
@@ -247,9 +253,14 @@ class BilibiliSpider extends Spider {
const playUrl = title + '$' + aaid + '+' + cid + '+' + qualityList.join(':') + '+' + descriptionList.join(':');
playList.push(playUrl);
}
for (let quality of qualityList) {
treeMap["相关" + ` - ${this.play_url_obj[quality]}`] = playList.join("#")
if (this.catOpenStatus) {
for (let quality of qualityList) {
treeMap["相关" + ` - ${this.play_url_obj[quality]}`] = playList.join("#")
}
} else {
await this.jadeLog.warning("TV暂不支持相关播放")
}
vodDetail.vod_play_from = Object.keys(treeMap).join("$$$");
vodDetail.vod_play_url = Object.values(treeMap).join("$$$");
return vodDetail
@@ -301,7 +312,10 @@ class BilibiliSpider extends Spider {
this.result.header = this.getHeader()
if (flag.indexOf("dash") > -1 || flag.indexOf('相关') > -1) {
// dash mpd 代理
this.playUrl = this.js2Base + Utils.base64Encode(aid + '+' + cid + '+' + quality_id)
if (this.catOpenStatus) {
this.playUrl = this.js2Base + Utils.base64Encode(aid + '+' + cid + '+' + quality_id)
}
} else if (flag.indexOf('mp4') > -1) {
// 直链
const url = this.apiUrl + `/x/player/playurl`;

253
cat/tjs/js/cilixiong.js Normal file
View File

@@ -0,0 +1,253 @@
/*
* @File : cilixiong.js
* @Author : jade
* @Date : 2024/4/13 14:52
* @Email : jadehh@1ive.com
* @Software : Samples
* @Desc :
*/
import {_, load} from '../lib/cat.js';
import {VodDetail, VodShort} from "../lib/vod.js"
import * as Utils from "../lib/utils.js";
import {Spider} from "./spider.js"
class CiliXiongSpider extends Spider {
constructor() {
super();
this.siteUrl = "https://www.cilixiong.com"
this.cateObj = {"/movie/": "1", "/drama/": "2"}
}
getAppName() {
return "磁力熊"
}
getName() {
return "🐻┃磁力熊┃🐻"
}
getJSName() {
return "cilixiong"
}
getType() {
return 3
}
async setClasses() {
let $ = await this.getHtml()
let navElements = $("[class=\"nav col-12 col-lg-auto me-lg-auto mb-2 justify-content-center mb-md-0\"]").find("li")
for (const navElement of navElements) {
let element = $(navElement).find("a")[0]
let type_name = $(element).text()
let type_id = element.attribs.href
if (type_name !== "首页" && type_name !== "榜单" && type_name !== "留言") {
this.classes.push(this.getTypeDic(type_name, type_id))
}
}
}
async getFilter($) {
let extend_list = []
let filerElements = $("[class=\"nav small\"]")
let i = 1
for (const filetElement of filerElements) {
let extend_name = $($(filetElement).find("li")[0]).text().replaceAll("", "")
let extend_dic = {"key": (i).toString(), "name": extend_name, "value": []}
for (const typeElement of $(filetElement).find("li").slice(1)) {
let element = $(typeElement).find("a")[0]
let type_id = element.attribs.href.split("-")[i]
extend_dic["value"].push({"n": $(element).text(), "v": type_id})
}
i = i + 1
extend_list.push(extend_dic)
}
return extend_list
}
async setFilterObj() {
for (const type_dic of this.classes) {
let type_id = type_dic["type_id"]
if (type_id !== "最近更新") {
let $ = await this.getHtml(this.siteUrl + type_id)
this.filterObj[type_id] = await this.getFilter($)
}
}
}
async parseVodShortListFromDoc($) {
let vod_list = []
let vodElements = $("[class=\"col\"]")
for (const vodElement of vodElements) {
let vodShort = new VodShort()
vodShort.vod_id = $(vodElement).find("a")[0].attribs.href
vodShort.vod_pic = Utils.getStrByRegex(/background-image: url\('(.*?)'\)/, $(vodElement).find("[class=\"card-img\"]")[0].attribs["style"])
vodShort.vod_name = $($(vodElement).find("h2")).text()
let remarks = $($(vodElement).find("[class=\"rank bg-success p-1\"]")).text()
vodShort.vod_remarks = "评分:" + remarks
if (remarks !== "AD") {
vod_list.push(vodShort)
}
}
return vod_list
}
async parseVodShortListFromDocBySearch($) {
let vod_list = []
let vodElements = $("[class=\"card card-cover h-100 overflow-hidden text-bg-dark rounded-4 shadow-lg position-relative\"]")
for (const vodElement of vodElements){
let vodShort= new VodShort()
vodShort.vod_id = $(vodElement).find("a")[0].attribs.href
vodShort.vod_name = $($(vodElement).find("[class=\"pt-5 lh-1 pb-2 h4\"]")).text()
vodShort.vod_pic = Utils.getStrByRegex(/background-image: url\('(.*?)'\)/,$(vodElement).find("[class=\"card-img\"]")[0].attribs.style)
vodShort.vod_remarks = "评分:" + $($(vodElement).find("[class=\"rank bg-success p-1\"]")).text()
vod_list.push(vodShort)
}
return vod_list
}
async parseVodDetailFromDoc($) {
let vodDetail = new VodDetail()
let vodDetailElement = $("[class=\"row row-cols-1 row-cols-lg-3 align-items-stretch g-4 p-5 text-white\"]")
vodDetail.vod_pic = $(vodDetailElement).find("img")[0].attribs.src
vodDetail.vod_name = $($(vodDetailElement).find("h1")).text()
let vodContentElements = $(vodDetailElement).find("[class=\"mb-2\"]").slice(1)
for (const contentElement of vodContentElements) {
let name = $(contentElement).text()
if (name.indexOf("豆瓣评分") > -1) {
vodDetail.vod_remarks = name
}
if (name.indexOf("类型") > -1) {
vodDetail.type_name = name.replaceAll("", "").replace("类型", "").replaceAll(":", "")
}
if (name.indexOf("上映地区") > -1) {
vodDetail.vod_area = name.replaceAll("", "").replace("上映地区", "").replaceAll(":", "")
}
if (name.indexOf("主演") > -1) {
vodDetail.vod_actor = name.replaceAll("", "").replace("主演", "").replaceAll(":", "")
}
if (name.indexOf("上映日期") > -1){
vodDetail.vod_year = name.replaceAll("", "").replace("上映日期", "").replaceAll(":", "")
}
}
vodDetail.vod_content = $($(vodDetailElement).find("[class=\"mv_card_box\"]")).text()
let playerMap = {}
let emebedVideoElements = $("[class=\"row col-md-12 embed_video\"]")
let index = 1
for (const emebedVideoElement of emebedVideoElements){
let vodItems = []
let playUrl = $($(emebedVideoElement).find("iframe"))[0].attribs["src"]
vodItems.push("播放" + "$" + playUrl);
playerMap["在线播放" + index.toString()+ "第一集在线播放预览"] = vodItems.join("#")
index = index + 1
}
let mangetIndex = 1
let mangetElements = $("[class=\"row col-md-12 text-white p-3 pt-1\"]").find("[class=\"container\"]")
for (const mangenment of mangetElements){
let vodItems = []
let playElement = $($(mangenment).find("a"))[0]
let playUrl = playElement.attribs.href
let playName = $(playElement).text()
if (playUrl.startsWith("magnet")){
vodItems.push(playName + "$" + playUrl);
}
if (vodItems.length > 0){
playerMap["磁力链接" + "-" + mangetIndex] = vodItems.join("#")
mangetIndex = mangetIndex + 1
}
}
vodDetail.vod_play_from = Object.keys(playerMap).join("$$$");
vodDetail.vod_play_url = Object.values(playerMap).join("$$$");
return vodDetail
}
async setHomeVod() {
let $ = await this.getHtml()
this.homeVodList = await this.parseVodShortListFromDoc($)
}
async setCategory(tid, pg, filter, extend) {
let type = extend["1"] ?? "0"
let area = extend["2"] ?? "0"
let page = parseInt(pg) - 1
let url = this.siteUrl + "/" + this.cateObj[tid] + `-${type}-${area}-${page}.html`
await this.jadeLog.debug(`分类URL:${url}`)
let $ = await this.getHtml(url)
this.vodList = await this.parseVodShortListFromDoc($)
}
async setDetail(id) {
let $ = await this.getHtml(this.siteUrl + id)
this.vodDetail = await this.parseVodDetailFromDoc($)
}
async setPlay(flag, id, flags) {
if (flag.indexOf("在线播放") > -1){
let $ = await this.getHtml(this.siteUrl + id)
this.playUrl = Utils.getStrByRegex(/const source = '(.*?)'/,$.html())
}else{
this.playUrl = id
}
}
async setSearch(wd, quick) {
let params = {"classid":"1,2","show":"title","tempid":"1","keyboard":wd}
let response = await this.post(this.siteUrl + "/e/search/index.php",params,this.getHeader())
let $ = load(response)
this.vodList = await this.parseVodShortListFromDocBySearch($)
}
}
let spider = new CiliXiongSpider()
async function init(cfg) {
await spider.init(cfg)
}
async function home(filter) {
return await spider.home(filter)
}
async function homeVod() {
return await spider.homeVod()
}
async function category(tid, pg, filter, extend) {
return await spider.category(tid, pg, filter, extend)
}
async function detail(id) {
return await spider.detail(id)
}
async function play(flag, id, flags) {
return await spider.play(flag, id, flags)
}
async function search(wd, quick) {
return await spider.search(wd, quick)
}
async function proxy(segments, headers) {
return await spider.proxy(segments, headers)
}
export function __jsEvalReturn() {
return {
init: init,
home: home,
homeVod: homeVod,
category: category,
detail: detail,
play: play,
search: search,
proxy: proxy
};
}
export {spider}

View File

@@ -17,12 +17,17 @@ class Doll extends Spider {
super();
this.siteUrl = "https://hongkongdollvideo.com"
}
getImgHeader(){
let headers = this.getHeader()
headers["Proxy"] = true
return headers
}
async spiderInit(inReq = null) {
if (inReq !== null) {
this.jsBase = await js2Proxy(inReq, "img", {});
this.jsBase = await js2Proxy(inReq, "img", this.getImgHeader());
} else {
this.jsBase = await js2Proxy(true, this.siteType, this.siteKey, 'img/', {});
this.jsBase = await js2Proxy(true, this.siteType, this.siteKey, 'img/', this.getImgHeader());
}
}
@@ -61,11 +66,12 @@ class Doll extends Spider {
vodShort.vod_name = videoInfoElements[0].attribs["title"]
vodShort.vod_remarks = $(videoInfoElements[1]).text()
let pic = $(vodElement).find("img")[0].attribs["data-src"]
if (this.catOpenStatus) {
vodShort.vod_pic = this.jsBase + Utils.base64Encode(pic)
} else {
vodShort.vod_pic = pic
}
// if (this.catOpenStatus) {
// vodShort.vod_pic = this.jsBase + Utils.base64Encode(pic)
// } else {
// vodShort.vod_pic = pic
// }
vodShort.vod_pic = pic
vod_list.push(vodShort)
}
@@ -78,11 +84,12 @@ class Doll extends Spider {
vodDetail.vod_name = $($(vodElement).find("[class=\"page-title\"]")[0]).text()
vodDetail.vod_remarks = $(vodElement).find("[class=\"tag my-1 text-center\"]")[0].attribs["href"].replaceAll("/", "")
let pic = $(vodElement).find("video")[0].attribs["poster"]
if (this.catOpenStatus) {
vodDetail.vod_pic = this.jsBase + Utils.base64Encode(pic)
} else {
vodDetail.vod_pic = pic
}
// if (this.catOpenStatus) {
// vodDetail.vod_pic = this.jsBase + Utils.base64Encode(pic)
// } else {
// vodDetail.vod_pic = pic
// }
vodDetail.vod_pic = pic
let html = $.html()
let voteTag = Utils.getStrByRegex(/var voteTag="(.*?)";/g, html)
// let videoInfoStr = Utils.getStrByRegex(/<script type="application\/ld\+json">(.*?)<\/script>/g, html)

625
cat/tjs/js/hanxiucao.js Normal file
View File

@@ -0,0 +1,625 @@
/*
* @File : hanxiucao.js
* @Author : jade
* @Date : 2024/04/13 19:38
* @Email : jadehh@1ive.com
* @Software : Samples
* @Desc :
*/
import {_, Crypto} from '../lib/cat.js';
import {VodDetail, VodShort} from "../lib/vod.js"
import {Spider} from "./spider.js";
import * as Utils from "../lib/utils.js";
function He(e, {key: t, iv: s} = {}) {
let VITE_APP_AES_KEY = "B77A9FF7F323B5404902102257503C2F"
let VITE_APP_AES_IV = "B77A9FF7F323B5404902102257503C2F"
var o = Crypto.enc.Utf8.parse(e)
, A = Crypto.AES.encrypt(o, Crypto.enc.Utf8.parse(t || VITE_APP_AES_KEY), {
iv: Crypto.enc.Utf8.parse(s || VITE_APP_AES_IV),
mode: Crypto.mode.CBC,
padding: Crypto.pad.Pkcs7
});
return Crypto.enc.Base64.stringify(A.ciphertext)
}
function Kt() {
const e = new Date;
return He(parseInt(e.getTime() / 1e3) + e.getTimezoneOffset() * 60 + -1)
}
function bt(e) {
const wA = "46cc793c53dc451b"
let t = Crypto.enc.Utf8.parse(wA)
, s = Crypto.AES.decrypt(e, t, {
mode: Crypto.mode.ECB,
padding: Crypto.pad.Pkcs7
});
return Crypto.enc.Utf8.stringify(s).toString()
}
class HanXiuCaoSpider extends Spider {
constructor() {
super();
this.siteUrl = "https://api.qianyuewenhua.xyz"
}
async spiderInit(inReq = null) {
if (inReq !== null) {
this.jsBase = await js2Proxy(inReq, "imgBt", this.getHeader());
} else {
this.jsBase = await js2Proxy(true, this.siteType, this.siteKey, 'imgBt/', this.getHeader());
}
}
async init(cfg) {
await super.init(cfg);
this.danmuStaus = true
await this.spiderInit(null)
}
getAppName() {
return "含羞草"
}
getName() {
return "🔞┃含羞草┃🔞"
}
getJSName() {
return "hanxiucao"
}
getType() {
return 3
}
getParams(params) {
return {"endata": He(JSON.stringify(params)), "ents": Kt()}
}
async setClasses() {
let params = this.getParams({"channel": "pc"})
let response = await this.post(this.siteUrl + "/panel/list", params, this.getHeader(), "")
let resJson = JSON.parse(response)
for (const data of resJson["data"]["list"]) {
let type_id = data["panelId"]
let type_name = data["panelName"]
if (type_name !== "首页") {
this.classes.push(this.getTypeDic(type_name, type_id))
}
}
}
async getFilter(Layouts) {
let extend_list = []
for (const data of Layouts) {
let layoutObj = JSON.parse(data["layoutContent"])
for (const layout of layoutObj["sortKeys"]) {
let extend_dic = {}
if (layout["label"] !== "综合排序") {
extend_dic = {"key": "sorts", "name": layout["label"].toString(), value: []}
extend_dic["value"].push({"n": "升序", "v": layout["value"].toString() + "-" + "升序"})
extend_dic["value"].push({"n": "降序", "v": layout["value"].toString() + "-" + "降序"})
} else {
extend_dic = {"key": "sorts", "name": "排序", value: []}
extend_dic["value"].push({"n": layout["label"].toString(), "v": layout["value"].toString()})
}
extend_list.push(extend_dic)
}
}
return extend_list
}
async getNvYouFilter(Layouts) {
let extend_list = []
let params = {
"uids": [],
"page": 1,
"length": 20
}
for (let i = 0; i < Layouts.length; i++) {
let data = Layouts[i]
let layoutObj = JSON.parse(data["layoutContent"])
params["uids"] = layoutObj["list"]
let resJson = JSON.parse(await this.post(this.siteUrl + "/user/getUpList", this.getParams(params), this.getHeader(), ""))
let extend_dic = {"key": `tags`, "name": data["layoutName"], value: []}
for (const layout of resJson["data"]["list"]) {
extend_dic["value"].push({"n": layout["user_nicename"], "v": JSON.stringify(layout)})
}
extend_list.push(extend_dic)
}
let sort_list = [
{
"key": "sorts",
"name": "发布时间",
"value": [
{
"n": "升序",
"v": "1-升序"
},
{
"n": "降序",
"v": "1-降序"
}
]
},
{
"key": "sorts",
"name": "点赞数量",
"value": [
{
"n": "升序",
"v": "5-升序"
},
{
"n": "降序",
"v": "5-降序"
}
]
},
{
"key": "sorts",
"name": "收藏数量",
"value": [
{
"n": "升序",
"v": "6-升序"
},
{
"n": "降序",
"v": "6-降序"
}
]
}
]
return [...extend_list, ...sort_list]
}
async getZhuanTiFilter(Layouts) {
let extend_list = []
let params = {
"page": 1,
"length": 36,
"subjectIds": []
}
for (let i = 0; i < Layouts.length; i++) {
let data = Layouts[i]
let layoutObj = JSON.parse(data["layoutContent"])
params["subjectIds"] = layoutObj["list"]
let resJson = JSON.parse(await this.post(this.siteUrl + "/subject/list", this.getParams(params), this.getHeader(), ""))
let extend_dic = {"key": `tags`, "name": data["layoutName"], value: []}
for (const layout of resJson["data"]["list"]) {
extend_dic["value"].push({"n": layout["name"], "v": JSON.stringify(layout)})
}
extend_list.push(extend_dic)
}
let sort_dic = {
"key": "sorts",
"name": "排序",
"value": [
{
"n": "推荐",
"v": "8"
},
{
"n": "最新",
"v": "1"
},
{
"n": "最热",
"v": "2"
}
]
}
extend_list.push(sort_dic)
return extend_list
}
async getChuanMeiFilter(Layouts) {
let extend_list = []
let extend_dic = {"key": `tags`, "name": "传媒", value: []}
for (let i = 0; i < Layouts.length; i++) {
let data = Layouts[i]
extend_dic["value"].push({"n": data["layoutName"], "v": data["layoutContent"]})
}
extend_list.push(extend_dic)
for (const layout of JSON.parse(Layouts[0]["layoutContent"])["moreOrderType"]) {
extend_dic = {"key": "sorts", "name": layout["label"].toString(), value: []}
extend_dic["value"].push({"n": "升序", "v": layout["value"].toString() + "-" + "升序"})
extend_dic["value"].push({"n": "降序", "v": layout["value"].toString() + "-" + "降序"})
extend_list.push(extend_dic)
}
extend_list.push(extend_dic)
return extend_list
}
async getHeJiFilter(Layouts) {
let extend_list = []
let params = {
"page": 1,
"length": 24,
"gatherType": 1,
"gatherIds": []
}
let extend_dic = {"key": `tags`, "name": "合集", value: []}
let resJson = JSON.parse(await this.post(this.siteUrl + "/gather/getList", this.getParams(params), this.getHeader(), ""))
for (const data of resJson["data"]["list"]) {
extend_dic["value"].push({"n": data["name"], "v": data["gatherId"].toString()})
}
extend_list.push(extend_dic)
return extend_list
}
async setFilterObj() {
for (let i = 0; i < this.classes.length; i++) {
let type_dic = this.classes[i]
let type_id = type_dic["type_id"]
let type_name = type_dic["type_name"]
let filterList = []
if (type_id !== "最近更新") {
type_id = parseInt(type_id)
let params = this.getParams({"panelId": type_id})
let response = await this.post(this.siteUrl + "/panel/get", params, this.getHeader(), "")
let resJson = JSON.parse(response)
let layoutList = resJson["data"]["info"]["Layouts"]
let layOutObj = JSON.parse(resJson["data"]["info"]["Layouts"][0]["layoutContent"])
if (type_id > 174 && type_id < 181) {
let layOutObj = JSON.parse(resJson["data"]["info"]["Layouts"][0]["layoutContent"])
type_id = type_id + "$" + JSON.stringify(layOutObj)
filterList = await this.getFilter(layoutList)
} else {
switch (type_id) {
case 172:
filterList = await this.getHeJiFilter(layoutList)
type_id = type_id + "$" + filterList[0]["value"][0]["v"]
break
case 173:
filterList = await this.getChuanMeiFilter(layoutList)
type_id = type_id + "$" + JSON.stringify(layOutObj)
break
case 182:
filterList = await this.getNvYouFilter(layoutList)
type_id = type_id + "$" + filterList[0]["value"][0]["v"]
break
case 209:
filterList = await this.getZhuanTiFilter(layoutList)
type_id = type_id + "$" + filterList[0]["value"][0]["v"]
break
default:
break
}
}
this.classes[i] = this.getTypeDic(type_name, type_id)
this.filterObj[type_id] = filterList
}
}
}
async parseVodShortListFromJson(obj) {
let vod_list = []
for (const data of obj) {
let vodShort = new VodShort()
vodShort.vod_id = data["id"]
vodShort.vod_name = data["name"]
vodShort.vod_pic = this.jsBase + Utils.base64Encode(data["coverImgUrl"])
if (data["hot"] === undefined) {
vodShort.vod_remarks = "观看:" + (data["seeCount"] / 10000).toFixed(1).toString() + "W"
} else {
vodShort.vod_remarks = "热度:" + (data["hot"] / 1000).toFixed(1).toString() + "K"
}
vod_list.push(vodShort)
}
return vod_list
}
async parseVodShortListFromGatherJson(obj) {
let vod_list = []
for (const data of obj) {
let vodShort = new VodShort()
vodShort.vod_id = data["gatherId"]
vodShort.vod_name = data["name"]
vodShort.vod_pic = this.jsBase + Utils.base64Encode(data["coverImgUrl"])
vod_list.push(vodShort)
}
return vod_list
}
async parseVodDetailFromDoc(detailObj) {
let vodDetail = new VodDetail()
vodDetail.vod_name = detailObj["name"]
vodDetail.vod_year = detailObj["addTime"]
vodDetail.vod_pic = this.jsBase + Utils.base64Encode(detailObj["coverImgUrl"])
vodDetail.type_name = detailObj["typeName"]
vodDetail.vod_content = detailObj["tags"]
let vodItems = []
let params = {
"videoId": detailObj["id"]
}
let resJson = JSON.parse(await this.post(this.siteUrl + "/videos/getPreUrl", this.getParams(params), this.getHeader(), ""))
let playList = resJson["data"]["url"].split("?")
let playUrl = playList[0] + "?sign" + playList[1].split("&sign").slice(-1)[0]
vodItems.push(vodDetail.vod_name + "$" + playUrl)
let playObj = {"线路1": vodItems.join("#")}
vodDetail.vod_play_url = _.values(playObj).join('$$$');
vodDetail.vod_play_from = _.keys(playObj).join('$$$');
return vodDetail
}
async getHomeVod(params) {
let params_str = this.getParams(params)
let response = await this.post(this.siteUrl + "/videos/getList", params_str, this.getHeader(), "")
return await this.parseVodShortListFromJson(JSON.parse(response)["data"]["list"])
}
async setHomeVod() {
let vod_list1 = await this.getHomeVod({
"page": 1,
"length": 16,
"offset": 0,
"typeIds": [],
"orderType": 1,
"payType": [3, 4]
})
let vod_list2 = await this.getHomeVod({
"page": 1,
"length": 16,
"offset": 0,
"typeIds": [],
"orderType": 3,
"payType": [
1
]
})
let vod_list3 = await this.getHomeVod({
"page": 1,
"length": 32,
"offset": 0,
"typeIds": [],
"orderType": 1,
"payType": [
3
]
})
this.homeVodList = [...vod_list1, ...vod_list2, ...vod_list3];
}
getSortParams(params, extend) {
let orderTypeStr = extend["sorts"] ?? ""
if (!_.isEmpty(orderTypeStr)) {
let orderType = orderTypeStr.split("-")[0]
params["orderType"] = parseInt(orderType)
let orderModeStr = orderTypeStr.split("-")[1]
let orderMode = 0
if (orderModeStr === "升序") {
orderMode = "1"
} else {
orderMode = "0"
}
params["orderMode"] = parseInt(orderMode)
}
return params
}
getTopParams(type_id, layOutObj, pg, extend) {
let defaultOderType
if (type_id === 180) {
defaultOderType = "1"
} else {
defaultOderType = "7"
}
let orderMode = "1"
let orderType
let orderTypeStr = extend["sorts"] ?? defaultOderType
let isOrderModel = false
if (orderTypeStr.indexOf("-") > -1) {
orderType = orderTypeStr.split("-")[0]
let orderModeStr = orderTypeStr.split("-")[1]
if (orderModeStr === "升序") {
orderMode = "1"
} else {
orderMode = "0"
}
isOrderModel = true
} else {
orderType = defaultOderType
}
let params = {
"orderType": parseInt(orderType), //或者7
"tags": [],
"length": 11,
"page": parseInt(pg),
"typeIds": layOutObj["classs"],
"payType": layOutObj["payType"],
}
if (isOrderModel) {
params["orderMode"] = parseInt(orderMode)
}
return params
}
getChuanMeiParams(layOutObj, pg, extend) {
let obj
if (!_.isEmpty(extend["tags"])) {
obj = JSON.parse(extend["tags"])
} else {
obj = layOutObj
}
let params = {
"page": parseInt(pg),
"length": 32,
"offset": 32 * parseInt(pg - 1),
"tag": obj["videoLables"].join(","),
"typeIds": obj["classs"],
"orderType": obj["orderType"],
"payType": obj["payType"]
}
params = this.getSortParams(params, extend)
return params
}
getNvYouParams(layoutObj, pg, extend) {
let obj
if (!_.isEmpty(extend["tags"])) {
obj = JSON.parse(extend["tags"])
} else {
obj = layoutObj
}
let params = {"videoSort": 1, "touid": obj["id"], "page": parseInt(pg), "length": 12, "orderType": 1}
params = this.getSortParams(params, extend)
return params
}
getZhuantiParams(layoutObj, pg, extend) {
let obj
if (!_.isEmpty(extend["tags"])) {
obj = JSON.parse(extend["tags"])
} else {
obj = layoutObj
}
let orderType = extend["sorts"] ?? "8"
return {
"page": parseInt(pg),
"length": 12,
"offset": 12 * (parseInt(pg) - 1),
"orderType": parseInt(orderType),
"subjectId": obj["id"]
}
}
async setCategory(tid, pg, filter, extend) {
let tid_list = tid.split("$")
let type_id = parseInt(tid_list[0])
let layOutObj = JSON.parse(tid_list[1])
let params = {}
let url = "/videos/getList"
if (type_id > 174 && type_id < 181) {
params = this.getTopParams(type_id, layOutObj, pg, extend)
} else {
switch (type_id) {
case 173:
params = this.getChuanMeiParams(layOutObj, pg, extend)
break
case 182:
params = this.getNvYouParams(layOutObj, pg, extend)
url = "/user/getSpaceVideo"
break
case 209:
params = this.getZhuantiParams(layOutObj, pg, extend)
break
case 172:
let gatherId = extend["tags"] ?? layOutObj
params = {
"gatherId": parseInt(gatherId)
}
url = "/gather/getDetail"
break
default:
break
}
}
let resJson = JSON.parse(await this.post(this.siteUrl + url, this.getParams(params), this.getHeader(), ""))
if (type_id === 172) {
this.vodList = await this.parseVodShortListFromJson(resJson["data"]["info"]["videos"])
} else {
this.vodList = await this.parseVodShortListFromJson(resJson["data"]["list"])
}
}
async setDetail(id) {
let params = {
"videoId": parseInt(id),
"videoSort": 1
}
let resJson = JSON.parse(await this.post(this.siteUrl + "/videos/getInfo", this.getParams(params), this.getHeader(), ""))
this.vodDetail = await this.parseVodDetailFromDoc(resJson["data"]["info"])
}
async proxy(segments, headers) {
let what = segments[0];
let url = Utils.base64Decode(segments[1]);
if (what === 'imgBt') {
let response = await req(url, {buffer: 0});
return JSON.stringify({
code: 200,
buffer: 2,
content: bt(response.content).replaceAll("data:image/jpeg;base64,", "").replaceAll("data:image/jpg;base64,", "").replaceAll("data:image/png;base64", ""),
headers: headers,
});
}
}
async setSearch(wd, quick, pg) {
let params = {
"page": parseInt(pg),
"length": 12,
"type": 1,
"key": wd
}
let resJson = JSON.parse(await this.post(this.siteUrl + "/base/globalSearch", this.getParams(params), this.getHeader(), ""))
this.vodList = await this.parseVodShortListFromJson(resJson["data"]["infos"])
this.result.setPage(parseInt(pg), resJson["data"]["count"] / 12, 12, resJson["data"]["count"])
}
}
let spider = new HanXiuCaoSpider()
async function init(cfg) {
await spider.init(cfg)
}
async function home(filter) {
return await spider.home(filter)
}
async function homeVod() {
return await spider.homeVod()
}
async function category(tid, pg, filter, extend) {
return await spider.category(tid, pg, filter, extend)
}
async function detail(id) {
return await spider.detail(id)
}
async function play(flag, id, flags) {
return await spider.play(flag, id, flags)
}
async function search(wd, quick) {
return await spider.search(wd, quick)
}
async function proxy(segments, headers) {
return await spider.proxy(segments, headers)
}
export function __jsEvalReturn() {
return {
init: init,
home: home,
homeVod: homeVod,
category: category,
detail: detail,
play: play,
search: search,
proxy: proxy
};
}
export {spider, bt}

View File

@@ -21,12 +21,20 @@ class JableTVSpider extends Spider {
async spiderInit(inReq = null) {
if (inReq !== null) {
this.jsBase = await js2Proxy(inReq, "img", {});
this.jsBase = await js2Proxy(inReq, "img", this.getImgHeaders());
} else {
this.jsBase = await js2Proxy(true, this.siteType, this.siteKey, 'img/', {});
this.jsBase = await js2Proxy(true, this.siteType, this.siteKey, 'img/', this.getImgHeaders());
}
}
getImgHeaders(){
return {
"User-Agent": "PostmanRuntime/7.37.3",
"Postman-Token": "c2602692-1a05-4bb0-93cd-270afad97e87",
"Host": "assets-cdn.jable.tv",
"Proxy": true
}
}
async init(cfg) {
await super.init(cfg);
@@ -54,7 +62,7 @@ class JableTVSpider extends Spider {
let header = {}
header["User-Agent"] = "PostmanRuntime/7.36.3"
header["Host"] = "jable.tv"
// header["Postman-Token"] = "33290483-3c8d-413f-a160-0d3aea9e6f95"
header["Postman-Token"] = "33290483-3c8d-413f-a160-0d3aea9e6f95"
return header
}
@@ -169,11 +177,12 @@ class JableTVSpider extends Spider {
let vodShort = new VodShort()
let vod_pic = $(element).find("img").attr("data-src")
if (vod_pic !== undefined) {
if (this.catOpenStatus) {
vodShort.vod_pic = this.jsBase + Utils.base64Encode(vod_pic)
} else {
vodShort.vod_pic = vod_pic
}
vodShort.vod_pic = vod_pic
// if (this.catOpenStatus) {
// vodShort.vod_pic = this.jsBase + Utils.base64Encode(vod_pic)
// } else {
// vodShort.vod_pic = vod_pic
// }
let url = $(element).find("a").attr("href");
vodShort.vod_id = url.split("/")[4];
vodShort.vod_name = url.split("/")[4];
@@ -197,11 +206,12 @@ class JableTVSpider extends Spider {
let leftElement = $("[class=\"header-left\"]")
vodDetail.vod_name = $($(leftElement).find("h4")).text();
let vod_pic = Utils.getStrByRegex(/<video poster="(.*?)" id=/, $.html())
if (this.catOpenStatus) {
vodDetail.vod_pic = this.jsBase + Utils.base64Encode(vod_pic)
} else {
vodDetail.vod_pic = vod_pic
}
vodDetail.vod_pic = vod_pic
// if (this.catOpenStatus) {
// vodDetail.vod_pic = this.jsBase + Utils.base64Encode(vod_pic)
// } else {
// vodDetail.vod_pic = vod_pic
// }
vodDetail.vod_year = $($("[class=\"inactive-color\"]")).text()
let episodeName = $($("[class=\"header-right d-none d-md-block\"] > h6")).text().replaceAll("\n", "").replaceAll("●", "")
let vodItems = []

View File

@@ -35,7 +35,7 @@ class Sp360Spider extends Spider {
async init(cfg) {
await super.init(cfg);
this.danmuUrl = true
this.danmuStaus = true
}
async setClasses() {
@@ -518,9 +518,9 @@ class Sp360Spider extends Spider {
let vodShort = new VodShort();
vodShort.vod_id = data["id"] + "+" + tid
if (!data["cover"].startsWith("http")) {
vodShort.vod_pic = "https:" + data["cdncover"]
vodShort.vod_pic = "https:" + data["cover"]
} else {
vodShort.vod_pic = data["cdncover"]
vodShort.vod_pic = data["cover"]
}
vodShort.vod_name = data["title"]
vodShort.vod_remarks = data["tag"]
@@ -624,7 +624,7 @@ class Sp360Spider extends Spider {
}
async setPlay(flag, id, flags) {
if (this.danmuUrl) {
if (this.danmuStaus && ! this.catOpenStatus) {
this.danmuUrl = await this.danmuSpider.getVideoUrl(id, 0)
}
this.result.parse = 1 //启用自动解析

View File

@@ -57,7 +57,7 @@ class Result {
}
search(vod_list) {
return JSON.stringify({"list": vod_list})
return JSON.stringify({"list": vod_list,"page":this.page,"pagecount":this.pagecount,"total":this.total})
}
detail(vod_detail) {
@@ -648,7 +648,7 @@ class Spider {
if (this.danmuStaus && !this.catOpenStatus) {
if (!_.isEmpty(this.danmuUrl)) {
await this.jadeLog.debug("播放详情页面有弹幕,所以不需要再查找弹幕")
return_result = this.result.setHeader(this.header).danmu(this.danmuUrl).play(this.playUrl)
return_result = this.result.danmu(this.danmuUrl).play(this.playUrl)
} else {
let danmuUrl;
try {
@@ -656,12 +656,12 @@ class Spider {
} catch (e) {
await this.jadeLog.error(`弹幕加载失败,失败原因为:${e}`)
}
return_result = this.result.setHeader(this.header).danmu(danmuUrl).play(this.playUrl)
return_result = this.result.danmu(danmuUrl).play(this.playUrl)
}
} else {
await this.jadeLog.debug("不需要加载弹幕", true)
return_result = this.result.setHeader(this.header).play(this.playUrl)
return_result = this.result.play(this.playUrl)
}
}
await this.jadeLog.info("播放页面解析完成", true)
@@ -695,17 +695,25 @@ class Spider {
async getImg(url, headers) {
let resp;
let use_proxy = false // 使用代理不需要加headers
let vpn_proxy = headers["Proxy"] // 使用代理不需要加headers
if (_.isEmpty(headers)) {
headers = {Referer: url, 'User-Agent': Utils.CHROME}
use_proxy = true
}
resp = await req(url, {buffer: 2, headers: headers,proxy:use_proxy});
resp = await req(url, {buffer: 2, headers: headers,proxy:vpn_proxy});
try {
//二进制文件是不能使用Base64编码格式的
Utils.base64Decode(resp.content)
await this.jadeLog.error(`图片代理获取失败,重连失败`, true)
this.reconnectTimes = 0
return {"code": 500, "headers": headers, "content": "加载失败"}
if (vpn_proxy){
await this.jadeLog.error(`使用VPN代理,图片地址为:${url},headers:${JSON.stringify(headers)},代理失败,准备重连,输出内容为:${JSON.stringify(resp)}`)
}else {
await this.jadeLog.error(`使用普通代理,图片地址为:${url},headers:${JSON.stringify(headers)},代理失败,准备重连,输出内容为:${JSON.stringify(resp)}`)
}
if (this.reconnectTimes < this.maxReconnectTimes){
this.reconnectTimes = this.reconnectTimes + 1
return await this.getImg(url,headers)
}else{
return {"code": 500, "headers": headers, "content": "加载失败"}
}
} catch (e) {
await this.jadeLog.debug("图片代理成功", true)
this.reconnectTimes = 0

View File

@@ -1,4 +1,4 @@
import {__jsEvalReturn} from './jable.js';
import {__jsEvalReturn} from './bilibili.js';
import * as Utils from "../lib/utils.js";
@@ -55,7 +55,7 @@ async function test() {
await spider.init({
skey: siteKey, stype: siteType, ext: {
"token": "6827db23e5474d02a07fd7431d3d5a5a",
"box": "TV",
"box": "bilibili",
"code": "1",
"from": "justlive1",
"danmu": true,
@@ -74,22 +74,32 @@ async function test() {
//测试分类列表
let catePage = JSON.parse(await spider.category("历史记录", "1", undefined, {}));
console.debug(JSON.stringify(catePage));
// 测试详情
let detail1 = JSON.parse(await spider.detail("BV12r421t7nu"))
let detail1 = JSON.parse(await spider.detail("BV1Pp421R7pn"))
await testPlay(detail1)
let catePage = JSON.parse(await spider.category("2", "1", undefined, {}));
console.debug(JSON.stringify(catePage));
// 测试搜索
let search_page = JSON.parse(await spider.search("海贼王"))
// 测试搜索
let search_page = JSON.parse(await spider.search("王"))
console.debug(JSON.stringify(search_page));
// 测试详情
if (search_page.list && search_page.list.length > 0) {
for (const k in search_page.list) {

View File

@@ -1,6 +1,15 @@
{
"video": {
"sites": [
{
"key": "cilixiong",
"name": "🐻┃磁力熊┃🐻",
"playerType": 0,
"type": 3,
"api": "./js/cilixiong.js",
"timeout": 30,
"ext": "{\"box\": \"CatOpen\", \"danmu\": false}"
},
{
"key": "aiyingshi",
"name": "🚀‍┃爱影视┃🚀",

View File

@@ -1,5 +1,14 @@
{
"sites": [
{
"key": "cilixiong",
"name": "🐻┃磁力熊┃🐻",
"playerType": 0,
"type": 3,
"api": "./js/cilixiong.js",
"timeout": 30,
"ext": "{\"box\": \"TVBox\", \"danmu\": false}"
},
{
"key": "aiyingshi",
"name": "🚀‍┃爱影视┃🚀",