趣笔阁下载器

可在趣笔阁下载小说,在小说目录页面使用,仅供交流,可能存在bug。

目前为 2024-07-10 提交的版本。查看 最新版本

// ==UserScript==
// @name         趣笔阁下载器
// @namespace    http://tampermonkey.net/
// @version      0.1.3
// @description  可在趣笔阁下载小说,在小说目录页面使用,仅供交流,可能存在bug。
// @author       Yearly
// @match        https://www.beqege.cc/*/
// @license      MIT
// @grant        GM_registerMenuCommand
// @grant        GM_addStyle
// @namespace    https://gf.qytechs.cn/scripts/500170
// @supportURL   https://gf.qytechs.cn/scripts/500170
// @homepageURL  https://gf.qytechs.cn/scripts/500170
// @icon         https://www.beqege.cc/favicon.ico
// ==/UserScript==

(function() {

    // 添加自定义样式
    GM_addStyle(`
        #fetchContentModal {
            border-radius: 10px;
            position: fixed;
            top: 40%;
            left: 50%;
            transform: translate(-50%, -50%);
            background: white;
            padding: 5px 20px 10px 20px;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
            z-index: 10000;
            width: 300px;
            text-align: center;
        }
        #fetchContentModal input[type="number"] {
            width: 30%;
            margin: 5px 0;
            text-align: center;
        }
        #fetchContentModal button {
            width: 100%;
            margin: 10px 0;
        }
        #fetchContentProgress {
            width: 100%;
            background: #f3f3f3;
            border: 1px solid #ccc;
            margin: 10px 0;
        }
        #fetchContentProgress div {
            width: 0;
            height: 20px;
            background: #4caf50;
            text-align: center;
            margin-left: 0;
            color: #960;
            white-space: nowrap;
        }
    `);

    // 创建悬浮窗
    const modalHtml = `
        <div id="fetchContentModal" style="display:none;">
            <h3>小说下载工具<span id="fetcModalClose" style="cursor: pointer; float: right; margin:-8px -4px;">✕</span></h3>
            <label for="ranges">下载章节范围:</label>
            <input type="number" id="_startRange" min="1" value="1">~
            <input type="number" id="_endRange" min="1" value="2">
            <label id="_warn_info"></label>
            <button id="fetchContentButton">开始下载</button>
            <div id="fetchContentProgress">
                <div></div>
            </div>
            <a id="_downlink"></a>
        </div>
    `;
    document.body.insertAdjacentHTML('beforeend', modalHtml);

    // 获取元素
    const modal = document.getElementById('fetchContentModal');
    const startRangeInput = document.getElementById('_startRange');
    const endRangeInput = document.getElementById('_endRange');
    const fetchButton = document.getElementById('fetchContentButton');
    const progressBar = document.getElementById('fetchContentProgress').firstElementChild;
    const downlink = document.getElementById('_downlink');
    const warnInfo = document.getElementById('_warn_info');
    const fetcClose = document.getElementById('fetcModalClose');

    // 注册(不可用)菜单命令
    GM_registerMenuCommand('小说下载工具', () => {
        modal.style.display = 'block';
        endRangeInput.max = document.querySelectorAll("#list > dl > dd > a").length;
        warnInfo.innerText=`当前小说共 ${endRangeInput.max} 章,设置范围后开始下载。\n 若章节范围较大耗时会较长,请稍作等待。`
    });

    fetcClose.addEventListener('click', async () => {
         modal.style.display = 'none';
    });

    // 下载
    fetchButton.addEventListener('click', async () => {
        const startRange = parseInt(startRangeInput.value, 10) - 1;
        const endRange = parseInt(endRangeInput.value, 10);

        // Step 1: 获取当前网页中的 document.querySelectorAll("#list > dl > dd > a")
        const links = document.querySelectorAll("#list > dl > dd > a");

        // Step 2: 获取指定范围的链接
        const selectedLinks = Array.from(links).slice(startRange, endRange); // 数组是从0开始计数的,所以startRange-1对应第startRange个元素

        const title = document.title;

        // Step 3: 逐个去GET该链接内容并解析
        let results = document.querySelector("#maininfo #info").innerText || title || '';

        results+=`\n\n下载章节范围:${startRange} ~ ${endRange}\n`

        results+="\n-----------------------\n"

        for (let i = 0; i < selectedLinks.length; i++) {
            const link = selectedLinks[i];
            const url = link.href;

            results += "\n ## " + link.innerText + '\n';

            try {
                const response = await fetch(url);
                const text = await response.text();
                const parser = new DOMParser();
                const doc = parser.parseFromString(text, 'text/html');
                doc.querySelectorAll('div#content > :not(div#device)').forEach(function (item) {
                    const content = item.innerText || '';
                    results += content + '\n';
                });
            } catch (error) {
                results += `Error fetching ${url}:` + error + '\n';
            }

            // 更新进度条
            progressBar.style.width = `${((i + 1) / selectedLinks.length) * 100}%`;
            progressBar.textContent = `${i + 1} / ${selectedLinks.length}`;
        }

        // Step 4: 创建并下载包含所有内容的文件
        const blob = new Blob([results], { type: 'text/plain' });
        downlink.innerText="加载完成后,若未开始自动下载,点击这里"
        downlink.href = URL.createObjectURL(blob);
        downlink.download = `${title}_${startRange}_${endRange}.txt`;
        downlink.click();
    });
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址