刺猬猫章节自动下载

打开刺猬猫章节页面时自动保存文章到本地, 支持付费章节。

当前为 2021-11-20 提交的版本,查看 最新版本

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @namespace https://github.com/NateScarlet/Scripts/tree/master/user-script
// @name     刺猬猫章节自动下载
// @description 打开刺猬猫章节页面时自动保存文章到本地, 支持付费章节。
// @version  10
// @grant    none
// @include	 https://www.ciweimao.com/chapter/*
// @run-at   document-idle
// ==/UserScript==
const __name__ = "刺猬猫章节自动下载";
function image2line(img) {
    const canvas = document.createElement("canvas");
    canvas.width = img.naturalWidth;
    canvas.height = img.naturalHeight;
    const ctx = canvas.getContext("2d");
    ctx.drawImage(img, 0, 0);
    return `![${img.alt}](${canvas.toDataURL()} "${img.title}")`;
}
function strip(str) {
    return str.replace(/^\s+|\s+$/g, "");
}
function getElementRootText(element) {
    let ret = "";
    for (const i of element.childNodes) {
        if (i.nodeType === i.TEXT_NODE) {
            ret += i.nodeValue;
        }
    }
    return strip(ret);
}
async function imageUrl2line(url) {
    return new Promise((resolve) => {
        const img = new Image();
        img.onload = () => {
            resolve(image2line(img));
        };
        img.src = url;
    });
}
(async function () {
    const chapter = document.querySelector("#J_BookCnt .chapter").firstChild
        .textContent;
    let lines = [];
    // 收费章节
    for (const i of document.querySelectorAll("#J_BookImage")) {
        const url = i.style["background-image"].match(/(?:url\(")?(.+)(?:"\))?/)[1];
        const line = await imageUrl2line(url);
        lines.push(line);
    }
    // 免费章节
    for (const i of document.querySelectorAll("#J_BookRead p:not(.author_say)")) {
        const line = getElementRootText(i);
        lines.push(line);
        for (const img of i.querySelectorAll("img")) {
            lines.push(image2line(img));
        }
    }
    // 作者说
    for (const i of document.querySelectorAll("p.author_say")) {
        const line = getElementRootText(i);
        lines.push(`    ${line}`);
        for (const img of i.querySelectorAll("img")) {
            lines.push(image2line(img));
        }
    }
    // 下载文件
    lines = lines.filter(i => i.length > 0);
    console.log(`${__name__}: 获取到 ${lines.length} 行`);
    const file = new Blob([`# ${chapter}\n\n`, lines.join("\n\n")], {
        type: "text/markdown",
    });
    const anchor = document.createElement("a");
    anchor.href = URL.createObjectURL(file);
    anchor.download = `${location.pathname.split("/").slice(-1)[0]} ${document.title}.md`;
    anchor.style["display"] = "none";
    document.body.append(anchor);
    anchor.click();
    setTimeout(() => {
        document.body.removeChild(anchor);
        URL.revokeObjectURL(anchor.href);
    }, 0);
})();