您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Adds a button that get all attached images as original size to every post.
- // ==UserScript==
- // @name Extract images for pixiv
- // @name:zh P站原图收割机
- // @namespace https://github.com/cmheia/extract-images-for-pixiv
- // @description Adds a button that get all attached images as original size to every post.
- // @include http://www.pixiv.net/member_illust.php*
- // @include https://www.pixiv.net/member_illust.php*
- // @author cmheia
- // @version 1.3.2
- // @icon http://www.pixiv.net/favicon.ico
- // @grant GM_setClipboard
- // @grant GM_xmlhttpRequest
- // @license MPL
- // ==/UserScript==
- (function () {
- 'use strict';
- /**********************************************************************
- * 长得像库
- **********************************************************************/
- var $id = function (o) {
- // return document.getElementById(o);
- return document.querySelector(`#${o}`);
- };
- var $class = function (o) {
- // return document.getElementsByClassName(o);
- return document.querySelector(`.${o}`);
- };
- // 去重
- var unique = function (arr) {
- var result = [],
- hash = {};
- for (let i = 0, elem; (elem = arr[i]) !== undefined; i++) {
- if (!hash[elem]) {
- result.push(elem);
- hash[elem] = true;
- }
- }
- return result;
- };
- // 插入样式表
- var apendStyle = function (cssText) {
- var head = document.head || document.getElementsByTagName('head')[0];
- var style = document.createElement('style');
- style.type = 'text/css';
- var textNode = document.createTextNode(cssText);
- style.appendChild(textNode);
- head.appendChild(style);
- };
- // 增加 class
- var addClassName = function (elem, clas) {
- var current = elem.className;
- if (current) {
- current += " ";
- current += clas;
- current = current.split(' ').filter(function (v, i) {
- if (v) {
- return v;
- }
- });
- current = unique(current);
- elem.className = current.join(" ");
- } else {
- elem.className = clas;
- }
- };
- // 移除 class
- var removeClassName = function (elem, clas) {
- var current = elem.className;
- if (current) {
- current = current.split(' ').filter(function (v, i) {
- if (clas != v) {
- return v;
- }
- });
- current = unique(current);
- elem.className = current.join(" ");
- }
- };
- // 增加/移除 class
- var toggleClassName = function (elem, clas) {
- var current = elem.className;
- if (current) {
- if (-1 === current.split(' ').indexOf(clas)) {
- addClassName(elem, clas);
- } else {
- removeClassName(elem, clas);
- }
- } else {
- elem.className = clas;
- }
- };
- // 伤脑筋!
- function illustCollector() {
- function tergetContainer() {
- // illust_id
- this.id = "-1";
- // 取得的原图链接
- this.result = [];
- // 最终的原图链接,1 -> yes,0 -> no,-1 -> failed
- this.final = [];
- }
- this.illust = [];
- // 删除重复目标
- this.shrinkTarget = function () {
- var elem,
- hash = {},
- duplicate = [];
- // 第一步:找出需要删除的重复 id
- for (let i = 0; (elem = this.illust[i]) !== undefined; i++) {
- if (hash[elem.id]) {
- duplicate.push(i); // 重复
- } else {
- hash[elem.id] = true;
- }
- }
- // 第二步:删除的重复 id
- for (let i = duplicate.length - 1; i >= 0; i--) {
- this.illust.splice(duplicate[i], 1);
- }
- // console.log("删除重复 id", duplicate.length, "个");
- return duplicate.length;
- };
- // 增加新目标
- this.addTarget = function (illust_id) {
- // console.group("addTarget", illust_id, this.illust.length);
- var i,
- index;
- for (i = 0; i < this.illust.length; i++) {
- if (illust_id === this.illust[i].id) {
- // console.log("目标重复了");
- index = -1;
- break;
- }
- }
- if (-1 !== index) {
- this.shrinkTarget();
- index = this.illust.length;
- // console.log("新增目标", index, this.illust.length);
- this.illust.push(new tergetContainer());
- // illust_id
- this.illust[index].id = illust_id;
- }
- // console.log(index, this.illust);
- // console.groupEnd();
- return index;
- };
- // 删除目标
- // type: true -> target is id; false -> target is index (default)
- this.removeTarget = function (target, type) {
- // console.group("removeTarget", target, type);
- var index = -1;
- if (type) {
- for (let i = 0; i < this.illust.length; i++) {
- if (target === this.illust[i].id) {
- index = i;
- break;
- }
- }
- } else {
- index = target;
- }
- if (index > -1) {
- this.illust.splice(index, 1);
- }
- // console.groupEnd();
- };
- // 记录指定 illust_id 包含的图片数量(取得目标 html 后调用)
- // count: -1 -> 记录为失败
- // type: true -> target is index; false -> target is id (default)
- this.recordTargetLength = function (target, count, type) {
- // console.group("recordTargetLength", target, count, type);
- var index = -1;
- if (type && this.illust[target] && this.illust[target].id) {
- index = target;
- } else {
- for (let i = 0; i < this.illust.length; i++) {
- if (target === this.illust[i].id) {
- index = i;
- break;
- }
- }
- }
- if (index > -1) {
- if (0 > count) {
- // 记录为失败
- // 取得的原图链接
- // this.illust[index].result[0] = "";
- // 最终的原图链接,1 -> yes,0 -> no,-1 -> failed
- this.illust[index].final[0] = -1;
- // console.log(target, "被标记为获取失败,index =", index);
- } else {
- // 取得的原图链接
- this.illust[index].result = new Array(count);
- // 最终的原图链接,1 -> yes,0 -> no,-1 -> failed
- this.illust[index].final = new Array(count);
- // console.log("初始化 illust[", index, "] 为", count, "个原图存放区");
- }
- }
- // console.groupEnd();
- };
- // 记录指定 illust_id 的原图 URL (取得目标的原图后调用, 每次调用添加一个 URL, 多图多调)
- // type: true -> target is index; false -> target is id (default)
- this.setTarget = function (target, content, offset, status, type) {
- // console.group("setTarget", target, content, offset, status, type);
- var index = -1,
- result = false;
- if (type && this.illust[target] && this.illust[target].id) {
- index = target;
- } else {
- for (let i = 0; i < this.illust.length; i++) {
- if (target === this.illust[i].id) {
- index = i;
- break;
- }
- }
- }
- if (index > -1) {
- if (offset < this.illust[index].final.length) {
- // console.log("记录第", offset, "个原图", content, "到", index);
- // 取得的原图链接
- this.illust[index].result[offset] = content;
- // 最终的原图链接,1 -> yes,0 -> no,-1 -> failed
- this.illust[index].final[offset] = parseInt(status);
- result = true;
- } else {
- // console.log(offset, "已越界");
- }
- }
- // console.groupEnd();
- return result;
- };
- // 完工?
- // final[],1 -> yes,0 -> no,-1 -> failed
- // 遍历所有 final, 发现 0 即为未完成
- this.isAllDone = function () {
- // console.group("isAllDone", this.illust.length);
- var working = false;
- // console.group("loop illust[]");
- for (let i = 0; i < this.illust.length && !working; i++) {
- // console.log("illust[", i, "]: id =", this.illust[i].id, ", final.length =", this.illust[i].final.length);
- if (0 === this.illust[i].final.length) {
- working = true;
- // console.warn("final.length=0, 即还未记录结果, 属未完成");
- break;
- }
- for (let j = 0; j < this.illust[i].final.length && !working; j++) {
- // console.log("\tfinal[", j, "] =", this.illust[i].final[j]);
- if (0 === this.illust[i].final[j]) {
- working = true;
- // console.warn("illust[", i, "].final[", j, "] = 0, 还未完成");
- break;
- }
- }
- }
- // console.groupEnd();
- if (working) {
- // console.warn("在忙");
- } else {
- // console.warn("完工!!!");
- }
- // console.groupEnd();
- return !working;
- };
- // 导出结果
- this.exportAll = function () {
- // console.group("exportAll");
- var j,
- k,
- total = 0,
- failed = new Array(this.illust.length),
- src = [],
- result = {};
- for (let i = 0; i < this.illust.length; i++) {
- for (j = 0, k = 0; j < this.illust[i].final.length; j++) {
- if (1 === this.illust[i].final[j]) {
- src[total++] = this.illust[i].result[j];
- k++;
- }
- }
- failed[i] = j - k;
- // console.log("illust[", i, "]导出", k, "个,失败", failed, "个");
- }
- // console.log("共导出", total, "个");
- result.fail = failed;
- result.done = src;
- // console.groupEnd();
- return result;
- };
- // 导出 ID
- this.getID = function () {
- // console.group("getID");
- var result = [];
- for (let i = 0; i < this.illust.length; i++) {
- result[i] = this.illust[i].id;
- }
- // console.groupEnd();
- return result;
- };
- }
- /**********************************************************************
- * 基础设施
- **********************************************************************/
- // 页面显示信息
- var msg = function (msg) {
- $id("extracted").innerHTML = msg;
- };
- // 创建样式表
- var addStyle = function () {
- apendStyle(".cmheia_checkbox {position:absolute;left:0;} .cmheia_item {padding:1px;} .cmheia_item_unselect {background-color:pink;}");
- };
- // 作品目录?
- // 综合
- // http://www.pixiv.net/member_illust.php?id=xxxxxxxx
- // 插画
- // http://www.pixiv.net/member_illust.php?type=illust&id=xxxxxxxx
- // 漫画
- // http://www.pixiv.net/member_illust.php?type=manga&id=xxxxxxxx
- // 动图
- // http://www.pixiv.net/member_illust.php?type=ugoira&id=xxxxxxxx
- // 小说
- // http://www.pixiv.net/novel/member.php?id=xxxxxxxx
- var isWorksList = function () {
- // console.group('页面类型');
- var userId,
- workId;
- userId = window.location.search.match(/[^_]id=(\d+)/);
- workId = window.location.search.match(/illust_id=(\d+)/);
- if (userId) {
- // console.log("作品目录,USER ID:", userId[1]);
- }
- if (workId) {
- // console.log("作品页面,WORK ID:", workId[1]);
- }
- // console.groupEnd();
- return null !== userId && null === workId;
- };
- // 匹配单个图片链接
- var parseImageUrl = function (src) {
- var result = src.match(/((http|https):\/\/)+(\w+\.)+(\w+)[\w\/\.\-]*(jpg|jpeg|gif|png|webp)/gi);
- if (null === result || 1 !== result.length) {
- return null;
- }
- return result[0];
- };
- // 提取多图页面原图链接
- var parseMultiImageUrl = function (target, callback) {
- // console.group("parseMultiImageUrl", target);
- var num = target.length,
- parsed = 0,
- result = {};
- var referer = target[0].replace(/big/, "medium");
- // console.warn('Referer :', referer);
- result.done = new Array(num);
- result.fail = new Array(num);
- for (let i = 0; i < num; i++) {
- // console.log(target[i]);
- // 下面闭包的 index 无实际必要,
- // xhr.finalUrl.replace(/.*(page=\d+)/, "$1") 可取得相同的值,
- // 然而
- // 听说闭包很深奥,那就多练练
- GM_xmlhttpRequest({
- method : 'GET',
- url : target[i],
- headers: {
- 'Referer': referer
- },
- onload : (function (xhr) {
- var index = i;
- return function (xhr) {
- var src;
- if (200 === xhr.status) {
- src = parseImageUrl(xhr.response);
- if (null !== src) {
- result.done[index] = src;
- }
- }
- // console.log("parseMultiImageUrl:onload", xhr.finalUrl.replace(/.*(page=\d+)/, "$1"), parsed, src, result);
- if (++parsed === num) {
- callback(result);
- }
- };
- })(),
- onerror: (function (xhr) {
- var index = i;
- return function (xhr) {
- // console.log("parseMultiImageUrl:onerror", xhr.finalUrl.replace(/.*(page=\d+)/, "$1"));
- result.fail[index] = xhr.finalUrl;
- if (++parsed === num) {
- callback(result);
- }
- };
- })()
- });
- }
- // console.groupEnd();
- return num;
- };
- /**********************************************************************
- * 作品目录页面功能
- **********************************************************************/
- // 解析详情页链接
- var extractIllustUrl = function () {
- // console.group("extractIllustUrl");
- var id = [],
- itemList = $class('_image-items').children;
- if (itemList) {
- for (let i = 0; i < itemList.length; i++) {
- let cmheia_checkbox = itemList[i].children[0].children[0].getElementsByTagName('input')[0];
- // console.log(cmheia_checkbox);
- if (cmheia_checkbox && cmheia_checkbox.checked) {
- let href = itemList[i].children[1].getAttribute('href');
- if (href && href.match(/.*illust_id=(\d+).*/)) {
- // id.push(href.replace(/.*illust_id=(\d+).*/, "$1") || "");
- id.push(href);
- }
- }
- }
- }
- // console.log(id);
- // console.groupEnd();
- return id;
- };
- // 选中全部图片
- var ctrlSelectAll = function () {
- // console.group("ctrlSelectAll");
- var itemList = $class('_image-items').children;
- if (itemList) {
- for (let i = 0; i < itemList.length; i++) {
- let index = itemList[i].children[0].children[0].children.length - 1;
- let bt = itemList[i].children[0].children[0].children[index];
- bt.checked = true;
- removeClassName(itemList[i].children[0], 'cmheia_item_unselect');
- }
- }
- // console.groupEnd();
- };
- // 反选
- var ctrlSelectInvert = function () {
- // console.group("ctrlSelectInvert");
- var itemList = $class('_image-items').children;
- if (itemList) {
- for (let i = 0; i < itemList.length; i++) {
- let index = itemList[i].children[0].children[0].children.length - 1;
- let bt = itemList[i].children[0].children[0].children[index];
- let x = bt.checked;
- bt.checked = !x;
- toggleClassName(itemList[i].children[0], 'cmheia_item_unselect');
- }
- }
- // console.groupEnd();
- };
- // 提取指定页面
- var fetchPageContent = function (arr, prefix, onload, onerror, referer) {
- // console.group('fetchPageContent');
- // console.warn('Referer :', referer);
- for (let i of arr) {
- // 听说闭包很深奥,那就多练练
- var target = i.replace(/.*illust_id=(\d+).*/, "$1");
- // console.log(prefix + i);
- GM_xmlhttpRequest({
- method : 'GET',
- url : prefix + i,
- headers: {
- 'Referer': referer
- },
- onload : (function (xhr) {
- var id = target;
- return function (xhr) {
- onload(id, xhr);
- };
- })(),
- onerror: (function (xhr) {
- var id = target;
- return function (xhr) {
- onerror(id, xhr);
- };
- })()
- });
- }
- // console.groupEnd();
- };
- // 从 html 源码提取原图链接
- // 先尝试作为单图解析,解析失败再作为图集解析,解析再次失败再作为动图解析
- // 返回:
- // 单图 -> 原图链接(57565823);
- // -> html 中包含字符串 "original-image"
- // 多图 -> 包含原图的目标页面链接(第二个参数为此而生)(56207143);
- // -> html 中包含字符串 "multiple"
- // 动图 -> 原图压缩包链接(44588377,56083603)(动图仅包含单个 zip , 使用与单图相同的方法处理)
- // -> html 中包含字符串 "ugoira_view"
- var parseWorkPage = function (html, url) {
- // console.group("parseWorkPage");
- // 2016-07-18 更新特征:
- // 单图 -> 原图链接(57565823);
- // -> html 中包含字符串 "original-image"
- // -> document.querySelector('.works_display').innerHTML.indexOf('manga') === -1
- // -> html 中仅字符串 "manga" 仅出现一次 <meta name="keywords" content="pixiv,插画,漫画,manga,社区,SNS投稿,比赛">
- // -> 即 XMLHttpRequest.responseText.match(/manga/gi).length === 1
- // 多图 -> 包含原图的目标页面链接(第二个参数为此而生)(56207143);
- // -> html 中包含字符串 "multiple"
- // -> html 中仅字符串 "manga" 仅出现一次 <meta name="keywords" content="pixiv,插画,漫画,manga,社区,SNS投稿,比赛">
- // -> document.querySelector('.works_display').innerHTML.indexOf('manga') !== -1
- // -> 即 XMLHttpRequest.responseText.match(/manga/gi).length > 1
- // 动图 -> 原图压缩包链接(44588377,56083603)(动图仅包含单个 zip , 使用与单图相同的方法处理)
- // -> html 中包含字符串 "ugoira_view"
- // -> document.querySelector('.works_display').innerHTML.indexOf('manga') === -1
- // -> html 中仅字符串 "manga" 仅出现一次 <meta name="keywords" content="pixiv,插画,漫画,manga,社区,SNS投稿,比赛">
- // -> 即 XMLHttpRequest.responseText.match(/manga/gi).length === 1
- // 实例:
- // 单图
- // <div class="works_display"><div class="_layout-thumbnail ui-modal-trigger"><img src="http://i1.pixiv.net/c/600x600/img-master/img/2015/01/23/12/29/40/xxxxxxxx_p0_master1200.jpg" alt="Верный"></div></div>
- // 多图(伪)
- // <div class="works_display"><a href="member_illust.php?mode=big&illust_id=xxxxxxxx" target="_blank" class=" _work manga "><div class="_layout-thumbnail"><img src="http://i3.pixiv.net/c/600x600/img-master/img/2015/11/13/20/05/08/xxxxxxxx_p0_master1200.jpg" alt="COMITIA114"></div></a></div>
- // 多图(真)
- // <div class="works_display"><a href="member_illust.php?mode=manga&illust_id=xxxxxxxx" target="_blank" class=" _work multiple "><div class="_layout-thumbnail"><div class="multiple"><i class="_icon-20 _icon-files"></i></div><img src="http://i3.pixiv.net/c/600x600/img-master/img/2016/07/15/20/47/58/xxxxxxxx_p0_master1200.jpg" alt="シャロ生誕祭"></div></a></div>
- // 动图
- // <div class="works_display"><div class="_ugoku-illust-player-container ready playing"><div class="wrapper"><div class="_spinner"></div><div class="player toggle"><canvas width="477.326968973747" height="600" style="width: 477.327px; height: 600px;"></canvas></div><a href="/member_illust.php?mode=ugoira_view&illust_id=xxxxxxxx" target="_blank" class="full-screen _ui-tooltip" data-tooltip="全屏显示"><img src="http://source.pixiv.net/www/images/ugoku-illust/full-screen.png?2" width="20" height="20"></a></div></div><div class="_full-screen-container"><div class="_ugoku-illust-player-container"><div class="wrapper toggle"><div class="_spinner"></div><div class="player"></div></div><div class="exit-full-screen"><img src="http://source.pixiv.net/www/images/ugoku-illust/exit-full-screen.png" width="30" height="30"></div></div></div></div>
- // 对应正则:
- // /<div[^<>]*class=\"works_display\">[^<>]*<(\w*)[^<>]*class=\"([\w\s\-\_]*)\"[^<>]*>/
- // /<div[^<>]*class[^<>]*=[^<>]*\"[^<>]*works_display[^<>]*\">[^<>]*<(\w*)[^<>]*class[^<>]*=[^<>]*\"([\w\s\-\_]*)\"[^<>]*>/
- // 上述实例 match 结果:
- // 单图
- // ["<div class="works_display"><div class="_layout-thumbnail ui-modal-trigger">", "div", "_layout-thumbnail ui-modal-trigger"]
- // 多图(伪)
- // ["<div class="works_display"><a href="member_illust.php?mode=big&illust_id=xxxxxxxx" target="_blank" class=" _work manga ">", "a", " _work manga "]
- // 多图(真)
- // ["<div class="works_display"><a href="member_illust.php?mode=manga&illust_id=xxxxxxxx" target="_blank" class=" _work multiple ">", "a", " _work multiple "]
- // 动图
- // ["<div class="works_display"><div class="_ugoku-illust-player-container ready playing">", "div", "_ugoku-illust-player-container ready playing"]
- var result = [],
- target = html.match(/<div[^<>]*class=\"works_display\">[^<>]*<(\w*)[^<>]*class=\"([\w\s\-\_]*)\"[^<>]*>/);
- if (target && 3 === target.length) {
- // 先尝试用类名判断
- if (-1 !== target[2].indexOf("trigger")) {
- // 单图
- target = html.match(/<img\s+alt=\"[^\"]*\".*data-src=\"([^\"]*)\".*class=\"original-image\">/);
- if (target && target[1]) {
- result.push(target[1]);
- }
- // console.log("单图", result);
- // console.log(target);
- } else if (-1 !== target[2].indexOf("multiple")) {
- // 多图(真)
- target = html.match(/<ul class=\"meta\"><li>[^<>]*<\/li><li>[^<>\d]*(\d+)P<\/li>/);
- if (target && target[1]) {
- let count = parseInt(target[1]);
- result.push(count);
- for (let i = 0; i < count; i++) {
- let link = url.replace(/medium/, "manga_big");
- link = `${link}&page=${i}`;
- result.push(link);
- }
- }
- // console.log("多图(真)", result);
- // console.log(target);
- } else if (-1 !== target[2].indexOf("_ugoku")) {
- // 动图
- target = html.match(/pixiv\.context\.ugokuIllustFullscreenData[\s]*=[\s]*\{[^}]*\"src\"[\s]*:[\s]*\"((http|https):[\\\/]*[\w\d\.]*pximg\.net(.*)\/(\d+)_ugoira(\d+)x(\d+)\.zip)\"/);
- if (target && target[1]) {
- result[0] = target[1].replace(/\\(.)/gi, '$1');
- }
- // console.log("动图", result);
- } else if (-1 !== target[2].indexOf("manga")) {
- // 多图(伪)
- result.push(1);
- result.push(url.replace(/medium/, "big"));
- // http://www.pixiv.net/member_illust.php?mode=big&illust_id=53517282
- // 这个链接直接打开会被302导致失败
- // 需要设置 Referer
- // console.log("多图(伪)", result);
- // console.log(target);
- } else {
- // 未知
- // console.error("错误:未知类型", target);
- }
- } else {
- // 不行再靠老一套
- target = html.match(/<img\s+alt=\"[^\"]*\".*data-src=\"([^\"]*)\".*class=\"original-image\">/);
- if (target && target[1]) {
- // 单图
- result[0] = target[1];
- // console.log("单图", result);
- } else if (-1 !== html.indexOf("multiple") && (target = html.match(/<ul class=\"meta\"><li>[^<>]*<\/li><li>[^<>\d]*(\d+)P<\/li>/)) && target && target[1]) {
- // 根据 meta 判断遇到作者使用多图模式发表单张图片会失败
- // meta === "一次性投稿多张作品 "(\d+)"P"
- // 多图
- // http://www.pixiv.net/member_illust.php?mode=manga_big&illust_id=xxxxxxxx&page=0
- let count = parseInt(target[1]);
- result.push(count);
- for (let i = 0; i < count; i++) {
- let link = url.replace(/medium/, "manga_big");
- link = `${link}&page=${i}`;
- result.push(link);
- }
- // console.log("多图", result, target);
- } else if (html.match(/manga/gi).length > 1) {
- // 多图模式的单图
- result.push(1);
- result.push(url.replace(/medium/, "big"));
- // http://www.pixiv.net/member_illust.php?mode=big&illust_id=53517282
- // 这个链接直接打开会被302导致失败
- // 需要设置 Referer
- // console.log("多图模式的单图", result, target);
- } else if (-1 !==html.indexOf("ugoira_view") && (target = html.match(/pixiv\.context\.ugokuIllustFullscreenData[\s]*=[\s]*\{[^}]*\"src\"[\s]*:[\s]*\"((http|https):[\\\/]*[\w\d\.]*pixiv\.net(.*)\/(\d+)_ugoira(\d+)x(\d+)\.zip)\"/)) && target && target[1]) {
- // 动图
- // http://www.pixiv.net/member_illust.php?mode=medium&illust_id=xxxxxxxx
- result[0] = target[1].replace(/\\(.)/gi, '$1');
- // console.log("动图", result[0]);
- } else {
- // console.error("错误:未知类型", target);
- }
- }
- // console.groupEnd();
- return result;
- };
- // 提取选定的原图
- var extractWorkList = function (url) {
- // console.group("开始提取");
- var exportImages = function () {
- if (result.isAllDone()) {
- var info,
- arr,
- res = result.exportAll();
- // console.log("已采集原图:", res.done);
- // console.log("提取失败: ", res.fail);
- info = "搞到 " + res.done.length + " 张图啦 (⺻▽⺻ )";
- arr = result.getID();
- for (let i = res.fail.length - 1; i >= 0; i--) {
- if (0 === res.fail[i]) {
- arr.splice(i, 1);
- }
- }
- if (arr.length) {
- info += " 然而" + arr.toString() + "提取失败 (ಥ_ಥ)";
- }
- msg(info);
- GM_setClipboard(res.done.join("\r\n"));
- }
- };
- var recordFails = function (illustId, status) {
- // console.error(illustId, "提取失败", status);
- msg(illustId + "提取失败 (ಥ_ಥ) [http " + status + "]");
- result.recordTargetLength(illustId, -1);
- result.setTarget(illustId, null, 0, -1);
- };
- var progress = 0,
- result;
- if (0 === url.length) {
- msg("至少选择一张图吧 ◔ ‸◔?");
- // console.groupEnd();
- return;
- }
- msg("正在赶工 (๑•̀_•́๑)");
- // console.log("添加目标", url);
- result = new illustCollector();
- for (let i = 0; i < url.length; i++) {
- result.addTarget(url[i].replace(/.*illust_id=(\d+).*/, "$1"));
- }
- fetchPageContent(url,
- window.location.origin,
- function (illustId, xhr) {
- // console.group("得到页面", illustId, ", 开始解析", illustId == xhr.finalUrl.replace(/.*illust_id=(\d+).*/, "$1"));
- progress++;
- msg("进度" + progress + "/" + url.length + " (ฅ´ω`ฅ)");
- // console.warn("进度" + progress + "/" + url.length + " (ฅ´ω`ฅ)");
- if (200 === xhr.status) {
- // 解析页面取得原图链接(单图和动图)或新的目标页面链接(多图)
- let target = parseWorkPage(xhr.responseText, xhr.finalUrl);
- if (target) {
- // 记录原图数量
- if (1 === target.length) {
- result.recordTargetLength(illustId, 1);
- // 单图和动图可立即取得原图链接,那就顺手录入,并标记为已完成
- let i = result.setTarget(illustId, target[0], 0, 1);
- // console.log("记录单图或动图", i);
- // msg("到手" + parsed + "页,就剩" + (url.length - parsed) + "页啦 (ฅ´ω`ฅ)");
- } else {
- var count = target.shift();
- result.recordTargetLength(illustId, count);
- // 多图需要再次解析链接
- // console.warn("多图需要再次解析链接", target);
- if (1 === count && 1 === target.length) { // 伪多图
- result.setTarget(illustId, target[0], 0, 0);
- // console.warn("伪多图", target[0]);
- } else {
- for (let i = 0; i < count; i++) {
- result.setTarget(illustId, target[i], i, 0);
- // console.log(target[i]);
- }
- }
- parseMultiImageUrl(target, function (obj) {
- // console.warn("n:callback", obj);
- // console.log("搞完这 ", count, " 张图啦 (⺻▽⺻ )");
- for (let i = 0; i < count; i++) {
- let status = (undefined !== obj.done[i] && undefined === obj.fail[i]) ? 1 : -1;
- result.setTarget(illustId, obj.done[i], i, status);
- }
- exportImages();
- });
- }
- } else {
- recordFails(illustId, xhr.status);
- }
- } else {
- recordFails(illustId, xhr.status);
- }
- exportImages();
- // console.groupEnd();
- },
- function (illustId, xhr) {
- // console.group("页面", illustId, ", 获取失败", illustId == xhr.finalUrl.replace(/.*illust_id=(\d+).*/, "$1"));
- progress++;
- msg("进度" + progress + "/" + url.length + " (ฅ´ω`ฅ)");
- recordFails(illustId, xhr.status);
- exportImages();
- // console.groupEnd();
- },
- window.location.href
- );
- // console.groupEnd();
- };
- // 添加按钮
- var addButtonWorkList = function () {
- // console.group("addButtonWorkList");
- var itemList = $class("_image-items");
- if (itemList) {
- let button,
- menu = $class('menu-items');
- // 全选按钮
- button = document.createElement('li');
- button.innerHTML="<a href='javascript:;'>全选</a>";
- button.addEventListener("click", function () {
- ctrlSelectAll();
- });
- menu.appendChild(button);
- // 反选按钮
- button = document.createElement('li');
- button.innerHTML="<a href='javascript:;'>反选</a>";
- button.addEventListener("click", function () {
- ctrlSelectInvert();
- });
- menu.appendChild(button);
- // 导出按钮
- button = document.createElement('li');
- button.innerHTML="<a href='javascript:;'>收割 ๑乛◡乛๑ (●´∀`●)</a>";
- button.addEventListener("click", function () {
- extractWorkList(extractIllustUrl());
- });
- menu.appendChild(button);
- // 消息显示区域
- button = document.createElement('li');
- button.innerHTML="<span id='extracted'></span>";
- menu.appendChild(button);
- // 添加复选框
- addStyle();
- for (let i = 0; i < itemList.children.length; i++) {
- button = document.createElement('input');
- button.type = "checkbox";
- button.className = "cmheia_checkbox";
- button.checked = true;
- button.setAttribute('data-index', i);
- // a
- // 删除原先的链接
- // console.log(itemList.children[i].children[0]);
- itemList.children[i].children[0].setAttribute('href', '#');
- // 增加背景
- itemList.children[i].children[0].setAttribute('style', 'margin-bottom:0;');
- addClassName(itemList.children[i].children[0], 'cmheia_item');
- // addClassName(itemList.children[i].children[0], 'cmheia_item_unselect');
- // div
- // 增加点击事件
- itemList.children[i].children[0].children[0].appendChild(button);
- itemList.children[i].children[0].addEventListener("click", function (e) {
- // 点击图片切换选中状态
- let index = this.children[0].children.length - 1;
- let bt = this.children[0].children[index];
- // console.log(index);
- // console.log(bt);
- // console.log('点击图片切换' + (bt.checked ? '未' : '') + '选中状态');
- bt.checked = !bt.checked;
- toggleClassName(this, 'cmheia_item_unselect');
- });
- }
- }
- // console.groupEnd();
- };
- /**********************************************************************
- * 作品页面功能
- **********************************************************************/
- // 移除分享按钮
- var removeShareButton = function () {
- var shareButton = $class('share-link-container'),
- count = shareButton.children.length;
- for (let i = 0; i < count; i++) {
- shareButton.removeChild(shareButton.children[0]);
- }
- };
- // 添加导出按钮
- var addButtonWorkPage = function () {
- var button = document.createElement('li');
- button.innerHTML="<a href='javascript:;' style='margin:0 8px;'>收割 ๑乛◡乛๑ (●´∀`●)</a>";
- button.addEventListener("click", function () {
- extractWorkList([window.location.pathname + window.location.search]);
- });
- $class('share-link-container').appendChild(button);
- button = document.createElement('li');
- button.innerHTML="<span id='extracted'></span>";
- $class('share-link-container').appendChild(button);
- };
- // 初始化作品列表界面
- var postInitWorksListUI = function () {
- let itemList = $class("_image-items");
- if (itemList) {
- if (1 === itemList.children.length && "" === itemList.children[0].className) {
- // <li>未找到任何相关结果</li>
- // console.log("未找到任何相关结果");
- } else {
- addButtonWorkList();
- document.addEventListener("keyup", function (event) {
- // F9 = 120
- if (120 === event.keyCode) {
- extractWorkList(extractIllustUrl());
- }
- }, true);
- }
- }
- console.warn("inited");
- };
- // 初始化作品列表界面
- var initWorksListUI = function () {
- var DOMObserverTimer = false;
- var DOMObserverConfig = {
- childList : true,
- subtree : true,
- };
- var DOMObserver = new MutationObserver(function () {
- if (DOMObserverTimer !== 'false') {
- clearTimeout(DOMObserverTimer);
- }
- DOMObserverTimer = setTimeout(function () {
- if (!$id("extracted")) {
- DOMObserver.disconnect();
- postInitWorksListUI();
- }
- }, 100);
- });
- DOMObserver.observe(document.querySelector('.image-item'), DOMObserverConfig);
- };
- // 初始化作品界面
- var initWorkPageUI = function () {
- removeShareButton();
- addButtonWorkPage();
- document.addEventListener("keyup", function (event) {
- // F9 = 120
- if (120 === event.keyCode) {
- extractWorkList([window.location.pathname + window.location.search]);
- }
- }, true);
- console.warn("inited");
- };
- var initPEUI = function () {
- if (isWorksList()) {
- initWorksListUI();
- } else {
- initWorkPageUI();
- }
- };
- // 运行
- console.warn("P站原图收割机:开始");
- initPEUI();
- }) ();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址