您需要先安装一个扩展,例如 篡改猴、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或关注我们的公众号极客氢云获取最新地址