得奇小说网

https://www.deqixs.co

zpccool (13551) 1天前 下载:370

小说 小说 免费 连载
得奇小说网,免费在线阅读小说
二维码导入(APP尚未完成该功能)
// @name        得奇小说网
// @version     1.0.2
// @uuid        deqixiaoshuowang
// @author      Ai
// @url         https://www.deqixs.co
// @type        novel
// @enabled     true
// @tags        小说,免费,连载
// @description 得奇小说网,免费在线阅读小说

var BASE = 'https://www.deqixs.co';

function _trim(s) {
    if (!s) return '';
    return s.replace(/^[\s\u3000\u00A0]+|[\s\u3000\u00A0]+$/g, '');
}

async function search(keyword, page) {
    legado.log('searching: ' + keyword);
    var headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
        'Content-Type': 'application/x-www-form-urlencoded',
        'Referer': BASE + '/',
        'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
    };
    var body = 'searchkey=' + encodeURIComponent(keyword) + '&action=search&searchtype=articlename';
    var html = await legado.http.post(BASE + '/modules/article/search.php', body, headers);
    if (!html) {
        legado.log('search returned empty response');
        return [];
    }

    legado.log('search response length: ' + html.length);

    var doc = legado.dom.parse(html);

    var ogTitle = legado.dom.selectAttr(doc, 'meta[property="og:novel:book_name"]', 'content');
    var ogUrl = legado.dom.selectAttr(doc, 'meta[property="og:novel:read_url"]', 'content');
    var ogAuthor = legado.dom.selectAttr(doc, 'meta[property="og:novel:author"]', 'content');
    var ogCover = legado.dom.selectAttr(doc, 'meta[property="og:image"]', 'content');
    var ogLatest = legado.dom.selectAttr(doc, 'meta[property="og:novel:latest_chapter_name"]', 'content');

    if (ogTitle && ogUrl) {
        legado.log('single result: ' + ogTitle);
        return [{
            name: _trim(ogTitle),
            author: _trim(ogAuthor),
            bookUrl: ogUrl,
            coverUrl: ogCover || '',
            kind: '小说',
            lastChapter: _trim(ogLatest)
        }];
    }

    var items = legado.dom.selectAll(doc, 'div.bookbox');
    if (!items || items.length === 0) {
        legado.log('no results found');
        return [];
    }

    legado.log('found ' + items.length + ' results');
    var results = [];
    for (var i = 0; i < items.length; i++) {
        var item = items[i];
        var titleEl = legado.dom.select(item, 'h4.bookname a');
        var title = legado.dom.text(titleEl);
        var url = legado.dom.attr(titleEl, 'href');
        if (!title || !url) continue;
        if (url.indexOf('http') !== 0) {
            url = BASE + url;
        }

        var authorText = legado.dom.text(legado.dom.select(item, 'div.author'));
        var author = authorText.replace('作者:', '');

        var lastChapterEl = legado.dom.select(item, 'div.cat a');
        var lastChapter = legado.dom.text(lastChapterEl);

        var articleIdMatch = url.match(/\/books\/(\d+)\//);
        var articleId = articleIdMatch ? articleIdMatch[1] : '';
        var coverUrl = articleId ? (BASE + '/files/article/image/0/' + articleId + '/' + articleId + 's.jpg') : '';

        results.push({
            name: _trim(title),
            author: _trim(author),
            bookUrl: url,
            coverUrl: coverUrl,
            kind: '小说',
            lastChapter: _trim(lastChapter)
        });
    }
    return results;
}

async function bookInfo(bookUrl) {
    legado.log('bookInfo: ' + bookUrl);
    var html = await legado.http.get(bookUrl);
    if (!html) {
        legado.log('bookInfo returned empty');
        return null;
    }

    var doc = legado.dom.parse(html);

    var title = legado.dom.selectText(doc, 'h1.booktitle');
    var authorEl = legado.dom.select(doc, 'a.red[title^="作者"]');
    var author = legado.dom.attr(authorEl, 'title');
    if (author) {
        author = author.replace('作者:', '');
    }
    var coverUrl = legado.dom.attr(legado.dom.select(doc, 'img.thumbnail'), 'src');

    var introDoc = legado.dom.select(doc, 'p.bookintro');
    legado.dom.remove(introDoc, 'img');
    var intro = legado.dom.text(introDoc);

    var kind = legado.dom.selectText(doc, 'ol.breadcrumb li:nth-child(2) a');

    var statusEls = legado.dom.selectAll(doc, 'span.red');
    var status = '';
    if (statusEls && statusEls.length > 0) {
        status = legado.dom.text(statusEls[0]);
    }

    var latestEl = legado.dom.select(doc, 'a.bookchapter');
    var lastChapter = legado.dom.text(latestEl);

    return {
        name: _trim(title),
        author: _trim(author),
        coverUrl: coverUrl || '',
        intro: _trim(intro),
        kind: _trim(kind) || _trim(status) || '小说',
        lastChapter: _trim(lastChapter),
        tocUrl: bookUrl
    };
}

async function chapterList(tocUrl) {
    legado.log('chapterList: ' + tocUrl);
    var html = await legado.http.get(tocUrl);
    if (!html) {
        legado.log('chapterList returned empty');
        return [];
    }

    var doc = legado.dom.parse(html);

    var chapters = [];
    var seen = {};
    var links = legado.dom.selectAll(doc, 'dl.chapterlist a');

    for (var i = 0; i < links.length; i++) {
        var link = links[i];
        var url = legado.dom.attr(link, 'href');
        var name = legado.dom.text(link);

        if (!url || url.indexOf('javascript') === 0) {
            continue;
        }
        if (url.indexOf('http') !== 0) {
            url = BASE + url;
        }
        if (seen[url]) {
            continue;
        }
        var nameTrim = _trim(name);
        if (nameTrim === '开始阅读' || nameTrim === '加入书架' || nameTrim === '推荐本书' || nameTrim === 'TXT下载') {
            continue;
        }

        seen[url] = true;
        chapters.push({
            name: nameTrim,
            url: url
        });
    }

    chapters.sort(function(a, b) {
        var idA = parseInt(a.url.replace(/.*\/(\d+)\.html.*/, '$1'), 10);
        var idB = parseInt(b.url.replace(/.*\/(\d+)\.html.*/, '$1'), 10);
        return idA - idB;
    });

    legado.log('chapterList: ' + chapters.length + ' chapters');
    return chapters;
}

async function chapterContent(chapterUrl) {
    legado.log('chapterContent: ' + chapterUrl);

    var articleId = '';
    var chapterId = '';
    var parts = chapterUrl.split('/');
    for (var i = 0; i < parts.length; i++) {
        if (parts[i] === 'books' && i + 1 < parts.length) {
            articleId = parts[i + 1];
        }
    }
    var cidMatch = chapterUrl.match(/\/(\d+)\.html/);
    if (cidMatch) {
        chapterId = cidMatch[1];
    }

    if (!articleId || !chapterId) {
        legado.log('Cannot extract IDs from URL: ' + chapterUrl);
        return '解析章节ID失败';
    }

    legado.log('articleId=' + articleId + ' chapterId=' + chapterId);

    var headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
        'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
        'Referer': BASE + '/',
    };

    var pageHtml = await legado.http.get(chapterUrl, headers);
    if (!pageHtml) {
        legado.log('chapter page returned empty');
        return '获取章节页面失败';
    }
    legado.log('chapter page loaded, length: ' + pageHtml.length);

    var tokenUrl = BASE + '/scripts/chapter.js.php?aid=' + articleId + '&cid=' + chapterId + '&referrer=' + encodeURIComponent(chapterUrl);
    var tokenHeaders = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
        'Referer': chapterUrl,
        'Accept': '*/*',
    };
    var tokenHtml = await legado.http.get(tokenUrl, tokenHeaders);

    if (!tokenHtml) {
        legado.log('Token request returned empty');
        return '获取Token失败';
    }

    legado.log('token response: ' + tokenHtml.substring(0, 150));

    var tokenMatch = tokenHtml.match(/var chapterToken = '([^']+)'/);
    var tsMatch = tokenHtml.match(/var timestamp = (\d+)/);
    var nonceMatch = tokenHtml.match(/var nonce = '([^']+)'/);

    if (!tokenMatch || !tsMatch || !nonceMatch) {
        legado.log('Token parse failed');
        return '获取章节Token失败';
    }

    var token = tokenMatch[1];
    var timestamp = tsMatch[1];
    var nonce = nonceMatch[1];

    legado.log('token=' + token + ' ts=' + timestamp + ' nonce=' + nonce);

    var apiUrl = BASE + '/modules/article/ajax2.php?aid=' + articleId + '&cid=' + chapterId + '&token=' + token + '&timestamp=' + timestamp + '&nonce=' + nonce;
    var apiHeaders = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
        'Referer': chapterUrl,
        'X-Requested-With': 'XMLHttpRequest',
        'Accept': 'application/json, text/javascript, */*; q=0.01',
    };
    var apiResponse = await legado.http.get(apiUrl, apiHeaders);

    legado.log('API response: ' + apiResponse.substring(0, 200));

    try {
        var data = JSON.parse(apiResponse);
        if (data && data.status === 1 && data.data && data.data.content) {
            var content = data.data.content;
            content = content.replace(/<br\s*\/?>/gi, '\n');
            content = content.replace(/<[^>]+>/g, '');
            content = content.replace(/&emsp;/g, '    ');
            content = content.replace(/&nbsp;/g, ' ');
            content = content.replace(/&amp;/g, '&');
            content = content.replace(/&lt;/g, '<');
            content = content.replace(/&gt;/g, '>');
            content = content.replace(/&quot;/g, '"');
            content = content.replace(/&#39;/g, "'");
            content = content.replace(/\n{3,}/g, '\n\n');
            content = content.replace(/[\u200B\u200C\u200D\uFEFF]/g, '');
            content = _trim(content);
            legado.log('content length: ' + content.length);
            return content;
        } else {
            var msg = '获取章节内容失败';
            if (data && data.message) {
                msg = msg + ': ' + data.message;
            }
            legado.log(msg);
            return msg;
        }
    } catch (e) {
        legado.log('JSON parse error: ' + e);
        return '解析章节内容失败';
    }
}

async function explore(page, category) {
    legado.log('explore: page=' + page + ' category=' + category);

    if (category === 'GETALL' || !category) {
        return ['全部', '玄幻', '都市', '仙侠', '历史', '科幻', '诸天', '悬疑', '体育', '游戏', '综合'];
    }

    var categoryMap = {
        '全部': '0',
        '玄幻': '1',
        '都市': '2',
        '仙侠': '3',
        '历史': '4',
        '科幻': '5',
        '诸天': '6',
        '悬疑': '7',
        '体育': '8',
        '游戏': '9',
        '综合': '10'
    };

    var sortId = categoryMap[category];
    if (!sortId) {
        legado.log('unknown category: ' + category);
        return [];
    }

    var url = BASE + '/sort/' + sortId + '/' + page + '.html';
    legado.log('explore url: ' + url);

    var html = await legado.http.get(url);
    if (!html) {
        legado.log('explore returned empty');
        return [];
    }

    var doc = legado.dom.parse(html);
    var items = legado.dom.selectAll(doc, 'div.bookbox');
    if (!items || items.length === 0) {
        legado.log('no books found');
        return [];
    }

    var results = [];
    for (var i = 0; i < items.length; i++) {
        var item = items[i];
        var titleEl = legado.dom.select(item, 'h4.bookname a');
        var title = legado.dom.text(titleEl);
        var bUrl = legado.dom.attr(titleEl, 'href');
        if (!title || !bUrl) continue;
        if (bUrl.indexOf('http') !== 0) {
            bUrl = BASE + bUrl;
        }

        var authorEls = legado.dom.selectAll(item, 'div.author');
        var author = '';
        for (var j = 0; j < authorEls.length; j++) {
            var at = legado.dom.text(authorEls[j]);
            if (at.indexOf('作者:') === 0) {
                author = at.replace('作者:', '');
                break;
            }
        }

        var lastChapterEl = legado.dom.select(item, 'div.cat a');
        var lastChapter = legado.dom.text(lastChapterEl);

        var articleIdMatch = bUrl.match(/\/books\/(\d+)\//);
        var articleId = articleIdMatch ? articleIdMatch[1] : '';
        var coverUrl = articleId ? (BASE + '/files/article/image/0/' + articleId + '/' + articleId + 's.jpg') : '';

        results.push({
            name: _trim(title),
            author: _trim(author),
            bookUrl: bUrl,
            coverUrl: coverUrl,
            kind: category,
            lastChapter: _trim(lastChapter)
        });
    }

    legado.log('explore results: ' + results.length);
    return results;
}

async function TEST(type) {
    if (type === '__list__') return ['search', 'explore', 'bookInfo', 'chapterList', 'chapterContent'];
    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 + ' 条' };
    }
    if (type === 'bookInfo') {
        var r = await bookInfo('https://www.deqixs.co/books/3305/');
        return { passed: !!r.name, message: 'bookInfo name=' + r.name };
    }
    if (type === 'chapterList') {
        var r = await chapterList('https://www.deqixs.co/books/3305/');
        return { passed: r.length > 0, message: 'chapterList cnt=' + r.length + ' first=' + (r[0] ? r[0].name : 'N/A') };
    }
    if (type === 'chapterContent') {
        var r = await chapterContent('https://www.deqixs.co/books/3305/2905167.html');
        return { passed: r.length > 100, message: 'chapterContent len=' + r.length + ' first=' + r.substring(0, 40) };
    }
    return { passed: false, message: '未知: ' + type };
}
广告