红袖添香
https://www.hongxiu.com
zpccool (13551) 16小时前 下载:320
小说
红袖添香小说网 - 免费无弹窗小说阅读(已过滤作品相关)
// @name 红袖添香
// @uuid hongxiutianxiang
// @version 1.0.0
// @author AI
// @url https://www.hongxiu.com
// @type novel
// @enabled true
// @description 红袖添香小说网 - 免费无弹窗小说阅读(已过滤作品相关)
var BASE = 'https://www.hongxiu.com';
var SEARCH_BASE = 'https://www.hongxiu.com';
var EXPLORE_BASE = 'https://www.hongxiu.com';
var BOOK_BASE = 'https://www.hongxiu.com';
var GENRE_MAP = {
'现代言情': '30020',
'古代言情': '30013',
'浪漫青春': '30031',
'玄幻言情': '30001',
'仙侠奇缘': '30008',
'悬疑': '30036',
'科幻空间': '30042',
'游戏竞技': '30050',
'短篇小说': '30083',
'轻小说': '30055'
};
var GENRE_LIST = Object.keys(GENRE_MAP);
function _trim(s) {
if (!s) return '';
return String(s).replace(/^[\s\u3000\u00A0]+|[\s\u3000\u00A0]+$/g, '').trim();
}
async function search(keyword, page) {
legado.log('[search] keyword=' + keyword + ' page=' + page);
var result = [];
var url = SEARCH_BASE + '/so/' + encodeURIComponent(keyword);
var html = await legado.http.get(url);
legado.log('[search] html length=' + (html ? html.length : 'null'));
if (!html || html.length < 500) {
return result;
}
var doc = legado.dom.parse(html);
var listItems = legado.dom.selectAll(doc, '#result-list li');
legado.log('[search] listItems count=' + (listItems ? listItems.length : 0));
for (var i = 0; i < listItems.length; i++) {
var item = listItems[i];
var bookBox = legado.dom.select(item, '.book-img-box');
var bookLink = bookBox ? legado.dom.select(bookBox, 'a') : null;
var bookUrl = bookLink ? legado.dom.attr(bookLink, 'href') || '' : '';
var coverEl = bookBox ? legado.dom.select(bookBox, 'img') : null;
var coverUrl = coverEl ? legado.dom.attr(coverEl, 'src') || '' : '';
var midInfo = legado.dom.select(item, '.book-mid-info');
var titleEl = midInfo ? legado.dom.select(midInfo, 'h4 a') : null;
var name = titleEl ? legado.dom.text(titleEl) : '';
name = name.replace(/<[^>]+>/g, '').trim();
var authorEl = midInfo ? legado.dom.select(midInfo, 'a.name') : null;
var author = authorEl ? legado.dom.text(authorEl) : '';
var kindEl = midInfo ? legado.dom.select(midInfo, 'a[href*="/category/"]') : null;
var kind = kindEl ? legado.dom.text(kindEl) : '';
var introEl = midInfo ? legado.dom.select(midInfo, 'p.intro') : null;
var intro = introEl ? legado.dom.text(introEl) : '';
legado.log('[search] item ' + i + ': name=' + name + ' author=' + author + ' url=' + bookUrl);
if (bookUrl && name) {
if (bookUrl.indexOf('http') !== 0) {
bookUrl = SEARCH_BASE + bookUrl;
}
if (coverUrl && coverUrl.indexOf('//') === 0) {
coverUrl = 'https:' + coverUrl;
}
result.push({
name: _trim(name),
author: _trim(author),
bookUrl: bookUrl,
coverUrl: coverUrl,
intro: _trim(intro),
kind: _trim(kind),
lastChapter: ''
});
}
}
legado.log('[search] found=' + result.length);
legado.dom.free(doc);
return result;
}
async function bookInfo(bookUrl) {
legado.log('[bookInfo] url=' + bookUrl);
if (bookUrl.indexOf('m.xxsy.net') >= 0) {
bookUrl = bookUrl.replace('m.xxsy.net', 'www.hongxiu.com');
legado.log('[bookInfo] converted to pc: ' + bookUrl);
}
var result = {
name: '',
author: '',
bookUrl: bookUrl,
coverUrl: '',
intro: '',
kind: '',
lastChapter: '',
wordCount: '',
tocUrl: bookUrl
};
var html = await legado.http.get(bookUrl);
if (!html || html.length < 500) {
return result;
}
var doc = legado.dom.parse(html);
var nameEl = legado.dom.select(doc, 'h1.book-title');
if (nameEl) {
result.name = _trim(legado.dom.text(nameEl));
}
if (!result.name) {
var nameEl2 = legado.dom.select(doc, '.book-info h1');
if (nameEl2) {
result.name = _trim(legado.dom.text(nameEl2));
}
}
var authorEl = legado.dom.select(doc, 'span.book-author');
if (authorEl) {
result.author = _trim(legado.dom.text(authorEl));
}
var coverEl = legado.dom.select(doc, '.book-img img');
if (coverEl) {
result.coverUrl = legado.dom.attr(coverEl, 'src') || legado.dom.attr(coverEl, 'data-src') || '';
if (result.coverUrl && result.coverUrl.indexOf('//') === 0) {
result.coverUrl = 'https:' + result.coverUrl;
}
}
var introEl = legado.dom.select(doc, 'p.book-intro');
if (introEl) {
result.intro = _trim(legado.dom.text(introEl));
}
if (!result.intro) {
var introEl2 = legado.dom.select(doc, '.book-desc');
if (introEl2) {
result.intro = _trim(legado.dom.text(introEl2));
}
}
var kindEl = legado.dom.select(doc, 'a.tag');
if (kindEl) {
result.kind = _trim(legado.dom.text(kindEl));
}
var lastChEl = legado.dom.select(doc, '.book-chapter a.chapterName');
if (lastChEl) {
result.lastChapter = _trim(legado.dom.text(lastChEl));
}
var tocLink = legado.dom.select(doc, '#j_catalogPage');
if (tocLink) {
var tocHref = legado.dom.attr(tocLink, 'href');
if (tocHref) {
result.tocUrl = tocHref.indexOf('http') === 0 ? tocHref : BOOK_BASE + tocHref;
}
} else {
var tocLink2 = legado.dom.select(doc, '.j_catalog_block a');
if (tocLink2) {
var tocHref = legado.dom.attr(tocLink2, 'href');
if (tocHref) {
result.tocUrl = tocHref.indexOf('http') === 0 ? tocHref : BOOK_BASE + tocHref;
}
}
}
legado.log('[bookInfo] name=' + result.name + ' author=' + result.author);
legado.dom.free(doc);
return result;
}
async function chapterList(tocUrl) {
legado.log('[chapterList] url=' + tocUrl);
var result = [];
if (tocUrl.indexOf('m.xxsy.net') >= 0) {
tocUrl = tocUrl.replace('m.xxsy.net', 'www.hongxiu.com');
legado.log('[chapterList] converted to pc: ' + tocUrl);
}
if (tocUrl.indexOf('chapterlist') >= 0) {
var bookUrl = tocUrl.replace('/chapterlist/', '/book/');
legado.log('[chapterList] try book page: ' + bookUrl);
var pcResult = await chapterList(bookUrl);
if (pcResult && pcResult.length > 0) {
return pcResult;
}
}
var html = await legado.http.get(tocUrl);
if (!html || html.length < 500) {
return result;
}
// ---------- 新增:移除“作品相关”分卷的全部内容 ----------
var h3Pattern = /<h3[^>]*>[\s\S]*?<\/h3>/g;
var h3Positions = [];
var match;
while ((match = h3Pattern.exec(html)) !== null) {
h3Positions.push({ index: match.index, text: match[0].replace(/<[^>]+>/g, '').trim() });
}
var cleanedHtml = html;
var removeRanges = [];
for (var i = 0; i < h3Positions.length; i++) {
if (h3Positions[i].text.indexOf('作品相关') !== -1) {
var start = h3Positions[i].index;
var end = (i + 1 < h3Positions.length) ? h3Positions[i + 1].index : html.length;
removeRanges.push({ start: start, end: end });
}
}
// 从后往前删除,避免索引错乱
for (var j = removeRanges.length - 1; j >= 0; j--) {
cleanedHtml = cleanedHtml.substring(0, removeRanges[j].start) + cleanedHtml.substring(removeRanges[j].end);
}
// ---------- 结束 ----------
var doc = legado.dom.parse(cleanedHtml);
// 原有逻辑:寻找“正文”分卷,进一步缩小范围(如果存在)
var zhengwenStart = -1;
var h3Matches = cleanedHtml.match(/<h3[^>]*>[\s\S]*?<\/h3>/g);
if (h3Matches) {
for (var i = 0; i < h3Matches.length; i++) {
var h3Text = h3Matches[i].replace(/<[^>]+>/g, '').replace(/&[^;]+;/g, '');
if (h3Text.indexOf('正文') >= 0) {
zhengwenStart = cleanedHtml.indexOf(h3Matches[i]);
break;
}
}
}
if (zhengwenStart > 0) {
var afterZhengwen = cleanedHtml.substring(zhengwenStart);
var nextH3 = afterZhengwen.indexOf('<h3');
var zhengwenSection;
if (nextH3 > 0) {
zhengwenSection = afterZhengwen.substring(0, nextH3);
} else {
zhengwenSection = afterZhengwen;
}
var liMatches = zhengwenSection.match(/<li[^>]*><a[^>]*href="([^"]+)"[^>]*>([^<]+)<\/a>/g);
if (liMatches) {
for (var i = 0; i < liMatches.length; i++) {
var m = liMatches[i].match(/href="([^"]+)"[^>]*>([^<]+)/);
if (m && m[1] && m[2]) {
var url = m[1];
var name = _trim(m[2]);
if (_isValidChapter(url, name)) {
if (url.indexOf('http') !== 0) {
url = BOOK_BASE + url;
}
result.push({ name: name, url: url });
}
}
}
}
}
// 如果上一步没提取到章节,则提取全部列表(此时已无“作品相关”)
if (result.length === 0) {
var chapterItems = legado.dom.selectAll(doc, 'ul.j_catalogList li');
if (!chapterItems || chapterItems.length === 0) {
chapterItems = legado.dom.selectAll(doc, 'ul li');
}
for (var k = 0; k < chapterItems.length; k++) {
var item = chapterItems[k];
var linkEl = legado.dom.select(item, 'a');
if (!linkEl) continue;
var chapterUrl = legado.dom.attr(linkEl, 'href');
var chapterName = legado.dom.text(linkEl);
if (_isValidChapter(chapterUrl, chapterName)) {
if (chapterUrl.indexOf('http') !== 0) {
chapterUrl = BOOK_BASE + chapterUrl;
}
result.push({ name: _trim(chapterName), url: chapterUrl });
}
}
}
legado.log('[chapterList] found=' + result.length);
legado.dom.free(doc);
return result;
}
function _isValidChapter(url, name) {
if (!url || !name || name.length < 2) return false;
if (url.indexOf('javascript') >= 0) return false;
if (url.indexOf('/category') >= 0) return false;
if (url.indexOf('/rank') >= 0) return false;
if (url.indexOf('/free') >= 0) return false;
if (url.indexOf('/chapter/') < 0) return false;
var chapterNumMatch = url.match(/\/(\d+)$/);
if (!chapterNumMatch) return false;
var lowerName = name.toLowerCase();
if (lowerName.indexOf('新书') >= 0) return false;
if (lowerName.indexOf('试阅') >= 0) return false;
if (lowerName.indexOf('手游') >= 0) return false;
if (lowerName.indexOf('公测') >= 0) return false;
if (lowerName.indexOf('服务器') >= 0) return false;
if (lowerName.indexOf('玄界之门') >= 0) return false;
if (lowerName.indexOf('魔天记') >= 0) return false;
if (lowerName.indexOf('最新章节') >= 0) return false;
if (lowerName.indexOf('推荐总榜') >= 0) return false;
if (lowerName.indexOf('不到') >= 0 && lowerName.indexOf('票') >= 0) return false;
return true;
}
async function chapterContent(chapterUrl) {
legado.log('[chapterContent] url=' + chapterUrl);
var content = '';
var html = await legado.http.get(chapterUrl);
if (!html || html.length < 200) {
return content;
}
var doc = legado.dom.parse(html);
var contentEl = legado.dom.select(doc, '.j_readContent');
if (contentEl) {
var lines = [];
var ps = legado.dom.selectAll(contentEl, 'p');
if (ps && ps.length > 0) {
for (var i = 0; i < ps.length; i++) {
var line = _trim(legado.dom.text(ps[i]));
if (line) {
lines.push(line);
}
}
}
if (lines.length > 0) {
content = lines.join('\n\n');
} else {
content = _trim(legado.dom.text(contentEl));
}
}
if (!content) {
var contentEl2 = legado.dom.select(doc, '.ywskythunderfont');
if (contentEl2) {
content = _trim(legado.dom.text(contentEl2));
}
}
content = content.replace(/window\.[a-zA-Z0-9=]+/, '').trim();
content = content.replace(/=\s*"[^"]*"\s*;?\s*$/, '').trim();
content = content.replace(/\s*=\s*$/, '').trim();
content = content.replace(/\s+$/, '');
legado.log('[chapterContent] length=' + content.length);
legado.dom.free(doc);
return content;
}
async function explore(category, page) {
legado.log('[explore] page=' + page + ' category=' + category);
if (typeof category === 'number') {
var temp = category;
category = page;
page = temp;
}
if (category === 'GETALL' || category === undefined || category === null) {
return GENRE_LIST.slice();
}
var result = [];
var slug = GENRE_MAP[category];
if (!slug) {
legado.log('[explore] unknown category: ' + category);
return result;
}
var p = page && page > 1 ? page : 1;
var url = EXPLORE_BASE + '/category/' + slug + '_f1_f1_f1_f1_f1_0_' + p;
legado.log('[explore] url=' + url);
var html = await legado.http.get(url);
if (!html || html.length < 500) {
return result;
}
var doc = legado.dom.parse(html);
var bookItems = legado.dom.selectAll(doc, '.all-pro-wrap li');
for (var i = 0; i < bookItems.length; i++) {
var item = bookItems[i];
var linkEl = legado.dom.select(item, '.book-info h3 a');
if (!linkEl) continue;
var bookUrl = legado.dom.attr(linkEl, 'href');
var name = legado.dom.attr(linkEl, 'title') || legado.dom.text(linkEl);
var authorEl = legado.dom.select(item, '.book-info h4 a');
var author = authorEl ? legado.dom.text(authorEl) : '';
var coverEl = legado.dom.select(item, '.book-img img');
var coverUrl = coverEl ? legado.dom.attr(coverEl, 'src') || '' : '';
var introEl = legado.dom.select(item, '.book-info p.intro');
var intro = introEl ? legado.dom.text(introEl) : '';
var tagEls = legado.dom.selectAll(item, '.book-info p.tag span');
var kind = '';
var wordCount = '';
if (tagEls && tagEls.length > 0) {
kind = legado.dom.text(tagEls[0]);
}
if (tagEls && tagEls.length > 2) {
wordCount = legado.dom.text(tagEls[2]);
}
if (bookUrl && name) {
if (bookUrl.indexOf('http') !== 0) {
bookUrl = BASE + bookUrl;
}
if (coverUrl && coverUrl.indexOf('//') === 0) {
coverUrl = 'https:' + coverUrl;
}
result.push({
name: _trim(name),
author: _trim(author),
bookUrl: bookUrl,
coverUrl: coverUrl,
intro: _trim(intro),
kind: _trim(kind),
wordCount: _trim(wordCount),
lastChapter: ''
});
}
}
legado.log('[explore] found=' + result.length);
legado.dom.free(doc);
return result;
}
function init() {
legado.log('[init] 红袖添香 book source loaded');
}