Compare commits

..

2 Commits

Author SHA1 Message Date
nyne
f4bc304d1b Update index.json 2025-08-01 09:18:41 +08:00
Zion
08756ee659 fix search bug from manhuagui (#119)
* add new source from comick

* fix some code

* fix gif load and comic list info(none-type/chapter/volume)

* add some comick hidden tags

* revise coding error in file

* info updata time

* fix no-EN error

* add new function

- Multi-language comic selection support
- Added comic recommendations
- Fixed empty chapter return bug
- Resolved tag click issues
- Optimized data processing

* Optimize network request

Remove redundant requests and prevent async deadlocks

* Update comick.js

* new small comic source from baihehui

* Fixed some bugs and added some sorting methods

* Fixed some bugs and added some sorting methods

* Add a new resource from ykmh

* Remove invalid request

* fixed chapter api

* Update index.json

* Update index.json

* Update comick.js

* fix search bug from manhuagui

Fix ”querySelectorAll“ bug in search page.
Add multi-group of chapters in info page.
2025-08-01 08:52:44 +08:00
2 changed files with 171 additions and 35 deletions

View File

@@ -95,15 +95,16 @@
{ {
"name": "漫画柜", "name": "漫画柜",
"fileName": "manhuagui.js", "fileName": "manhuagui.js",
"key": "manhuagui", "key": "ManHuaGui",
"version": "1.0.0" "version": "1.0.1"
}, },
{ {
"name": "优酷漫画", "name": "优酷漫画",
"fileName": "ykmh.js", "fileName": "ykmh.js",
"key": "ykmh", "key": "ykmh",
"version": "1.0.0" "version": "1.0.0"
},{ },
{
"name": "漫蛙吧", "name": "漫蛙吧",
"fileName": "manwaba.js", "fileName": "manwaba.js",
"key": "manwaba", "key": "manwaba",

View File

@@ -8,7 +8,7 @@ class ManHuaGui extends ComicSource {
// unique id of the source // unique id of the source
key = "ManHuaGui"; key = "ManHuaGui";
version = "1.0.0"; version = "1.0.1";
minAppVersion = "1.4.0"; minAppVersion = "1.4.0";
@@ -17,6 +17,20 @@ class ManHuaGui extends ComicSource {
"https://cdn.jsdelivr.net/gh/venera-app/venera-configs@main/manhuagui.js"; "https://cdn.jsdelivr.net/gh/venera-app/venera-configs@main/manhuagui.js";
baseUrl = "https://www.manhuagui.com"; baseUrl = "https://www.manhuagui.com";
isAppVersionAfter(target) {
if (!APP || !APP.version) return false;
let current = APP.version;
let targetArr = target.split('.');
let currentArr = current.split('.');
for (let i = 0; i < 3; i++) {
if (parseInt(currentArr[i]) < parseInt(targetArr[i])) {
return false;
}
}
return true;
}
async getHtml(url) { async getHtml(url) {
let headers = { let headers = {
accept: accept:
@@ -624,6 +638,76 @@ class ManHuaGui extends ComicSource {
}, },
}; };
/**
* 专门解析搜索结果页面中的漫画信息
* @param {HTMLElement} item - 搜索结果中的单个漫画项
* @returns {Comic} - 解析后的漫画对象
*/
parseSearchComic(item) {
try {
// 获取漫画链接和ID
let linkElement = item.querySelector(".book-detail dl dt a");
if (!linkElement) return null;
let url = linkElement.attributes["href"];
let id = url.split("/")[2];
let title = linkElement.text.trim();
// 获取封面图片
let coverElement = item.querySelector(".book-cover .bcover img");
let cover = coverElement ? coverElement.attributes["src"] : null;
if (cover) {
cover = cover.startsWith("//") ? `https:${cover}` : cover;
}
// 获取更新状态和描述
let statusElement = item.querySelector(".tags.status span .red");
let status = statusElement ? statusElement.text.trim() : "";
let updateElement = item.querySelector(".tags.status span .red:nth-child(2)");
let updateTime = updateElement ? updateElement.text.trim() : "";
// 获取评分信息
let scoreElement = item.querySelector(".book-score .score-avg strong");
let score = scoreElement ? scoreElement.text.trim() : "";
// 获取作者信息
let authorElements = item.querySelectorAll(".tags a[href*='/author/']");
let author = authorElements.length > 0
? authorElements.map(a => a.text.trim()).join(", ")
: "";
// 获取类型信息
let typeElements = item.querySelectorAll(".tags a[href*='/list/']");
let types = typeElements.length > 0
? typeElements.map(a => a.text.trim())
: [];
// 获取简介
let introElement = item.querySelector(".intro span");
let description = introElement ? introElement.text.replace("简介:", "").trim() : "";
// 如果简介为空,使用更新状态作为描述
if (!description && status) {
description = `状态: ${status}`;
if (updateTime) description += `, 更新: ${updateTime}`;
}
return new Comic({
id,
title,
cover,
description,
tags: [...types, status],
author,
score
});
} catch (error) {
console.error("解析搜索结果项时出错:", error);
return null;
}
}
/// search related /// search related
search = { search = {
/** /**
@@ -634,44 +718,63 @@ class ManHuaGui extends ComicSource {
* @returns {Promise<{comics: Comic[], maxPage: number}>} * @returns {Promise<{comics: Comic[], maxPage: number}>}
*/ */
load: async (keyword, options, page) => { load: async (keyword, options, page) => {
let url = `${this.baseUrl}/s/${keyword}_p${page}.html`; let url = ""
if (options[0]) {
let type = options[0].split("-")[0];
if (type == '0') {
url = `${this.baseUrl}/s/${keyword}_p${page}.html`;
} else{
url = `${this.baseUrl}/s/${keyword}_o${type}_p${page}.html`;
}
}else{
url = `${this.baseUrl}/s/${keyword}_p${page}.html`;
}
let document = await this.getHtml(url); let document = await this.getHtml(url);
let comicNum = document
.querySelector(".result-count") // 检查是否有结果计数元素
.querySelectorAll("strong")[1].text; let resultCount = document.querySelector(".result-count");
if (!resultCount) {
// 没有搜索结果或页面结构不同
return {
comics: [],
maxPage: 1
};
}
let comicNum = resultCount.querySelectorAll("strong")[1].text;
comicNum = parseInt(comicNum); comicNum = parseInt(comicNum);
// 每页10个 // 每页10个
let maxPage = Math.ceil(comicNum / 10); let maxPage = Math.ceil(comicNum / 10);
let bookshelf = document // 在搜索结果页面中,漫画列表位于 .book-result ul 下
.querySelector("#contList") let comicList = document.querySelector(".book-result ul");
.querySelectorAll("li"); if (!comicList) {
let comics = bookshelf.map((e) => this.parseComic(e)); return {
comics: [],
maxPage: maxPage || 1
};
}
// 使用专门的搜索解析函数解析每个漫画项
let comics = comicList.querySelectorAll("li.cf")
.map(item => this.parseSearchComic(item))
.filter(comic => comic !== null); // 过滤掉解析失败的项
return { return {
comics, comics,
maxPage, maxPage,
}; };
}, },
// provide options for search
optionList: [ optionList: [
{ {
// [Optional] default is `select`
// type: select, multi-select, dropdown
// For select, there is only one selected value
// For multi-select, there are multiple selected values or none. The `load` function will receive a json string which is an array of selected values
// For dropdown, there is one selected value at most. If no selected value, the `load` function will receive a null
type: "select", type: "select",
// For a single option, use `-` to separate the value and text, left for value, right for text options: ["0-最新更新", "1-最近最热","2-最新上架", "3-评分最高"],
options: ["0-time", "1-popular"],
// option label
label: "sort", label: "sort",
// default selected options. If not set, use the first option as default
default: null, default: null,
}, },
], ],
// enable tags suggestions
enableTagsSuggestions: false, enableTagsSuggestions: false,
}; };
@@ -734,20 +837,52 @@ class ManHuaGui extends ComicSource {
let updateTime = detail_list[8].text.trim(); let updateTime = detail_list[8].text.trim();
// ANCHOR 章节信息 // ANCHOR 章节信息
let chapters = new Map(); // 支持多分组
let chapter_list = document.querySelector("#chapter-list-1"); let chaptersMap = new Map();
if (!chapter_list) {
chapter_list = document.querySelector("#chapter-list-0"); // 查找所有章节分组标题
let chapterGroups = document.querySelectorAll(".chapter h4 span");
// 处理每个分组
for (let i = 0; i < chapterGroups.length; i++) {
let groupName = chapterGroups[i].text.trim();
let groupChapters = new Map();
// 获取对应的章节列表
let chapterList = document.querySelectorAll(".chapter-list")[i];
if (chapterList) {
let lis = chapterList.querySelectorAll("li");
for (let li of lis) {
let a = li.querySelector("a");
let id = a.attributes["href"].split("/").pop().replace(".html", "");
let title = a.querySelector("span").text.trim();
groupChapters.set(id, title);
}
// 章节升序排列
groupChapters = new Map([...groupChapters].sort((a, b) => a[0] - b[0]));
// 将分组添加到总的章节映射中
chaptersMap.set(groupName, groupChapters);
}
} }
let lis = chapter_list.querySelectorAll("li");
for (let li of lis) { // 兼容旧版本如果app版本不支持多分组则合并所有分组
let a = li.querySelector("a"); let chapters;
let i = a.attributes["href"].split("/").pop().replace(".html", ""); if (this.isAppVersionAfter && this.isAppVersionAfter("1.3.0")) {
let title = a.querySelector("span").text.trim(); // 支持多分组
chapters.set(i, title); chapters = chaptersMap;
} else {
// 合并所有分组
chapters = new Map();
for (let [_, groupChapters] of chaptersMap) {
for (let [id, title] of groupChapters) {
chapters.set(id, title);
}
}
// 章节升序
chapters = new Map([...chapters].sort((a, b) => a[0] - b[0]));
} }
// chapters 升序
chapters = new Map([...chapters].sort((a, b) => a[0] - b[0]));
//ANCHOR - 推荐 //ANCHOR - 推荐
let recommend = []; let recommend = [];