增加二级分类及筛选功能
This commit is contained in:
40
js/README.md
40
js/README.md
@@ -19,10 +19,50 @@
|
|||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
# 脚本运行说明
|
||||||
|
|
||||||
|
1. 执行每个方法都会为 `webSite` 进行赋值
|
||||||
|
2. 流程图
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
|
||||||
|
graph TD
|
||||||
|
|
||||||
|
A[开始] --> A1[uz 调用 getClassList 获取一级分类] -->|返回数据 rep: RepVideoClassList| B[判断 rep.data 列表内 VideoClass 的 hasSubclass 是否为 true]
|
||||||
|
|
||||||
|
B -->|是,存在二级分类或者筛选列表| C[调用 getSubclassList 获取二级分类或筛选列表]
|
||||||
|
|
||||||
|
B -->|否,不存在二级分类| D[调用 getVideoList 获取视频列表]
|
||||||
|
|
||||||
|
|
||||||
|
C --> C1[调用 getSubclassVideoList 获取二级分类视频列表或者筛选视频列表] -->|点击单个视频| E
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
E[调用 getVideoDetail 获取视频详情]
|
||||||
|
|
||||||
|
D -->|点击单个视频| E
|
||||||
|
|
||||||
|
E -->|点击某一集| F[调用 getVideoPlayUrl 获取播放链接]
|
||||||
|
|
||||||
|
F --> G[结束]
|
||||||
|
|
||||||
|
S[搜索] -->S1[调用 searchVideo 返回视频列表] -->|点击单个视频| E
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
# 修改记录
|
# 修改记录
|
||||||
|
|
||||||
|
### v1.4.00
|
||||||
|
|
||||||
|
1. 增加二级分类和筛选列表功能
|
||||||
|
|
||||||
### v1.3.00
|
### v1.3.00
|
||||||
|
|
||||||
1. 去掉 `cat.js`, 更改为 `cheerio` `Crypto` `Encrypt` `parse`
|
1. 去掉 `cat.js`, 更改为 `cheerio` `Crypto` `Encrypt` `parse`
|
||||||
2. `VideoDetail` 新增 `quarkUrl` 支持夸克网盘
|
2. `VideoDetail` 新增 `quarkUrl` 支持夸克网盘
|
||||||
3. `RepVideoPlayUrl` 新增 `headers` 支持设置播放 `header`
|
3. `RepVideoPlayUrl` 新增 `headers` 支持设置播放 `header`
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
|||||||
@@ -1,3 +1,30 @@
|
|||||||
|
/**
|
||||||
|
* 筛选标签
|
||||||
|
*/
|
||||||
|
class FilterLabel {
|
||||||
|
constructor() {
|
||||||
|
// 筛选名称
|
||||||
|
this.name = "";
|
||||||
|
// 标识参数
|
||||||
|
this.id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 筛选标题
|
||||||
|
*/
|
||||||
|
class FilterTitle {
|
||||||
|
constructor() {
|
||||||
|
// 筛选标题
|
||||||
|
this.name = "";
|
||||||
|
/**
|
||||||
|
* 筛选标签列表
|
||||||
|
* @type {FilterLabel[]}
|
||||||
|
*/
|
||||||
|
this.list = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 视频分类
|
* 视频分类
|
||||||
*/
|
*/
|
||||||
@@ -7,6 +34,30 @@ class VideoClass {
|
|||||||
this.type_id = "";
|
this.type_id = "";
|
||||||
// 分类名称
|
// 分类名称
|
||||||
this.type_name = "";
|
this.type_name = "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否存在 筛选列表、子分类。 存在会调用 getSubclassList
|
||||||
|
*/
|
||||||
|
this.hasSubclass = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 视频二级分类,二级分类可以是 分类,也可以是筛选,都有值优先取筛选
|
||||||
|
*/
|
||||||
|
class VideoSubclass {
|
||||||
|
constructor() {
|
||||||
|
/**
|
||||||
|
* 子分类
|
||||||
|
* @type {VideoClass[]}
|
||||||
|
*/
|
||||||
|
this.class = [];
|
||||||
|
/**
|
||||||
|
* 筛选列表
|
||||||
|
* 请求二级分类列表 getSubclassList 时返回该数据或者 data,
|
||||||
|
* @type {FilterTitle[]}
|
||||||
|
*/
|
||||||
|
this.filter = [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,6 +117,20 @@ class RepVideoClassList {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回二级分类列表(包括筛选列表)
|
||||||
|
*/
|
||||||
|
class RepVideoSubclassList {
|
||||||
|
constructor() {
|
||||||
|
/**
|
||||||
|
* 二级分类数据
|
||||||
|
* @type {VideoSubclass}
|
||||||
|
*/
|
||||||
|
this.data = new VideoSubclass();
|
||||||
|
this.error = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 返回视频列表
|
* 返回视频列表
|
||||||
*/
|
*/
|
||||||
@@ -74,7 +139,7 @@ class RepVideoList {
|
|||||||
/**
|
/**
|
||||||
* @type {VideoDetail[]}
|
* @type {VideoDetail[]}
|
||||||
*/
|
*/
|
||||||
this.data = null;
|
this.data = [];
|
||||||
this.error = "";
|
this.error = "";
|
||||||
this.total = 0;
|
this.total = 0;
|
||||||
}
|
}
|
||||||
@@ -120,10 +185,36 @@ class UZArgs {
|
|||||||
this.searchWord = "";
|
this.searchWord = "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getSubclassVideoList 方法传入的参数
|
||||||
|
*/
|
||||||
|
class UZSubclassVideoListArgs extends UZArgs {
|
||||||
|
constructor() {
|
||||||
|
/**
|
||||||
|
* 主分类ID 即脚本返回的 @type {RepVideoClassList}.data[0].type_id
|
||||||
|
*/
|
||||||
|
this.mainClassId = "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 二级分类ID 即脚本返回的 @type {RepVideoSubclassList}.data.class.type_id
|
||||||
|
*/
|
||||||
|
this.subclassId = "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 筛选标签,按返回的顺序传入 即脚本返回的 @type {RepVideoSubclassList}.data.filter.
|
||||||
|
* @type {FilterLabel[]}
|
||||||
|
*/
|
||||||
|
this.filter = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 脚本基类
|
* 脚本基类
|
||||||
*/
|
*/
|
||||||
class WebApiBase {
|
class WebApiBase {
|
||||||
|
// 网站主页
|
||||||
|
webSite = "";
|
||||||
/**
|
/**
|
||||||
* 异步获取分类列表的方法。
|
* 异步获取分类列表的方法。
|
||||||
* @param {UZArgs} args
|
* @param {UZArgs} args
|
||||||
@@ -133,6 +224,15 @@ class WebApiBase {
|
|||||||
return JSON.stringify(new RepVideoClassList());
|
return JSON.stringify(new RepVideoClassList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取二级分类列表筛选列表的方法。
|
||||||
|
* @param {UZArgs} args
|
||||||
|
* @returns {@Promise<JSON.stringify(new RepVideoSubclassList())>}
|
||||||
|
*/
|
||||||
|
async getSubclassList(args) {
|
||||||
|
return JSON.stringify(new RepVideoSubclassList());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取分类视频列表
|
* 获取分类视频列表
|
||||||
* @param {UZArgs} args
|
* @param {UZArgs} args
|
||||||
@@ -141,6 +241,15 @@ class WebApiBase {
|
|||||||
async getVideoList(args) {
|
async getVideoList(args) {
|
||||||
return JSON.stringify(new RepVideoList());
|
return JSON.stringify(new RepVideoList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取二级分类视频列表 或 筛选视频列表
|
||||||
|
* @param {UZSubclassVideoListArgs} args
|
||||||
|
* @returns {@Promise<JSON.stringify(new RepVideoList())>}
|
||||||
|
*/
|
||||||
|
async getSubclassVideoList(args) {
|
||||||
|
return JSON.stringify(new RepVideoList());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取视频详情
|
* 获取视频详情
|
||||||
|
|||||||
342
js/spider/keke20240712.js
Normal file
342
js/spider/keke20240712.js
Normal file
@@ -0,0 +1,342 @@
|
|||||||
|
// ignore
|
||||||
|
import { WebApiBase, VideoClass } from "../core/uzCode.js";
|
||||||
|
import { parse } from "node-html-parser";
|
||||||
|
// ignore
|
||||||
|
|
||||||
|
// 类名要特殊
|
||||||
|
class Keke20240712 extends WebApiBase {
|
||||||
|
webSite = "https://www.keke12.com:51111";
|
||||||
|
/**
|
||||||
|
* 异步获取分类列表的方法。
|
||||||
|
* @param {UZArgs} args
|
||||||
|
* @returns {Promise<RepVideoClassList>}
|
||||||
|
*/
|
||||||
|
async getClassList(args) {
|
||||||
|
let webUrl = args.url;
|
||||||
|
var backData = new RepVideoClassList();
|
||||||
|
backData.data = [];
|
||||||
|
try {
|
||||||
|
const pro = await req(webUrl);
|
||||||
|
backData.error = pro.error;
|
||||||
|
let proData = pro.data;
|
||||||
|
if (proData) {
|
||||||
|
var document = parse(proData);
|
||||||
|
var ulList = document.querySelectorAll("div.main > ul") ?? [];
|
||||||
|
|
||||||
|
if (ulList.length >= 1) {
|
||||||
|
var li = ulList[1].querySelectorAll("li") ?? [];
|
||||||
|
for (let i = 0; i < li.length; i++) {
|
||||||
|
const element = li[i];
|
||||||
|
const title = element.querySelector(".menu-item-label").text;
|
||||||
|
const path = element.querySelector("a").attributes["href"];
|
||||||
|
const id = UZUtils.getStrByRegexDefault(/\/(\d+)\.html/, path);
|
||||||
|
var videoClass = new VideoClass();
|
||||||
|
videoClass.hasSubclass = true;
|
||||||
|
videoClass.type_id = id;
|
||||||
|
videoClass.type_name = title;
|
||||||
|
backData.data.push(videoClass);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
backData.error = "获取分类失败~";
|
||||||
|
}
|
||||||
|
return JSON.stringify(backData);
|
||||||
|
}
|
||||||
|
|
||||||
|
async getSubclassList(args) {
|
||||||
|
var backData = new RepVideoSubclassList();
|
||||||
|
backData.data = new VideoSubclass();
|
||||||
|
const id = args.url;
|
||||||
|
try {
|
||||||
|
var url =
|
||||||
|
UZUtils.removeTrailingSlash(this.webSite) +
|
||||||
|
"/show/" +
|
||||||
|
id +
|
||||||
|
"------1.html";
|
||||||
|
const pro = await req(url);
|
||||||
|
backData.error = pro.error;
|
||||||
|
let proData = pro.data;
|
||||||
|
if (proData) {
|
||||||
|
var document = parse(proData);
|
||||||
|
var filterTitleList = document.querySelectorAll("div.filter-row") ?? [];
|
||||||
|
for (let i = 0; i < filterTitleList.length; i++) {
|
||||||
|
const element = filterTitleList[i];
|
||||||
|
const title = element.querySelector(".filter-row-side > strong").text;
|
||||||
|
const items = element.querySelectorAll(".filter-item") ?? [];
|
||||||
|
// 2-惊悚-中国香港-英语-2022-1-1
|
||||||
|
// 分类-类型-地区-语言-年代-排序-页码
|
||||||
|
var filterTitle = new FilterTitle();
|
||||||
|
filterTitle.name = title.replace(":", "");
|
||||||
|
filterTitle.list = [];
|
||||||
|
for (let j = 0; j < items.length; j++) {
|
||||||
|
const item = items[j];
|
||||||
|
const name = item.text;
|
||||||
|
const path = item.attributes["href"] ?? "";
|
||||||
|
const regex = /\/show\/(.*?)\.html/;
|
||||||
|
const match = path.match(regex);
|
||||||
|
const parsStr = match ? match[1] : null;
|
||||||
|
if (parsStr) {
|
||||||
|
const parList = parsStr.split("-");
|
||||||
|
const id = parList[i + 1];
|
||||||
|
var filterLab = new FilterLabel();
|
||||||
|
filterLab.name = name;
|
||||||
|
filterLab.id = id;
|
||||||
|
filterTitle.list.push(filterLab);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
backData.data.filter.push(filterTitle);
|
||||||
|
}
|
||||||
|
if (id === 6 || id === "6") {
|
||||||
|
// 短剧
|
||||||
|
if (backData.data.filter.length > 0) {
|
||||||
|
const list = backData.data.filter[0].list;
|
||||||
|
var classList = [];
|
||||||
|
for (let index = 0; index < list.length; index++) {
|
||||||
|
const element = list[index];
|
||||||
|
var subclass = new VideoClass();
|
||||||
|
subclass.type_id = element.id;
|
||||||
|
subclass.type_name = element.name;
|
||||||
|
classList.push(subclass);
|
||||||
|
}
|
||||||
|
backData.data.filter = [];
|
||||||
|
backData.data.class = classList;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
backData.error = "获取分类失败~ " + error;
|
||||||
|
}
|
||||||
|
return JSON.stringify(backData);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 获取二级分类视频列表 或 筛选视频列表
|
||||||
|
* @param {UZSubclassVideoListArgs} args
|
||||||
|
* @returns {@Promise<JSON.stringify(new RepVideoList())>}
|
||||||
|
*/
|
||||||
|
async getSubclassVideoList(args) {
|
||||||
|
var backData = new RepVideoList();
|
||||||
|
backData.data = [];
|
||||||
|
try {
|
||||||
|
var pList = [args.mainClassId];
|
||||||
|
if (args.filter.length > 0) {
|
||||||
|
// 筛选
|
||||||
|
for (let index = 0; index < args.filter.length; index++) {
|
||||||
|
const element = args.filter[index];
|
||||||
|
pList.push(element.id);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
pList.push(args.subclassId);
|
||||||
|
for (let index = 0; index < 4; index++) {
|
||||||
|
pList.push("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pList.push(args.page);
|
||||||
|
var path = pList.join("-");
|
||||||
|
const url =
|
||||||
|
UZUtils.removeTrailingSlash(this.webSite) + "/show/" + path + ".html";
|
||||||
|
|
||||||
|
const pro = await req(url);
|
||||||
|
backData.error = pro.error;
|
||||||
|
let proData = pro.data;
|
||||||
|
if (proData) {
|
||||||
|
var document = parse(proData);
|
||||||
|
var allVideo = document.querySelectorAll("div.module-item") ?? [];
|
||||||
|
var videos = [];
|
||||||
|
for (let index = 0; index < allVideo.length; index++) {
|
||||||
|
const element = allVideo[index];
|
||||||
|
var vodUrl = element.querySelector("a")?.attributes["href"] ?? "";
|
||||||
|
var avaImg =
|
||||||
|
document.querySelector("img.user-avatar-img")?.attributes["src"] ??
|
||||||
|
"";
|
||||||
|
var path =
|
||||||
|
element.querySelector("img")?.attributes["data-original"] ?? "";
|
||||||
|
var vodPic = UZUtils.getHostFromURL(avaImg) + path;
|
||||||
|
var vodName = element.querySelector("img")?.attributes["title"] ?? "";
|
||||||
|
var vod_remarks =
|
||||||
|
element.querySelector("div.v-item-bottom > span")?.text ??
|
||||||
|
element.querySelector("div.v-item-top-left > span")?.text;
|
||||||
|
if (vodUrl && vodPic && vodName) {
|
||||||
|
var video = new VideoDetail();
|
||||||
|
video.vod_id = vodUrl;
|
||||||
|
video.vod_pic = vodPic;
|
||||||
|
video.vod_name = vodName;
|
||||||
|
video.vod_remarks = vod_remarks;
|
||||||
|
videos.push(video);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
backData.data = videos;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
backData.error = "获取视频列表失败~ " + error;
|
||||||
|
}
|
||||||
|
|
||||||
|
return JSON.stringify(backData);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取分类视频列表
|
||||||
|
* @param {UZArgs} args
|
||||||
|
* @returns {Promise<RepVideoList>}
|
||||||
|
*/
|
||||||
|
async getVideoList(args) {
|
||||||
|
var backData = new RepVideoList();
|
||||||
|
return JSON.stringify(backData);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取视频详情
|
||||||
|
* @param {UZArgs} args
|
||||||
|
* @returns {Promise<RepVideoDetail>}
|
||||||
|
*/
|
||||||
|
async getVideoDetail(args) {
|
||||||
|
var backData = new RepVideoDetail();
|
||||||
|
try {
|
||||||
|
var webUrl = UZUtils.removeTrailingSlash(this.webSite) + args.url;
|
||||||
|
let pro = await req(webUrl, null);
|
||||||
|
backData.error = pro.error;
|
||||||
|
let proData = pro.data;
|
||||||
|
if (proData) {
|
||||||
|
var document = parse(proData);
|
||||||
|
|
||||||
|
var detList = document.querySelectorAll("div.detail-info-row") ?? [];
|
||||||
|
var vod_year = "";
|
||||||
|
var vod_director = "";
|
||||||
|
var vod_actor = "";
|
||||||
|
|
||||||
|
for (let index = 0; index < detList.length; index++) {
|
||||||
|
const element = detList[index];
|
||||||
|
var title =
|
||||||
|
element.querySelector("div.detail-info-row-side")?.text ?? "";
|
||||||
|
var contentE = element.querySelector("div.detail-info-row-main");
|
||||||
|
if (title.includes("首映")) {
|
||||||
|
vod_year = contentE.text ?? "";
|
||||||
|
} else if (title.includes("导演")) {
|
||||||
|
vod_director = contentE?.querySelector("a")?.text ?? "";
|
||||||
|
} else if (title.includes("演员")) {
|
||||||
|
contentE.querySelectorAll("a").forEach((element) => {
|
||||||
|
vod_actor += element.text + "、";
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var vod_content =
|
||||||
|
document.querySelector("div.detail-desc > p").text?.trim() ?? "";
|
||||||
|
|
||||||
|
var fromListE =
|
||||||
|
document.querySelectorAll("span.source-item-label") ?? [];
|
||||||
|
var fromListStr = [];
|
||||||
|
for (let index = 0; index < fromListE.length; index++) {
|
||||||
|
fromListStr.push(fromListE[index].text);
|
||||||
|
}
|
||||||
|
var vod_play_from = fromListStr.join("$$$");
|
||||||
|
|
||||||
|
var playListE = document.querySelectorAll("div.episode-list") ?? [];
|
||||||
|
var vod_play_url = "";
|
||||||
|
for (let index = 0; index < playListE.length; index++) {
|
||||||
|
const epList = playListE[index].querySelectorAll("a") ?? [];
|
||||||
|
|
||||||
|
for (let index = 0; index < epList.length; index++) {
|
||||||
|
const element = epList[index];
|
||||||
|
vod_play_url += element.text;
|
||||||
|
vod_play_url += "$";
|
||||||
|
vod_play_url += element.attributes["href"];
|
||||||
|
vod_play_url += "#";
|
||||||
|
}
|
||||||
|
vod_play_url += "$$$";
|
||||||
|
}
|
||||||
|
|
||||||
|
let detModel = new VideoDetail();
|
||||||
|
detModel.vod_year = vod_year;
|
||||||
|
detModel.vod_director = vod_director;
|
||||||
|
detModel.vod_actor = vod_actor;
|
||||||
|
detModel.vod_content = vod_content;
|
||||||
|
detModel.vod_play_url = vod_play_url;
|
||||||
|
detModel.vod_play_from = vod_play_from;
|
||||||
|
detModel.vod_id = args.url;
|
||||||
|
backData.data = detModel;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
backData.error = "获取视频详情失败 ~ " + error;
|
||||||
|
}
|
||||||
|
|
||||||
|
return JSON.stringify(backData);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取视频的播放地址
|
||||||
|
* @param {UZArgs} args
|
||||||
|
* @returns {Promise<RepVideoPlayUrl>}
|
||||||
|
*/
|
||||||
|
async getVideoPlayUrl(args) {
|
||||||
|
var backData = new RepVideoPlayUrl();
|
||||||
|
backData.error = "获取播放链接失败~";
|
||||||
|
try {
|
||||||
|
const pro = await req(
|
||||||
|
UZUtils.removeTrailingSlash(this.webSite) + args.url
|
||||||
|
);
|
||||||
|
backData.error = pro.error;
|
||||||
|
let proData = pro.data;
|
||||||
|
const regex = /playSource\s*=\s*{[^}]*src:\s*"([^"]*)"/;
|
||||||
|
const match = proData.match(regex);
|
||||||
|
const result = match ? match[1] : "";
|
||||||
|
backData.data = result;
|
||||||
|
} catch (error) {
|
||||||
|
backData.error = "获取视频播放地址失败~ " + error;
|
||||||
|
}
|
||||||
|
return JSON.stringify(backData);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 搜索视频
|
||||||
|
* @param {UZArgs} args
|
||||||
|
* @returns {Promise<RepVideoList>}
|
||||||
|
*/
|
||||||
|
async searchVideo(args) {
|
||||||
|
var backData = new RepVideoList();
|
||||||
|
backData.data = [];
|
||||||
|
try {
|
||||||
|
const rep = await req(
|
||||||
|
UZUtils.removeTrailingSlash(this.webSite) +
|
||||||
|
"/search?k=" +
|
||||||
|
args.searchWord +
|
||||||
|
"&page=" +
|
||||||
|
args.page
|
||||||
|
);
|
||||||
|
backData.error = rep.error;
|
||||||
|
let repData = rep.data;
|
||||||
|
var document = parse(repData);
|
||||||
|
var count = document.querySelectorAll("span.highlight-text") ?? [];
|
||||||
|
if (count.length > 1) {
|
||||||
|
backData.total = count[1].text.trim();
|
||||||
|
}
|
||||||
|
const allVideoE = document.querySelectorAll("a.search-result-item") ?? [];
|
||||||
|
|
||||||
|
for (let index = 0; index < allVideoE.length; index++) {
|
||||||
|
const element = allVideoE[index];
|
||||||
|
var video = new VideoDetail();
|
||||||
|
video.vod_id = element.attributes["href"];
|
||||||
|
|
||||||
|
var avaImg =
|
||||||
|
document.querySelector("img.user-avatar-img")?.attributes["src"] ??
|
||||||
|
"";
|
||||||
|
var path =
|
||||||
|
element.querySelector("img")?.attributes["data-original"] ?? "";
|
||||||
|
var vodPic = UZUtils.getHostFromURL(avaImg) + path;
|
||||||
|
video.vod_pic = vodPic;
|
||||||
|
|
||||||
|
video.vod_name = element.querySelector("div.title")?.text ?? "";
|
||||||
|
video.vod_remarks =
|
||||||
|
element.querySelector("div.search-result-item-header > div")?.text ??
|
||||||
|
"";
|
||||||
|
|
||||||
|
backData.data.push(video);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
backData.error = "搜索视频失败 ~ " + error;
|
||||||
|
}
|
||||||
|
return JSON.stringify(backData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// json 中 instance 的值,这个名称一定要特殊
|
||||||
|
var keke20240712 = new Keke20240712();
|
||||||
@@ -5,5 +5,12 @@
|
|||||||
"instance": "changZhang20240614",
|
"instance": "changZhang20240614",
|
||||||
"webSite": "https://www.czzy77.com",
|
"webSite": "https://www.czzy77.com",
|
||||||
"remark": "部分视频不会解密,不支持搜索"
|
"remark": "部分视频不会解密,不支持搜索"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "可可影视",
|
||||||
|
"api": "https://mirror.ghproxy.com/https://raw.githubusercontent.com/YYDS678/uzVideo/main/js/spider/keke20240712.js",
|
||||||
|
"instance": "keke20240712",
|
||||||
|
"webSite": "https://www.keke12.com:51111",
|
||||||
|
"remark": ""
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
Reference in New Issue
Block a user