Greasy Fork

Greasy Fork is available in English.

刺猬猫小说下载

刺猬猫小说下载,全本下载,单章下载,暂不支持付费章节

目前为 2019-06-24 提交的版本,查看 最新版本

// ==UserScript==
// @name         刺猬猫小说下载
// @namespace    http://tampermonkey.net/
// @version      1.10
// @description  刺猬猫小说下载,全本下载,单章下载,暂不支持付费章节
// @author       backrock12
// @match        *://www.ciweimao.com/chapter-list/*
// @match        *://www.ciweimao.com/chapter/*
// @require      https://cdn.bootcss.com/html2canvas/0.5.0-beta4/html2canvas.min.js
// @require      https://cdn.jsdelivr.net/npm/[email protected]/FileSaver.min.js
// @grant        GM_xmlhttpRequest

// ==/UserScript==

(function () {
    'use strict';

    var DivInited = false, IsOk = false, IsCancel = false;
    var WCContent, WCWords, WCQuit, WCSave;
    var title, info = ''
    var downlist = [];
    var downNum = -1;
    var iframeId;

    function initDiv() {
        console.log("initDiv");
        if (DivInited) return;
        DivInited = true;
        var content = document.createElement("div");
        document.body.appendChild(content);
        content.outerHTML = `
      <div id="CWDownContent" style='display:none' >
        <div style="width:360px;height:100px;position:fixed;left:50%;top:50%;margin-top:-50px;margin-left:-180px;z-index:100000;background-color:#ffffff;border:1px solid #afb3b6;opacity:0.95;filter:alpha(opacity=95);box-shadow:5px 5px 20px 0px#000;">
          <div id="CWDownWords" style="font-size:12px;position:absolute;width:290px;height:90px;padding: 8px;border-radius: 10px;float: left;">
          </div>
          <div style="float: right;">
            <div id="CWDownSave" style="width:43px;height:26px;cursor: pointer;background-color:#3169da;margin: 5px 5px 3px 3px;">
              <span style="line-height:25px;display:block;color:#FFF;text-align:center;font-size:14px;">保存</span>
            </div>
            <div id="CWDownQuit" style="width:43px;height:26px;cursor: pointer;background-color:#3169da;margin: 3px;">
              <span style="line-height:25px;display:block;color:#FFF;text-align:center;font-size:14px;">取消</span>
            </div>
          </div>
        </div>
      </div>
      `;

        WCContent = document.querySelector("#CWDownContent");
        WCWords = document.querySelector("#CWDownWords");
        WCQuit = document.querySelector("#CWDownQuit");
        WCSave = document.querySelector("#CWDownSave");

        WCQuit.onclick = function () {
            IsCancel = true;
            DivInited = false;
            WCContent.style.display = "none";
            WCWords.innerHTML = '';
            WCContent.parentNode.removeChild(WCContent);
        };

        WCSave.onclick = function () {
            //if (IsOk)
            SaveText();
        };
    }

    function ShowWords(value) {
        WCWords.innerHTML = (title ? title + '<br>' : '') + value;
    }

    function IframeInit() {

        if (iframeId) {
            var ele = document.getElementById(iframeId);
            ele.src = 'about:blank';
            ele.onload=null;
            try {
                ele.contentWindow.document.write('');
                ele.contentWindow.document.clear();
                ele.contentWindow.close();
            } catch (e) {
                console.log('IframeInit' + e.message);
            }
             ele.parentNode.removeChild(ele);
            ele = null;
        }

        iframeId='iframe' + downNum;
       var ele1 = document.createElement('iframe');
        ele1.src = findurl();
        ele1.name = iframeId;
        ele1.id = iframeId;
        ele1.width = "195px";
        ele1.height = "126px";
        ele1.style.display = 'none';
        ele1.onload = iframeload;
        document.body.appendChild(ele1);
        console.log('iframe' + downNum);
        console.log(ele1.src);

    }

    function findurl() {
        if (downNum >= downlist.length) return '';
        downNum++;
        if (downlist.length > 0 && downlist[downNum].url) {
            var url = downlist[downNum].url +'#Autodown';
            return url;
        }
        return findurl();
    }

    function iframeload() {
        if (IsCancel || downlist.length == 0) return;
        var frame = window.frames[0];
        if (frame) {
            var ftext = frame.document;
            downtext(ftext, downlist[downNum]);
            iframeloop();
        }
    }

    function iframeloop() {
        if (downNum == downlist.length - 1) {
            SaveText();
        } else {
            if (downlist[downNum].lock) {
                downlist[downNum].text = '\r\n' + downlist[downNum].title + '\r\n' + '付费章节暂时无法下载';
                downNum++;
                iframeloop();
            } else {
                IframeInit();
            }
        }
    }



    function Analysis() {
        console.log("Analysis");
        IsOk = false;
        IsCancel = false;
        downNum = -1;
        title = '';
        info = '';

        initDiv();
        if (WCContent) {
            WCContent.style.display = "block";
            ShowWords(`分析网页中`);
        }

        title = document.querySelector(".hd h3").innerText;

        for (const i of document.querySelectorAll(".hd p")) {
            info += "\r\n" + i.innerText;
        }
        console.log(title);
        console.log(info);

        for (const c of document.querySelectorAll(".book-chapter .book-chapter-box")) {
            var ctitle = c.querySelector('.sub-tit').innerText;
            downlist.push({ title: ctitle, mk: false, url: '', text: ctitle, complete: true });
            for (const a of c.querySelectorAll('.book-chapter-list li a')) {
                if (a.querySelector('.icon-lock,.icon-unlock'))
                    var lock = true
                else
                    lock = false;
                downlist.push({ title: a.innerText, mk: true, url: a.href, text: '', complete: false, lock: lock });
            };
        };

        console.log(downlist);

        if (downlist.length == 0) {
            ShowWords(`分析网页失败`);
            return;
        }
        IframeInit();

    }


    function SaveText() {
        IsOk = true;
        var texts = [];
        WCContent.style.display = "block";

        var ok = 0, error = 0;
        downlist.forEach(function (c) {
            if (c.complete)
                ok++
            else
                error++;
            texts.push(c.text);
        });
        ShowWords(`已下载完成<br>共 ${downlist.length} 章节<br>成功 ${ok} 章节,失败 ${error} 章节 `);

        var blob = new Blob([title, info, texts.join("\r\n")], { type: "text/plain;charset=utf-8" });
        saveAs(blob, `${title}.txt`);
    }

    function getElementRootText(element) {
        let ret = "";
        for (const i of element.childNodes) {
            if (i.nodeType === i.TEXT_NODE) {
                ret += i.nodeValue;
            }
        }
        return ret.replace(/^\s+|\s+$/g, "");
    }

    function image2line(img) {

        var dataURL = GM_xmlhttpRequest({
            method: 'GET',
            url: img.src,
            responseType: "blob",
            onload: function (result) {
                var reader = new window.FileReader();
                reader.readAsDataURL(result.response);
                reader.onloadend = function () {
                    return reader.result;
                }
            }
        });

        return `![${img.alt}](${dataURL} "${img.title}")`;

        return;
        img.crossOrigin = 'Anonymous'
        html2canvas(img, {
            allowTaint: true,
            logging: false,
            useCORS: true,
        }
        ).then(function (canvas) {
            var dataUrl = canvas.toDataURL();
            console.log(dataUrl);
            console.log(canvas);

            var im = document.createElement("img");
            im.src = dataUrl;

            document.body.append(canvas);

        });


        return;
        img.crossOrigin = "Anonymous";
        var canvas = document.createElement("canvas");
        canvas.width = img.naturalWidth;
        canvas.height = img.naturalHeight;
        var ctx = canvas.getContext("2d");
        ctx.drawImage(img, 0, 0, img.width, img.height);
        var ext = img.src.substring(img.src.lastIndexOf(".") + 1).toLowerCase();
        console.log('img4');
        var dataURL = canvas.toDataURL("image/" + ext);
        console.log('img5');
        console.log(dataURL);

        return `![${img.alt}](${dataURL} "${img.title}")`;
    }

    async function image2lineasync(img) {
        return new Promise((resolve, reject) => {
            resolve(image2line(img));
        });
    }


    async function imageUrl2line(url) {
        return new Promise((resolve, reject) => {
            const img = new Image();
            img.onload = () => {
                resolve(image2line(img));
            };
            img.src = url;
            console.log(url);
        });
    }

    async function downtext(str, obj) {
        console.log('downtext');
        try {
            if (obj)
                ShowWords(`共 ${downlist.length} 章节<br>已下载完成 ${downNum - 1} 章节,剩余 ${downlist.length - downNum} 章节<br>正在下载 ${downNum}`);
            /*       var doc = null;
                  doc = document.implementation.createHTMLDocument('');
                  doc.documentElement.innerHTML = str; */

            var doc = str;

            let time, num;
            let lines = [];

            //console.log(doc);

            let title = doc.querySelector("#J_BookCnt h3.chapter").firstChild.textContent;

            for (const i of doc.querySelectorAll("#J_BookCnt p span")) {
                if (i.textContent.indexOf("更新时间")) {
                    time = i.textContent;
                } else if (i.textContent.indexOf("字数")) {
                    num = i.textContent;
                }
            }

            lines.push('\r\n\r\n');
            lines.push(`# ${title}`);
            lines.push(`  ${time}`);
            lines.push(`  ${num}\r\n`);

            console.log(title);

            if ((obj && obj.lock) || doc.querySelectorAll("#J_BookImage").length > 0) {
                lines.push(`付费章节暂时无法下载`);
            } else {
                // 收费章节
/*                 for (const i of doc.querySelectorAll("#J_BookImage")) {
                    const url = i.style["background-image"].match(/(?:url\(")?(.+)(?:"\))?/)[1];
                    const line = await imageUrl2line(url);
                    lines.push(line);
                } */

                // 免费章节
                for (const i of doc.querySelectorAll("#J_BookRead p:not(.author_say)")) {
                    let line = getElementRootText(i);
                    lines.push(line);
/*                     for (const img of i.querySelectorAll("img")) {
                        const line = await image2lineasync(img);
                        lines.push(line);
                    } */
                }

                // 作者说
                for (const i of doc.querySelectorAll("p.author_say")) {
                    let line = getElementRootText(i);
                    lines.push(`    ${line}`);
/*                     for (const img of i.querySelectorAll("img")) {
                        const line = await image2lineasync(img);
                        lines.push(line);
                    } */
                }
            }

            var blob = new Blob([lines.join("\r\n")], { type: "text/plain;charset=utf-8" });

            if (obj) {
                obj.text = lines.join("\r\n");
                obj.complete = true;
            } else {
                IsOk = true;
                IsCancel = false;
                saveAs(blob, document.title + ".txt");
            }
            return true;
        }
        catch (e) {
            if (obj) {
                obj.text = obj.title + " 下载错误!";
                obj.complete = true;
                ShowWords(obj.text);
            }
            console.log(e.message);
            return false;
        }
    }

    function Inited() {
        if (location.hash && location.hash=='Autodown'){
        
        }else
        {
            console.log('Inited');
        var t = document.querySelector(".hd");
        if (t) {
            var e = document.createElement('button');
            e.id = 'DownBtn';
            e.textContent = '下载';
            e.className = 'btn btn-md btn-default'
            e.onclick = Analysis;
            t.append(e)
            console.log('frame');
        }

        var ct = document.querySelector(".read-hd");
        if (ct) {
            var ce = document.createElement('button');
            ce.id = 'CDownBtn';
            ce.textContent = '单章下载';
            ce.className = 'btn btn-md btn-default'
            ce.onclick = function () { downtext(document); };
            ct.append(ce)
            console.log('frame');
        }
        }
    }
    Inited();
    //Analysis();

})();