奇书网
https://www.qishuxia.com
zpccool (13551) 1天前 下载:363
小说 小说 免费
奇书网 - 好看的小说大全免费在线阅读和txt下载
// @name 奇书网
// @version 1.1.0
// @uuid qishuwang
// @author Ai
// @url https://www.qishuxia.com
// @type novel
// @enabled true
// @tags 小说,免费
// @description 奇书网 - 好看的小说大全免费在线阅读和txt下载
var BASE = 'https://www.qishuxia.com';
var CATEGORIES = [
{ title: '玄幻奇幻', id: 'xuanhuanxiaoshuo' },
{ title: '武侠仙侠', id: 'xiuzhenxiaoshuo' },
{ title: '都市言情', id: 'dushixiaoshuo' },
{ title: '历史军事', id: 'lishixiaoshuo' },
{ title: '科幻灵异', id: 'kehuanxiaoshuo' },
{ title: '网游竞技', id: 'wangyouxiaoshuo' },
{ title: '女生频道', id: 'nvshengxiaoshuo' }
];
function absUrl(url, baseUrl) {
if (!url) return '';
if (url.indexOf('http') === 0) return url;
if (url.indexOf('/') === 0) return BASE + url;
var base = baseUrl || BASE;
var lastSlash = base.lastIndexOf('/');
if (lastSlash <= 7) return base + '/' + url;
return base.substring(0, lastSlash + 1) + url;
}
// isSearch: 搜索结果 s4=作者, s5=日期; 发现页 s5=作者
function parseBooks(doc, defaultKind, isSearch) {
var books = [];
var items = legado.dom.selectAll(doc, 'li');
var seen = {};
for (var i = 0; i < items.length; i++) {
var li = items[i];
var kind = legado.dom.selectText(li, 'span.s1') || defaultKind || '';
kind = kind.replace(/^\[|\]$/g, '');
var aEl = legado.dom.select(li, 'span.s2 a');
if (!aEl) continue;
var href = legado.dom.attr(aEl, 'href') || '';
var name = legado.dom.text(aEl) || '';
if (!name || !href) continue;
var author = '';
if (isSearch) {
author = legado.dom.selectText(li, 'span.s4') || '';
} else {
author = legado.dom.selectText(li, 'span.s5') || legado.dom.selectText(li, 'span.s4') || '';
}
var bookUrl = absUrl(href);
if (!seen[bookUrl]) {
seen[bookUrl] = true;
books.push({ name: name, author: author, bookUrl: bookUrl, coverUrl: '', kind: kind, lastChapter: '' });
}
}
return books;
}
function parseBookInfo(html) {
var result = { name: '', author: '', coverUrl: '', intro: '', kind: '', lastChapter: '' };
var metas = [
{ key: 'name', pattern: /<meta property="og:novel:book_name" content="([^"]+)"/i },
{ key: 'name', pattern: /<meta property="og:title" content="([^"]+)"/i },
{ key: 'author', pattern: /<meta property="og:novel:author" content="([^"]+)"/i },
{ key: 'coverUrl', pattern: /<meta property="og:image" content="([^"]+)"/i },
{ key: 'intro', pattern: /<meta property="og:description" content="([^"]+)"/i },
{ key: 'kind', pattern: /<meta property="og:novel:category" content="([^"]+)"/i },
{ key: 'lastChapter', pattern: /<meta property="og:novel:latest_chapter_name" content="([^"]+)"/i }
];
for (var i = 0; i < metas.length; i++) {
var meta = metas[i];
if (result[meta.key]) continue;
var match = html.match(meta.pattern);
if (match && match[1]) result[meta.key] = match[1];
}
if (!result.name) result.name = '未知书名';
if (!result.author) result.author = '未知作者';
return result;
}
async function explore(page, category) {
try {
if (category === 'GETALL' || !category) {
var names = [];
for (var i = 0; i < CATEGORIES.length; i++) names.push(CATEGORIES[i].title);
return names;
}
var catId = null;
for (var j = 0; j < CATEGORIES.length; j++) {
if (CATEGORIES[j].title === category) { catId = CATEGORIES[j].id; break; }
}
if (!catId) return [];
var pageNum = page || 1;
var url = BASE + '/' + catId + '/';
if (pageNum > 1) url = BASE + '/' + catId + '/' + pageNum + '.html';
var html = await legado.http.get(url);
var doc = legado.dom.parse(html);
var books = parseBooks(doc, category, false);
legado.log('[explore] cat=' + category + ' count=' + books.length);
return books;
} catch (e) {
legado.log('[explore] error: ' + (e.message || 'unknown'));
return [];
}
}
async function bookInfo(bookUrl) {
try {
var url = absUrl(bookUrl);
var html = await legado.http.get(url);
var info = parseBookInfo(html);
return {
name: info.name, author: info.author, bookUrl: url, tocUrl: url,
coverUrl: absUrl(info.coverUrl), intro: info.intro, kind: info.kind, lastChapter: info.lastChapter
};
} catch (e) {
legado.log('[bookInfo] error: ' + (e.message || 'unknown'));
return { name: '未知书名', author: '未知作者', bookUrl: bookUrl, tocUrl: bookUrl, coverUrl: '', intro: '', kind: '小说', lastChapter: '' };
}
}
async function chapterList(tocUrl) {
try {
var url = absUrl(tocUrl);
var html = await legado.http.get(url);
var doc = legado.dom.parse(html);
var listEl = legado.dom.select(doc, '#section-list');
var container = listEl || doc;
var anchors = legado.dom.selectAll(container, 'a');
var chapters = [];
var seen = {};
for (var i = 0; i < anchors.length; i++) {
var a = anchors[i];
var href = legado.dom.attr(a, 'href') || '';
var name = legado.dom.text(a) || '';
if (!href || !name) continue;
if (href.indexOf('.html') === -1) continue;
if (href.indexOf('//') >= 0 && href.indexOf('/book/') === -1) continue;
var chUrl = absUrl(href, url);
if (!seen[chUrl]) {
seen[chUrl] = true;
chapters.push({ name: name, url: chUrl });
}
}
legado.log('[chapterList] count=' + chapters.length);
return chapters;
} catch (e) {
legado.log('[chapterList] error: ' + (e.message || 'unknown'));
return [];
}
}
async function chapterContent(chapterUrl) {
try {
var url = absUrl(chapterUrl);
var html = await legado.http.get(url);
var doc = legado.dom.parse(html);
var contentEl = legado.dom.select(doc, '#content');
if (!contentEl) contentEl = legado.dom.select(doc, '.content');
if (!contentEl) {
legado.log('[chapterContent] no content element found');
return '';
}
legado.dom.remove(contentEl, 'script, style');
var text = legado.dom.text(contentEl);
text = text
.replace(/记住网站域名www[^\s]+com/g, '')
.replace(/天才一秒记住[^\s]+最快更新/g, '')
.replace(/本章未完[^\n]*/g, '')
.replace(/请收藏[^\n]*/g, '')
.replace(/章节报错[^\n]*/g, '')
.trim();
legado.log('[chapterContent] len=' + text.length);
return text;
} catch (e) {
legado.log('[chapterContent] error: ' + (e.message || 'unknown'));
return '';
}
}
async function search(keyword, page) {
try {
if (!keyword) return [];
var encoded = await legado.urlEncodeCharset(keyword, 'gbk');
var body = 'searchkey=' + encoded;
if (page && page > 1) body += '&page=' + page;
var html = await legado.http.post(
BASE + '/modules/article/search.php',
body,
{ 'Content-Type': 'application/x-www-form-urlencoded', 'Referer': BASE + '/' }
);
var doc = legado.dom.parse(html);
var books = parseBooks(doc, '', true);
legado.log('[search] keyword=' + keyword + ' count=' + books.length);
return books;
} catch (e) {
legado.log('[search] error: ' + (e.message || 'unknown'));
return [];
}
}
async function TEST(type) {
if (type === '__list__') return ['search', 'explore'];
if (type === 'search') {
var r = await search('斗破苍穹', 1);
if (!r || r.length < 1) return { passed: false, message: '搜索无结果' };
return { passed: true, message: '搜索返回 ' + r.length + ' 条' };
}
if (type === 'explore') {
var b = await explore(1, '都市言情');
if (!b || b.length < 1) return { passed: false, message: '发现页为空' };
return { passed: true, message: '发现页 ' + b.length + ' 条' };
}
return { passed: false, message: '未知: ' + type };
}