Greasy Fork

Greasy Fork is available in English.

刺猬猫小说下载

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

当前为 2019-06-20 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         刺猬猫小说下载
// @namespace    http://tampermonkey.net/
// @version      1.01
// @description  刺猬猫小说下载,全本下载,单章下载,暂不支持付费章节
// @author       backrock12
// @match        *://www.ciweimao.com/chapter-list/*
// @match        *://www.ciweimao.com/chapter/*
// @grant        GM_xmlhttpRequest

// ==/UserScript==

(function () {
  'use strict';

  /*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */
  var saveAs = saveAs || function (e) {
    "use strict"; if (typeof e === "undefined" || typeof navigator !== "undefined" && /MSIE [1-9]\./.test(navigator.userAgent)) { return }
    var t = e.document, n = function () { return e.URL || e.webkitURL || e }, r = t.createElementNS("http://www.w3.org/1999/xhtml", "a"), o = "download" in r, a = function (e) { var t = new MouseEvent("click"); e.dispatchEvent(t) }, i = /constructor/i.test(e.HTMLElement) || e.safari, f = /CriOS\/[\d]+/.test(navigator.userAgent), u = function (t) { (e.setImmediate || e.setTimeout)(function () { throw t }, 0) }, s = "application/octet-stream", d = 1e3 * 40, c = function (e) { var t = function () { if (typeof e === "string") { n().revokeObjectURL(e) } else { e.remove() } }; setTimeout(t, d) }, l = function (e, t, n) { t = [].concat(t); var r = t.length; while (r--) { var o = e["on" + t[r]]; if (typeof o === "function") { try { o.call(e, n || e) } catch (a) { u(a) } } } }, p = function (e) { if (/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(e.type)) { return new Blob([String.fromCharCode(65279), e], { type: e.type }) } return e }, v = function (t, u, d) { if (!d) { t = p(t) } var v = this, w = t.type, m = w === s, y, h = function () { l(v, "writestart progress write writeend".split(" ")) }, S = function () { if ((f || m && i) && e.FileReader) { var r = new FileReader; r.onloadend = function () { var t = f ? r.result : r.result.replace(/^data:[^;]*;/, "data:attachment/file;"); var n = e.open(t, "_blank"); if (!n) e.location.href = t; t = undefined; v.readyState = v.DONE; h() }; r.readAsDataURL(t); v.readyState = v.INIT; return } if (!y) { y = n().createObjectURL(t) } if (m) { e.location.href = y } else { var o = e.open(y, "_blank"); if (!o) { e.location.href = y } } v.readyState = v.DONE; h(); c(y) }; v.readyState = v.INIT; if (o) { y = n().createObjectURL(t); setTimeout(function () { r.href = y; r.download = u; a(r); h(); c(y); v.readyState = v.DONE }); return } S() }, w = v.prototype, m = function (e, t, n) { return new v(e, t || e.name || "download", n) }; if (typeof navigator !== "undefined" && navigator.msSaveOrOpenBlob) { return function (e, t, n) { t = t || e.name || "download"; if (!n) { e = p(e) } return navigator.msSaveOrOpenBlob(e, t) } } w.abort = function () { }; w.readyState = w.INIT = 0; w.WRITING = 1; w.DONE = 2; w.error = w.onwritestart = w.onprogress = w.onwrite = w.onabort = w.onerror = w.onwriteend = null; return m
  }(typeof self !== "undefined" && self || typeof window !== "undefined" && window || this.content); if (typeof module !== "undefined" && module.exports) { module.exports.saveAs = saveAs } else if (typeof define !== "undefined" && define !== null && define.amd !== null) { define("FileSaver.js", function () { return saveAs }) }




  var DivInited = false;
  var WCContent, WCWords, WCQuit, WCSave, ele;

  function initDiv() {
    console.log("initDiv");
    if (DivInited) return;
    DivInited = true;
    var content = document.createElement("div");
    document.body.appendChild(content);
    content.outerHTML = `
    <div id="CWDownContent" >
      <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:100px;border: 1px solid #f3f1f1;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 () {
      WCContent.style.display = "none";
      //WCContent.parentNode.removeChild(txtDownContent);
    };

    WCSave.onclick = function () {
      SaveText();
    };

    ele = document.createElement('iframe');
    ele.name = 'frameid';
    ele.id = 'frameid';
    ele.width = "195px";
    ele.height = "126px";
    ele.style.display = 'none';
    ele.onload = iframeload;
    document.body.appendChild(ele);
    console.log('frame');

  }

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

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

  function iframeload() {
    if (downlist.length == 0) return;
    var frame = window.frames[0];
    if (frame) {
      console.log('frame' + downNum);
      //console.log(frame.document.documentElement);
      var ftext = frame.document.documentElement.innerHTML;
      downtext(ftext, downlist[downNum]);
      iframeloop();
    }
  }

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

  var title, info = ''
  var downlist = [];
  var downNum = -1;

  function Analysis() {
    console.log("Analysis");

    downNum = -1;
    initDiv();

    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;
    }
    ele.src = findurl();

  }


  function SaveText() {
    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) {
      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}")`;
    }

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

  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;

      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")) {
                  lines.push(image2line(img));
                } */
        }

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

      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 {
        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() {
    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.documentElement.innerHTML); };
      ct.append(ce)
      console.log('frame');
    }
  }
  Inited();
  //Analysis();

})();