mirror of
https://github.com/venera-app/venera-configs.git
synced 2025-09-27 08:27:24 +00:00
862
ikmmh.js
862
ikmmh.js
@@ -1,437 +1,441 @@
|
|||||||
class NewComicSource extends ComicSource { // 首行必须为class...
|
class Ikm extends ComicSource {
|
||||||
|
// 基础配置
|
||||||
|
name = "爱看漫";
|
||||||
|
key = "ikmmh";
|
||||||
|
version = "1.0.2";
|
||||||
|
minAppVersion = "1.0.0";
|
||||||
|
url = "https://cdn.jsdelivr.net/gh/venera-app/venera-configs@main/ikmmh.js";
|
||||||
|
// 常量定义
|
||||||
|
static baseUrl = "https://ymcdnyfqdapp.ikmmh.com";
|
||||||
|
static Mobile_UA = "Mozilla/5.0 (Linux; Android) Mobile";
|
||||||
|
static webHeaders = {
|
||||||
|
"User-Agent": Ikm.Mobile_UA,
|
||||||
|
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",
|
||||||
|
};
|
||||||
|
static jsonHead = {
|
||||||
|
"User-Agent": Ikm.Mobile_UA,
|
||||||
|
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
|
||||||
|
Accept: "application/json, text/javascript, */*; q=0.01",
|
||||||
|
"Accept-Encoding": "gzip",
|
||||||
|
"X-Requested-With": "XMLHttpRequest",
|
||||||
|
};
|
||||||
|
// 统一缩略图加载配置
|
||||||
|
static thumbConfig = (url) => ({
|
||||||
|
headers: {
|
||||||
|
...Ikm.webHeaders,
|
||||||
|
Referer: Ikm.baseUrl,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
// 账号系统
|
||||||
|
account = {
|
||||||
|
login: async (account, pwd) => {
|
||||||
|
try {
|
||||||
|
let res = await Network.post(
|
||||||
|
`${Ikm.baseUrl}/api/user/userarr/login`,
|
||||||
|
Ikm.jsonHead,
|
||||||
|
`user=${account}&pass=${pwd}`
|
||||||
|
);
|
||||||
|
if (res.status !== 200)
|
||||||
|
throw new Error(`登录失败,状态码:${res.status}`);
|
||||||
|
let data = JSON.parse(res.body);
|
||||||
|
if (data.code !== 0) throw new Error(data.msg || "登录异常");
|
||||||
|
return "ok";
|
||||||
|
} catch (err) {
|
||||||
|
throw new Error(`登录失败:${err.message}`);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
logout: () => Network.deleteCookies("ymcdnyfqdapp.ikmmh.com"),
|
||||||
|
registerWebsite: `${Ikm.baseUrl}/user/register/`,
|
||||||
|
};
|
||||||
|
// 探索页面
|
||||||
|
explore = [
|
||||||
|
{
|
||||||
|
title: this.name,
|
||||||
|
type: "singlePageWithMultiPart",
|
||||||
|
load: async () => {
|
||||||
|
try {
|
||||||
|
let res = await Network.get(`${Ikm.baseUrl}/`, Ikm.webHeaders);
|
||||||
|
if (res.status !== 200)
|
||||||
|
throw new Error(`加载探索页面失败,状态码:${res.status}`);
|
||||||
|
let document = new HtmlDocument(res.body);
|
||||||
|
let parseComic = (e) => {
|
||||||
|
let title = e.querySelector("div.title").text.split("~")[0];
|
||||||
|
let cover = e.querySelector("div.thumb_img").attributes["data-src"];
|
||||||
|
let link = `${Ikm.baseUrl}${
|
||||||
|
e.querySelector("a").attributes["href"]
|
||||||
|
}`;
|
||||||
|
return {
|
||||||
|
title,
|
||||||
|
cover,
|
||||||
|
id: link,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
return {
|
||||||
|
本周推荐: document
|
||||||
|
.querySelectorAll("div.module-good-fir > div.item")
|
||||||
|
.map(parseComic),
|
||||||
|
今日更新: document
|
||||||
|
.querySelectorAll("div.module-day-fir > div.item")
|
||||||
|
.map(parseComic),
|
||||||
|
};
|
||||||
|
} catch (err) {
|
||||||
|
throw new Error(`探索页面加载失败:${err.message}`);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onThumbnailLoad: Ikm.thumbConfig,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
// 分类页面
|
||||||
|
category = {
|
||||||
|
title: "爱看漫",
|
||||||
|
parts: [
|
||||||
|
{
|
||||||
|
name: "分类",
|
||||||
|
// fixed 或者 random
|
||||||
|
// random用于分类数量相当多时, 随机显示其中一部分
|
||||||
|
type: "fixed",
|
||||||
|
// 如果类型为random, 需要提供此字段, 表示同时显示的数量
|
||||||
|
// randomNumber: 5,
|
||||||
|
categories: [
|
||||||
|
"全部",
|
||||||
|
"长条",
|
||||||
|
"大女主",
|
||||||
|
"百合",
|
||||||
|
"耽美",
|
||||||
|
"纯爱",
|
||||||
|
"後宫",
|
||||||
|
"韩漫",
|
||||||
|
"奇幻",
|
||||||
|
"轻小说",
|
||||||
|
"生活",
|
||||||
|
"悬疑",
|
||||||
|
"格斗",
|
||||||
|
"搞笑",
|
||||||
|
"伪娘",
|
||||||
|
"竞技",
|
||||||
|
"职场",
|
||||||
|
"萌系",
|
||||||
|
"冒险",
|
||||||
|
"治愈",
|
||||||
|
"都市",
|
||||||
|
"霸总",
|
||||||
|
"神鬼",
|
||||||
|
"侦探",
|
||||||
|
"爱情",
|
||||||
|
"古风",
|
||||||
|
"欢乐向",
|
||||||
|
"科幻",
|
||||||
|
"穿越",
|
||||||
|
"性转换",
|
||||||
|
"校园",
|
||||||
|
"美食",
|
||||||
|
"悬疑",
|
||||||
|
"剧情",
|
||||||
|
"热血",
|
||||||
|
"节操",
|
||||||
|
"励志",
|
||||||
|
"异世界",
|
||||||
|
"历史",
|
||||||
|
"战争",
|
||||||
|
"恐怖",
|
||||||
|
"霸总",
|
||||||
|
"全部",
|
||||||
|
"连载中",
|
||||||
|
"已完结",
|
||||||
|
"全部",
|
||||||
|
"日漫",
|
||||||
|
"港台",
|
||||||
|
"美漫",
|
||||||
|
"国漫",
|
||||||
|
"韩漫",
|
||||||
|
"未分类",
|
||||||
|
],
|
||||||
|
// category或者search
|
||||||
|
// 如果为category, 点击后将进入分类漫画页面, 使用下方的`categoryComics`加载漫画
|
||||||
|
// 如果为search, 将进入搜索页面
|
||||||
|
itemType: "category",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "更新",
|
||||||
|
type: "fixed",
|
||||||
|
categories: [
|
||||||
|
"星期一",
|
||||||
|
"星期二",
|
||||||
|
"星期三",
|
||||||
|
"星期四",
|
||||||
|
"星期五",
|
||||||
|
"星期六",
|
||||||
|
"星期日",
|
||||||
|
],
|
||||||
|
itemType: "category",
|
||||||
|
categoryParams: ["1", "2", "3", "4", "5", "6", "7"],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
enableRankingPage: false,
|
||||||
|
};
|
||||||
|
// 分类漫画加载
|
||||||
|
categoryComics = {
|
||||||
|
load: async (category, param, options, page) => {
|
||||||
|
try {
|
||||||
|
let res;
|
||||||
|
if (param) {
|
||||||
|
res = await Network.get(
|
||||||
|
`${Ikm.baseUrl}/update/${param}.html`,
|
||||||
|
Ikm.webHeaders
|
||||||
|
);
|
||||||
|
if (res.status !== 200)
|
||||||
|
throw new Error(`分类请求失败,状态码:${res.status}`);
|
||||||
|
let document = new HtmlDocument(res.body);
|
||||||
|
let comics = document.querySelectorAll("li.comic-item").map((e) => ({
|
||||||
|
title: e.querySelector("p.title").text.split("~")[0],
|
||||||
|
cover: e.querySelector("img").attributes["src"],
|
||||||
|
id: `${Ikm.baseUrl}${e.querySelector("a").attributes["href"]}`,
|
||||||
|
subTitle: e.querySelector("span.chapter").text,
|
||||||
|
}));
|
||||||
|
return {
|
||||||
|
comics,
|
||||||
|
maxPage: 1,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
res = await Network.post(
|
||||||
|
`${Ikm.baseUrl}/api/comic/index/lists`,
|
||||||
|
Ikm.jsonHead,
|
||||||
|
`area=${options[1]}&tags=${encodeURIComponent(category)}&full=${
|
||||||
|
options[0]
|
||||||
|
}&page=${page}`
|
||||||
|
);
|
||||||
|
let resData = JSON.parse(res.body);
|
||||||
|
return {
|
||||||
|
comics: resData.data.map((e) => ({
|
||||||
|
id: `${Ikm.baseUrl}${e.info_url}`,
|
||||||
|
title: e.name.split("~")[0],
|
||||||
|
subTitle: e.author,
|
||||||
|
cover: e.cover,
|
||||||
|
tags: e.tags,
|
||||||
|
description: e.lastchapter,
|
||||||
|
})),
|
||||||
|
maxPage: resData.end || 1,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
throw new Error(`分类加载失败:${err.message}`);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onThumbnailLoad: Ikm.thumbConfig,
|
||||||
|
optionList: [
|
||||||
|
{
|
||||||
|
// 对于单个选项, 使用-分割, 左侧为用于数据加载的值, 即传给load函数的options参数; 右侧为显示给用户的文本
|
||||||
|
|
||||||
// 此漫画源的名称
|
options: ["3-全部", "4-连载中", "1-已完结"],
|
||||||
name = "爱看漫"
|
notShowWhen: [
|
||||||
|
"星期一",
|
||||||
// 唯一标识符
|
"星期二",
|
||||||
key = "ikmmh"
|
"星期三",
|
||||||
|
"星期四",
|
||||||
version = "1.0.0"
|
"星期五",
|
||||||
|
"星期六",
|
||||||
minAppVersion = "1.0.0"
|
"星期日",
|
||||||
|
],
|
||||||
// 更新链接
|
showWhen: null,
|
||||||
url = "https://cdn.jsdelivr.net/gh/venera-app/venera-configs@main/ikmmh.js"
|
},
|
||||||
|
{
|
||||||
/// APP启动时或者添加/更新漫画源时执行此函数
|
options: [
|
||||||
init() {
|
"9-全部",
|
||||||
|
"1-日漫",
|
||||||
}
|
"2-港台",
|
||||||
|
"3-美漫",
|
||||||
/// 账号
|
"4-国漫",
|
||||||
/// 设置为null禁用账号功能
|
"5-韩漫",
|
||||||
account = {
|
"6-未分类",
|
||||||
/// 登录
|
],
|
||||||
/// 返回任意值表示登录成功
|
notShowWhen: [
|
||||||
login: async (account, pwd) => {
|
"星期一",
|
||||||
let res = await Network.post("https://ymcdnyfqdapp.ikmmh.com/api/user/userarr/login", {
|
"星期二",
|
||||||
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
|
"星期三",
|
||||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36"
|
"星期四",
|
||||||
}, `user=${account}&pass=${pwd}`)
|
"星期五",
|
||||||
|
"星期六",
|
||||||
let data = JSON.parse(res.body)
|
"星期日",
|
||||||
|
],
|
||||||
if (res.status !== 200) {
|
showWhen: null,
|
||||||
throw "Invalid status code: " + res.status
|
},
|
||||||
} else if (data["code"] !== 0) {
|
],
|
||||||
throw "Invalid response: " + data["msg"]
|
};
|
||||||
} else {
|
// 搜索功能
|
||||||
return 'ok'
|
search = {
|
||||||
}
|
load: async (keyword, options, page) => {
|
||||||
|
try {
|
||||||
},
|
let res = await Network.get(
|
||||||
|
`${Ikm.baseUrl}/search?searchkey=${encodeURIComponent(keyword)}`,
|
||||||
// 退出登录时将会调用此函数
|
Ikm.webHeaders
|
||||||
logout: () => {
|
);
|
||||||
Network.deleteCookies("ymcdnyfqdapp.ikmmh.com")
|
let document = new HtmlDocument(res.body);
|
||||||
},
|
return {
|
||||||
|
comics: document.querySelectorAll("li.comic-item").map((e) => ({
|
||||||
registerWebsite: "https://ymcdnyfqdapp.ikmmh.com/user/register/"
|
title: e.querySelector("p.title").text.split("~")[0],
|
||||||
}
|
cover: e.querySelector("img").attributes["src"],
|
||||||
|
id: `${Ikm.baseUrl}${e.querySelector("a").attributes["href"]}`,
|
||||||
/// 探索页面
|
subTitle: e.querySelector("span.chapter").text,
|
||||||
/// 一个漫画源可以有多个探索页面
|
})),
|
||||||
explore = [
|
maxPage: 1,
|
||||||
|
};
|
||||||
|
} catch (err) {
|
||||||
|
throw new Error(`搜索失败:${err.message}`);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onThumbnailLoad: Ikm.thumbConfig,
|
||||||
|
optionList: [],
|
||||||
|
};
|
||||||
|
// 收藏功能
|
||||||
|
favorites = {
|
||||||
|
multiFolder: false,
|
||||||
|
addOrDelFavorite: async (comicId, folderId, isAdding) => {
|
||||||
|
try {
|
||||||
|
let id = comicId.match(/\d+/)[0];
|
||||||
|
if (isAdding) {
|
||||||
|
// 获取漫画信息
|
||||||
|
let infoRes = await Network.get(comicId, Ikm.webHeaders);
|
||||||
|
let name = new HtmlDocument(infoRes.body).querySelector(
|
||||||
|
"meta[property='og:title']"
|
||||||
|
).attributes["content"];
|
||||||
|
// 添加收藏
|
||||||
|
let res = await Network.post(
|
||||||
|
`${Ikm.baseUrl}/api/user/bookcase/add`,
|
||||||
|
Ikm.jsonHead,
|
||||||
|
`articleid=${id}&articlename=${encodeURIComponent(name)}`
|
||||||
|
);
|
||||||
|
let data = JSON.parse(res.body);
|
||||||
|
if (data.code !== "0") throw new Error(data.msg || "收藏失败");
|
||||||
|
return "ok";
|
||||||
|
} else {
|
||||||
|
// 删除收藏
|
||||||
|
let res = await Network.post(
|
||||||
|
`${Ikm.baseUrl}/api/user/bookcase/del`,
|
||||||
|
Ikm.jsonHead,
|
||||||
|
`articleid=${id}`
|
||||||
|
);
|
||||||
|
let data = JSON.parse(res.body);
|
||||||
|
if (data.code !== "0") throw new Error(data.msg || "取消收藏失败");
|
||||||
|
return "ok";
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
throw new Error(`收藏操作失败:${err.message}`);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
//加载收藏
|
||||||
|
loadComics: async (page, folder) => {
|
||||||
|
let res = await Network.get(
|
||||||
|
`${Ikm.baseUrl}/user/bookcase`,
|
||||||
|
Ikm.webHeaders
|
||||||
|
);
|
||||||
|
if (res.status !== 200) {
|
||||||
|
throw "加载收藏失败:" + res.status;
|
||||||
|
}
|
||||||
|
let document = new HtmlDocument(res.body);
|
||||||
|
return {
|
||||||
|
comics: document.querySelectorAll("div.bookrack-item").map((e) => ({
|
||||||
|
title: e.querySelector("h3").text.split("~")[0],
|
||||||
|
subTitle: e.querySelector("p.desc").text,
|
||||||
|
cover: e.querySelector("img").attributes["src"],
|
||||||
|
id: `${Ikm.baseUrl}/book/${e.attributes["data-id"]}/`,
|
||||||
|
})),
|
||||||
|
maxPage: 1,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
onThumbnailLoad: Ikm.thumbConfig,
|
||||||
|
};
|
||||||
|
// 漫画详情
|
||||||
|
comic = {
|
||||||
|
loadInfo: async (id) => {
|
||||||
|
let res = await Network.get(id, Ikm.webHeaders);
|
||||||
|
let document = new HtmlDocument(res.body);
|
||||||
|
let comicId = id.match(/\d+/)[0];
|
||||||
|
// 获取章节数据
|
||||||
|
let epRes = await Network.get(
|
||||||
|
`${Ikm.baseUrl}/api/comic/zyz/chapterlink?id=${comicId}`,
|
||||||
{
|
{
|
||||||
/// 标题
|
...Ikm.jsonHead,
|
||||||
/// 标题同时用作标识符, 不能重复
|
Referer: id,
|
||||||
title: this.name,
|
|
||||||
|
|
||||||
/// singlePageWithMultiPart 或者 multiPageComicList
|
|
||||||
type: "singlePageWithMultiPart",
|
|
||||||
|
|
||||||
/*
|
|
||||||
加载漫画
|
|
||||||
如果类型为multiPageComicList, load方法应当接收一个page参数, 并且返回漫画列表
|
|
||||||
```
|
|
||||||
load: async (page) => {
|
|
||||||
let res = await Network.get("https://example.com")
|
|
||||||
|
|
||||||
if (res.status !== 200) {
|
|
||||||
throw `Invalid status code: ${res.status}`
|
|
||||||
}
|
|
||||||
|
|
||||||
let data = JSON.parse(res.body)
|
|
||||||
|
|
||||||
function parseComic(comic) {
|
|
||||||
// ...
|
|
||||||
|
|
||||||
return {
|
|
||||||
id: id,
|
|
||||||
title: title,
|
|
||||||
subTitle: author,
|
|
||||||
cover: cover,
|
|
||||||
tags: tags,
|
|
||||||
description: description
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
comics: data.list.map(parseComic),
|
|
||||||
maxPage: data.maxPage
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
*/
|
|
||||||
load: async () => {
|
|
||||||
let res = await Network.get("https://ymcdnyfqdapp.ikmmh.com/", {
|
|
||||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36"
|
|
||||||
})
|
|
||||||
if (res.status !== 200) {
|
|
||||||
throw "Invalid status code: " + res.status
|
|
||||||
}
|
|
||||||
let document = new HtmlDocument(res.body)
|
|
||||||
function parseComicDom(comicDom) {
|
|
||||||
let title = comicDom.querySelector("h4").text
|
|
||||||
let cover = comicDom.querySelector("img").attributes["data-src"]
|
|
||||||
let tags = []
|
|
||||||
let tagDoms = comicDom.querySelectorAll("div.tag-wrap > p")
|
|
||||||
for (let j = 0; j < tagDoms.length; j++) {
|
|
||||||
tags.push(tagDoms[j].text.trim())
|
|
||||||
}
|
|
||||||
tagDoms = comicDom.querySelectorAll("div.anime-mask > p")
|
|
||||||
for (let j = 0; j < tagDoms.length; j++) {
|
|
||||||
tags.push(tagDoms[j].text.trim())
|
|
||||||
}
|
|
||||||
let link = comicDom.querySelector("a").attributes["href"]
|
|
||||||
link = "https://ymcdnyfqdapp.ikmmh.com" + link
|
|
||||||
return {
|
|
||||||
title: title,
|
|
||||||
cover: cover,
|
|
||||||
tags: tags,
|
|
||||||
id: link
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
let data = {
|
|
||||||
"海量精品漫画": document.querySelectorAll("ul.panel-comic-r > li").map(parseComicDom),
|
|
||||||
"热门人气新番": document.querySelectorAll("ul.list-anime > li").map(parseComicDom),
|
|
||||||
}
|
|
||||||
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
);
|
||||||
|
let epData = JSON.parse(epRes.body);
|
||||||
|
let eps = new Map();
|
||||||
|
if (epData.data && epData.data.length > 0 && epData.data[0].list) {
|
||||||
|
epData.data[0].list.forEach((e) => {
|
||||||
|
let title = e.name;
|
||||||
|
let id = `${Ikm.baseUrl}${e.url}`;
|
||||||
|
eps.set(id, title);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
throw new Error(`章节数据格式异常`);
|
||||||
|
}
|
||||||
|
|
||||||
/// 分类页面
|
let title = document.querySelector(
|
||||||
/// 一个漫画源只能有一个分类页面, 也可以没有, 设置为null禁用分类页面
|
"div.book-hero__detail > div.title"
|
||||||
category = {
|
).text;
|
||||||
/// 标题, 同时为标识符, 不能与其他漫画源的分类页面重复
|
let escapedTitle = title.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
||||||
title: "爱看漫",
|
let thumb =
|
||||||
parts: [
|
document
|
||||||
{
|
.querySelector("div.coverimg")
|
||||||
name: "分类",
|
.attributes["style"].match(/\((.*?)\)/)?.[1] || "";
|
||||||
|
let desc = document
|
||||||
|
.querySelector("article.book-container__detail")
|
||||||
|
.text.match(
|
||||||
|
new RegExp(
|
||||||
|
`漫画名:${escapedTitle}(?:(?:[^。]*?(?:简介|漫画简介)\\s*[::]?\\s*)|(?:[^。]*?))([\\s\\S]+?)\\.\\.\\.。`
|
||||||
|
)
|
||||||
|
);
|
||||||
|
let intro = desc?.[1]?.trim().replace(/\s+/g, " ") || "";
|
||||||
|
|
||||||
// fixed 或者 random
|
return {
|
||||||
// random用于分类数量相当多时, 随机显示其中一部分
|
title: title.split("~")[0],
|
||||||
type: "fixed",
|
cover: thumb,
|
||||||
|
description: intro,
|
||||||
// 如果类型为random, 需要提供此字段, 表示同时显示的数量
|
tags: {
|
||||||
// randomNumber: 5,
|
作者: [
|
||||||
|
document
|
||||||
categories: ["全部", "长条", "大女主", "百合", "耽美", "纯爱", "後宫", "韩漫", "奇幻", "轻小说", "生活", "悬疑", "格斗", "搞笑", "伪娘", "竞技", "职场", "萌系", "冒险", "治愈", "都市", "霸总", "神鬼", "侦探", "爱情", "古风", "欢乐向", "科幻", "穿越", "性转换", "校园", "美食", "悬疑", "剧情", "热血", "节操", "励志", "异世界", "历史", "战争", "恐怖", "霸总", "全部", "连载中", "已完结", "全部", "日漫", "港台", "美漫", "国漫", "韩漫", "未分类",],
|
.querySelector("div.book-container__author")
|
||||||
|
.text.split("作者:")[1],
|
||||||
// category或者search
|
],
|
||||||
// 如果为category, 点击后将进入分类漫画页面, 使用下方的`categoryComics`加载漫画
|
更新: [document.querySelector("div.update > a > em").text],
|
||||||
// 如果为search, 将进入搜索页面
|
标签: document
|
||||||
itemType: "category",
|
.querySelectorAll("div.book-hero__detail > div.tags > a")
|
||||||
},
|
.map((e) => e.text.trim())
|
||||||
{
|
.filter((text) => text),
|
||||||
name: "更新",
|
|
||||||
type: "fixed",
|
|
||||||
categories: ["星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日"],
|
|
||||||
itemType: "category",
|
|
||||||
categoryParams: ['1', '2', '3', '4', '5', '6', '7']
|
|
||||||
}
|
|
||||||
],
|
|
||||||
enableRankingPage: false,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 分类漫画页面, 即点击分类标签后进入的页面
|
|
||||||
categoryComics = {
|
|
||||||
load: async (category, param, options, page) => {
|
|
||||||
category = encodeURIComponent(category)
|
|
||||||
let url = ""
|
|
||||||
if (param !== undefined && param !== null) {
|
|
||||||
url = `https://ymcdnyfqdapp.ikmmh.com/update/${param}.html`
|
|
||||||
} else {
|
|
||||||
url = `https://ymcdnyfqdapp.ikmmh.com/booklists/${options[1]}/${category}/${options[0]}/${page}.html`
|
|
||||||
}
|
|
||||||
let res = await Network.get(url, {
|
|
||||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36"
|
|
||||||
})
|
|
||||||
if (res.status !== 200) {
|
|
||||||
throw "Invalid status code: " + res.status
|
|
||||||
}
|
|
||||||
let document = new HtmlDocument(res.body)
|
|
||||||
|
|
||||||
function parseComic(element) {
|
|
||||||
let title = element.querySelector("h2").text
|
|
||||||
let cover = element.querySelector("img").attributes["data-src"]
|
|
||||||
let tags = []
|
|
||||||
let tagDoms = element.querySelectorAll("div.tag-list > p")
|
|
||||||
for (let j = 0; j < tagDoms.length; j++) {
|
|
||||||
tags.push(tagDoms[j].text.trim())
|
|
||||||
}
|
|
||||||
let link = element.querySelector("a").attributes["href"]
|
|
||||||
link = "https://ymcdnyfqdapp.ikmmh.com" + link
|
|
||||||
let updateInfo = element.querySelector("p.process").text
|
|
||||||
return {
|
|
||||||
title: title,
|
|
||||||
cover: cover,
|
|
||||||
tags: tags,
|
|
||||||
id: link,
|
|
||||||
subTitle: updateInfo
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
let maxPage = 1
|
|
||||||
if (param === undefined || param === null) {
|
|
||||||
maxPage = document.querySelectorAll("ul.list-page > li > a").pop().text
|
|
||||||
maxPage = parseInt(maxPage)
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
comics: document.querySelectorAll("ul.list-comic-book > li").map(parseComic),
|
|
||||||
maxPage: maxPage
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
// 提供选项
|
chapters: eps,
|
||||||
optionList: [
|
recommend: document
|
||||||
{
|
.querySelectorAll("div.module-guessu > div.item")
|
||||||
// 对于单个选项, 使用-分割, 左侧为用于数据加载的值, 即传给load函数的options参数; 右侧为显示给用户的文本
|
.map((e) => ({
|
||||||
options: [
|
title: e.querySelector("div.title").text.split("~")[0],
|
||||||
"3-全部",
|
cover: e.querySelector("div.thumb_img").attributes["data-src"],
|
||||||
"4-连载中",
|
id: `${Ikm.baseUrl}${e.querySelector("a").attributes["href"]}`,
|
||||||
"1-已完结",
|
})),
|
||||||
],
|
};
|
||||||
// 提供[]string, 当分类名称位于此数组中时, 禁用此选项
|
},
|
||||||
notShowWhen: ["星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日"],
|
onThumbnailLoad: Ikm.thumbConfig,
|
||||||
// 提供[]string, 当分类名称没有位于此数组中时, 禁用此选项
|
loadEp: async (comicId, epId) => {
|
||||||
showWhen: null
|
try {
|
||||||
},
|
let res = await Network.get(epId, Ikm.webHeaders);
|
||||||
{
|
let document = new HtmlDocument(res.body);
|
||||||
// 对于单个选项, 使用-分割, 左侧为用于数据加载的值, 即传给load函数的options参数; 右侧为显示给用户的文本
|
return {
|
||||||
options: [
|
images: document
|
||||||
"9-全部",
|
.querySelectorAll("img.lazy")
|
||||||
"1-日漫",
|
.map((e) => e.attributes["data-src"]),
|
||||||
"2-港台",
|
};
|
||||||
"3-美漫",
|
} catch (err) {
|
||||||
"4-国漫",
|
throw new Error(`加载章节失败:${err.message}`);
|
||||||
"5-韩漫",
|
}
|
||||||
"6-未分类"
|
},
|
||||||
],
|
onImageLoad: (url, comicId, epId) => {
|
||||||
// 提供[]string, 当分类名称位于此数组中时, 禁用此选项
|
return {
|
||||||
notShowWhen: ["星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日"],
|
url,
|
||||||
// 提供[]string, 当分类名称没有位于此数组中时, 禁用此选项
|
headers: {
|
||||||
showWhen: null
|
...Ikm.webHeaders,
|
||||||
},
|
Referer: epId,
|
||||||
],
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 搜索
|
|
||||||
search = {
|
|
||||||
load: async (keyword, options, page) => {
|
|
||||||
let res = await Network.get(`https://ymcdnyfqdapp.ikmmh.com/search?searchkey=${encodeURIComponent(keyword)}`, {
|
|
||||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36"
|
|
||||||
})
|
|
||||||
if (res.status !== 200) {
|
|
||||||
throw "Invalid status code: " + res.status
|
|
||||||
}
|
|
||||||
let document = new HtmlDocument(res.body)
|
|
||||||
|
|
||||||
function parseComic(element) {
|
|
||||||
let title = element.querySelector("a").text
|
|
||||||
let cover = element.querySelector("img").attributes["data-src"]
|
|
||||||
let link = element.querySelector("a").attributes["href"]
|
|
||||||
link = "https://ymcdnyfqdapp.ikmmh.com" + link
|
|
||||||
let updateInfo = element.querySelector("p.describe > a").text
|
|
||||||
return {
|
|
||||||
title: title,
|
|
||||||
cover: cover,
|
|
||||||
id: link,
|
|
||||||
subTitle: updateInfo
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
comics: document.querySelectorAll("div.classification").map(parseComic),
|
|
||||||
maxPage: 1
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
};
|
||||||
// 提供选项
|
},
|
||||||
optionList: []
|
};
|
||||||
}
|
|
||||||
|
|
||||||
/// 收藏
|
|
||||||
favorites = {
|
|
||||||
/// 是否为多收藏夹
|
|
||||||
multiFolder: false,
|
|
||||||
/// 添加或者删除收藏
|
|
||||||
addOrDelFavorite: async (comicId, folderId, isAdding) => {
|
|
||||||
let id = comicId.split("/")[4]
|
|
||||||
if (isAdding) {
|
|
||||||
let comicInfoRes = await Network.get(comicId, {
|
|
||||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36"
|
|
||||||
});
|
|
||||||
if (comicInfoRes.status !== 200) {
|
|
||||||
throw "Invalid status code: " + res.status
|
|
||||||
}
|
|
||||||
let document = new HtmlDocument(comicInfoRes.body)
|
|
||||||
let name = document.querySelector("h1").text;
|
|
||||||
let res = await Network.post("https://ymcdnyfqdapp.ikmmh.com/api/user/bookcase/add", {
|
|
||||||
"Content-Type": "application/x-www-form-urlencoded",
|
|
||||||
}, `articleid=${id}&articlename=${name}`)
|
|
||||||
if (res.status !== 200) {
|
|
||||||
throw "Invalid status code: " + res.status
|
|
||||||
}
|
|
||||||
let json = JSON.parse(res.body)
|
|
||||||
if (json["code"] === "0" || json["code"] === 0) {
|
|
||||||
return 'ok'
|
|
||||||
} else if (json["code"] === 1) {
|
|
||||||
throw "Login expired"
|
|
||||||
} else {
|
|
||||||
throw json["msg"].toString()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
let res = await Network.post("https://ymcdnyfqdapp.ikmmh.com/api/user/bookcase/del", {
|
|
||||||
"Content-Type": "application/x-www-form-urlencoded",
|
|
||||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36"
|
|
||||||
}, `articleid=${id}`)
|
|
||||||
if (res.status !== 200) {
|
|
||||||
error("Invalid status code: " + res.status)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let json = JSON.parse(res.body)
|
|
||||||
if (json["code"] === "0" || json["code"] === 0) {
|
|
||||||
success("ok")
|
|
||||||
} else if (json["code"] === 1) {
|
|
||||||
error("Login expired")
|
|
||||||
} else {
|
|
||||||
error(json["msg"].toString())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
/// 加载漫画
|
|
||||||
loadComics: async (page, folder) => {
|
|
||||||
let res = await Network.post("https://ymcdnyfqdapp.ikmmh.com/api/user/bookcase/ajax", {
|
|
||||||
"Content-Type": "application/x-www-form-urlencoded",
|
|
||||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36"
|
|
||||||
}, `page=${page}`)
|
|
||||||
if (res.status !== 200) {
|
|
||||||
throw "Invalid status code: " + res.status
|
|
||||||
}
|
|
||||||
let json = JSON.parse(res.body)
|
|
||||||
if (json["code"] === 1) {
|
|
||||||
throw "Login expired"
|
|
||||||
}
|
|
||||||
if (json["code"] !== "0" && json["code"] !== 0) {
|
|
||||||
throw "Invalid response: " + json["code"]
|
|
||||||
}
|
|
||||||
let comics = json["data"].map(e => {
|
|
||||||
return {
|
|
||||||
title: e["name"],
|
|
||||||
subTitle: e["author"],
|
|
||||||
cover: e["cover"],
|
|
||||||
id: "https://ymcdnyfqdapp.ikmmh.com" + e["info_url"]
|
|
||||||
}
|
|
||||||
})
|
|
||||||
let maxPage = json["end"]
|
|
||||||
return {
|
|
||||||
comics: comics,
|
|
||||||
maxPage: maxPage
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 单个漫画相关
|
|
||||||
comic = {
|
|
||||||
// 加载漫画信息
|
|
||||||
loadInfo: async (id) => {
|
|
||||||
let res = await Network.get(id, {
|
|
||||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36"
|
|
||||||
})
|
|
||||||
if (res.status !== 200) {
|
|
||||||
throw "Invalid status code: " + res.status
|
|
||||||
}
|
|
||||||
let document = new HtmlDocument(res.body)
|
|
||||||
let title = document.querySelector("h1.detail-title").text
|
|
||||||
let cover = document.querySelector("div.banner-img > img").attributes["data-src"]
|
|
||||||
let author = document.querySelector("p.author").text
|
|
||||||
let tags = document.querySelectorAll("p.ui-tag > a").map(e => e.text.trim())
|
|
||||||
let description = document.querySelector("div.detail-desc").text
|
|
||||||
let updateTime = document.querySelector("div.detail-info > div > span > b").text
|
|
||||||
let eps = {}
|
|
||||||
document.querySelectorAll("ol.chapter-list > li").forEach(element => {
|
|
||||||
let title = element.querySelector("a").attributes["title"]
|
|
||||||
let id = element.attributes["data-chapter"]
|
|
||||||
eps[id] = title
|
|
||||||
})
|
|
||||||
let comics = document.querySelectorAll("div.mod-vitem-comic").map(element => {
|
|
||||||
let title = element.querySelector("h4").text
|
|
||||||
let cover = element.querySelector("img").attributes["data-src"]
|
|
||||||
let link = element.querySelector("a").attributes["href"]
|
|
||||||
link = "https://ymcdnyfqdapp.ikmmh.com" + link
|
|
||||||
return {
|
|
||||||
title: title,
|
|
||||||
cover: cover,
|
|
||||||
id: link
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return {
|
|
||||||
title: title,
|
|
||||||
cover: cover,
|
|
||||||
description: description,
|
|
||||||
tags: {
|
|
||||||
"作者": [author],
|
|
||||||
"更新": [updateTime],
|
|
||||||
"标签": tags
|
|
||||||
},
|
|
||||||
chapters: eps,
|
|
||||||
suggestions: comics
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// 获取章节图片
|
|
||||||
loadEp: async (comicId, epId) => {
|
|
||||||
if (comicId.includes("https://")) {
|
|
||||||
comicId = comicId.split("/")[4]
|
|
||||||
}
|
|
||||||
let res = await Network.get(
|
|
||||||
`https://ymcdnyfqdapp.ikmmh.com/chapter/${comicId}/${epId}.html`,
|
|
||||||
{
|
|
||||||
"Referer": `https://ymcdnyfqdapp.ikmmh.com/book/${comicId}.html`,
|
|
||||||
"User-Agent": "Mozilla/5.0 (Linux; Android 10; SM-G9600) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.181 Mobile Safari/537.36"
|
|
||||||
}
|
|
||||||
)
|
|
||||||
if (res.status !== 200) {
|
|
||||||
throw "Invalid status code: " + res.status
|
|
||||||
}
|
|
||||||
let document = new HtmlDocument(res.body)
|
|
||||||
return {
|
|
||||||
images: document.querySelectorAll("img.lazy").map(e => e.attributes["data-src"])
|
|
||||||
}
|
|
||||||
},
|
|
||||||
/// 警告: 这是历史遗留问题, 对于新的漫画源, 不应当使用此字段, 在选取漫画id时, 不应当出现特殊字符
|
|
||||||
matchBriefIdRegex: "https://ymcdnyfqdapp.ikmmh.com/book/(\\d+)/"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user