pixiv页面生成按钮用于复制原图链接和下载原图
// ==UserScript== // @name pixiv获取原图 // @namespace https://github.com/MuXia-0326/twitter-auto-original-picture // @version 1.5 // @description pixiv页面生成按钮用于复制原图链接和下载原图 // @author Mossia // @icon https://raw.githubusercontent.com/MuXia-0326/drawio/master/angri.png // @match *://www.pixiv.net/* // @grant unsafeWindow // @grant GM_xmlhttpRequest // @grant GM_download // @license MIT // ==/UserScript== const css = ` .pixiv-Btn { z-index: 1000; position: relative; display: inline-block; margin-right: 5px; padding: 10px; text-align: center; font-size: 18px; letter-spacing: 1px; text-decoration: none; color: rgb(0, 150, 250); background: transparent; cursor: pointer; transition: ease-out 0.5s; border: 2px solid rgb(0, 150, 250); border-radius: 10px; box-shadow: inset 0 0 0 0 rgb(0, 150, 250); } .pixiv-Btn:hover { color: white; box-shadow: inset 0 -100px 0 0 rgb(0, 150, 250); } .pixiv-Btn:active { transform: scale(0.9); } .pixiv-Btn:hover svg { fill: white; } .pixiv-Btn:active svg, .pixiv-Btn svg { fill: rgb(0, 150, 250); } .Btn { position: absolute; right: 0px; bottom: 0px; } .svgClass { display: flex; } .share-btn { display:none; } `; let styleTag = document.createElement('style'); styleTag.innerText = css; document.head.append(styleTag); function ILog() { this.prefix = ''; this.v = function (value) { if (level <= this.LogLevel.Verbose) { console.log(this.prefix + value); } }; this.i = function (info) { if (level <= this.LogLevel.Info) { console.info(this.prefix + info); } }; this.w = function (warning) { if (level <= this.LogLevel.Warning) { console.warn(this.prefix + warning); } }; this.e = function (error) { if (level <= this.LogLevel.Error) { console.error(this.prefix + error); } }; this.d = function (element) { if (level <= this.LogLevel.Verbose) { console.log(element); } }; this.setLogLevel = function (logLevel) { level = logLevel; }; this.LogLevel = { Verbose: 0, Info: 1, Warning: 2, Error: 3, }; let level = this.LogLevel.Warning; } var iLog = new ILog(); // let pixiv_proxy = 'https://i.pixiv.cat'; let pixiv_proxy = 'https://pixiv.mossia.top'; let g_getArtworkUrl = '/ajax/illust/#id#/pages'; let share_url = ''; let share_url_two = ''; let userName = ''; // 当前页面类型 let g_pageType = -1; // 页面相关的一些预定义,包括处理页面元素等 let PageType = { // 作品详情页 Artwork: 0, // 总数 PageTypeCount: 1, }; /* Pages 必须实现的函数 * PageTypeString: string,字符串形式的 PageType * bool CheckUrl: function(string url),用于检查一个 url 是否是当前页面的目标 url * ProcessPageElements: function(),处理页面(寻找图片元素、添加按钮) */ let Pages = {}; Pages[PageType.Artwork] = { PageTypeString: 'ArtworkPage', CheckUrl: function (url) { return /^https:\/\/www.pixiv.net\/artworks\/.*/.test(url) || /^https:\/\/www.pixiv.net\/en\/artworks\/.*/.test(url); }, ProcessPageElements: function () { if (userName === '') { getUserName(); } // 动图不处理 if (document.querySelector('main figure canvas')) { return; } // 未加载完不处理 if (!document.querySelector('main figure')) { return; } let allImage = document.querySelector('main figure').parentNode.querySelector('section + button'); if (allImage) { allImage.click(); } let matched = location.href.match(/artworks\/(\d+)/); if (!matched) { return; } let pid = matched[1]; let url = g_getArtworkUrl.replace('#id#', pid); let original = []; //生成按钮 let divImages = document.querySelectorAll('main figure div:first-child div[role="presentation"]'); divImages.forEach((e, i) => { let _this = e; let image = _this.querySelector('a').parentNode; if (image.querySelector('.Btn') && image.querySelector('.Btn').getAttribute('data-pid') === pid) { return; } fetch(url, { method: 'GET', }) .then((response) => response.json()) .then((json) => { iLog.i('Got artwork urls:'); if (json.error === true) { iLog.e('Server responsed an error: ' + json.message); return; } for (let i = 0; i < json.body.length; i++) { original.push(json.body[i].urls.original); } }) .catch((error) => { iLog.e('Request image urls failed!'); if (error) { iLog.e(error); } }); let btns = image.querySelectorAll('.Btn'); if (btns.length > 0) { btns.forEach((btn) => btn.remove()); } let div = document.createElement('div'); div.innerHTML = ` <div class="Btn" data-pid=${pid}> <button class="pixiv-Btn" id="cp_${i}"> <div class="svgClass"> <svg t="1694962361717" class="icon" viewBox="0 0 #### ####" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5412" width="20" height="20"> <path d="M761.088 715.3152a38.7072 38.7072 0 0 1 0-77.4144 37.4272 37.4272 0 0 0 37.4272-37.4272V265.0112a37.4272 37.4272 0 0 0-37.4272-37.4272H425.6256a37.4272 37.4272 0 0 0-37.4272 37.4272 38.7072 38.7072 0 1 1-77.4144 0 115.0976 115.0976 0 0 1 114.8416-114.8416h335.4624a115.0976 115.0976 0 0 1 114.8416 114.8416v335.4624a115.0976 115.0976 0 0 1-114.8416 114.8416z" p-id="5413" ></path> <path d="M589.4656 883.0976H268.1856a121.1392 121.1392 0 0 1-121.2928-121.2928v-322.56a121.1392 121.1392 0 0 1 121.2928-121.344h321.28a121.1392 121.1392 0 0 1 121.2928 121.2928v322.56c1.28 67.1232-54.1696 121.344-121.2928 121.344zM268.1856 395.3152a43.52 43.52 0 0 0-43.8784 43.8784v322.56a43.52 43.52 0 0 0 43.8784 43.8784h321.28a43.52 43.52 0 0 0 43.8784-43.8784v-322.56a43.52 43.52 0 0 0-43.8784-43.8784z" p-id="5414" ></path> </svg> </div> </button> <button class="pixiv-Btn" id="download_${i}"> <div class="svgClass"> <svg t="1694962091616" class="icon" viewBox="0 0 #### ####" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4129" id="mx_n_1694962091617" width="20" height="20"> <path d="M160 579.2a28.8 28.8 0 0 1 28.8 28.8v170.672c0 30.4 25.664 56.528 59.2 56.528h528c33.536 0 59.2-26.144 59.2-56.528V608a28.8 28.8 0 0 1 57.6 0v170.672c0 63.856-53.12 114.128-116.8 114.128h-528c-63.68 0-116.8-50.272-116.8-114.128V608a28.8 28.8 0 0 1 28.8-28.8z" p-id="4130"></path><path d="M540.8 176l0 464a28.8 28.8 0 0 1-57.6 0L483.2 176a28.8 28.8 0 0 1 57.6 0z" p-id="4131"></path> <path d="M331.632 459.632a28.8 28.8 0 0 1 40.736 0l160 160a28.8 28.8 0 0 1-40.736 40.736l-160-160a28.8 28.8 0 0 1 0-40.736z" p-id="4132"></path><path d="M692.368 459.632a28.8 28.8 0 0 0-40.736 0l-160 160a28.8 28.8 0 0 0 40.736 40.736l160-160a28.8 28.8 0 0 0 0-40.736z" p-id="4133"></path> </svg> </div> </button> <button class="pixiv-Btn share-btn" id="share_${i}"> <div class="svgClass"> <svg t="1713618483987" class="icon" viewBox="0 0 #### ####" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2790" width="20" height="20"> <path d="M720.020242 809.16812c0-49.233308 39.919175-89.151459 89.151459-89.151459s89.150436 39.918151 89.150436 89.151459c0 49.227168-39.918151 89.159646-89.150436 89.159646S720.020242 858.397335 720.020242 809.16812zM571.433112 214.824717c0-49.234331 39.919175-89.152483 89.151459-89.152483 49.234331 0 89.152483 39.918151 89.152483 89.152483 0 49.232285-39.918151 89.151459-89.152483 89.151459C611.352287 303.976176 571.433112 264.057001 571.433112 214.824717zM125.674792 675.441443c0-82.07018 66.530252-148.586107 148.585083-148.586107 82.056877 0 148.58713 66.515926 148.58713 148.586107 0 82.071204-66.531276 148.58713-148.58713 148.58713C192.205045 824.028573 125.674792 757.511623 125.674792 675.441443zM66.240145 675.441443c0 114.89375 93.142353 208.027917 208.019731 208.027917 81.402985 0 151.8525-46.752814 186.03809-114.870214l200.360284 35.288714-0.073678 5.28026c0 82.07632 66.531276 148.594293 148.58713 148.594293s148.586107-66.517973 148.586107-148.594293c0-82.072227-66.530252-148.586107-148.586107-148.586107-59.507302 0-110.815875 34.927487-134.554532 85.436858l-195.454554-34.403554c2.059915-11.738345 3.119037-23.839965 3.119037-36.174897 0-54.311976-20.822235-103.748922-54.892191-140.779304l180.740434-180.755784c16.309454 6.152117 33.983999 9.503445 52.454676 9.503445 82.056877 0 148.58713-66.514903 148.58713-148.586107 0-82.07018-66.530252-148.58713-148.58713-148.58713-82.055854 0-148.585083 66.51695-148.585083 148.58713 0 41.674145 17.165961 79.32772 44.792159 106.317421L381.013225 496.92056c-31.211862-18.71934-67.703985-29.499871-106.753349-29.499871C159.382499 467.421712 66.240145 560.549739 66.240145 675.441443z" p-id="2791"></path> </svg> </div> </button> </div> `; image.appendChild(div); document.getElementById(`cp_${i}`).addEventListener('click', function () { let newUrl = original[i].replace('https://i.pximg.net', pixiv_proxy); navigator.clipboard.writeText(newUrl); }); document.getElementById(`download_${i}`).addEventListener('click', function () { // 点击喜欢按钮 let likeDiv = document.querySelector('main section section div.sc-181ts2x-3.cXSAgn'); if (likeDiv) { let a = likeDiv.querySelector('a'); if (!a) { likeDiv.querySelector('button').click(); } } let newUrl = original[i]; GM_xmlhttpRequest({ method: 'GET', url: newUrl, headers: { Referer: 'https://www.pixiv.net/', }, responseType: 'blob', // 添加这一行 onload: function (response) { if (response.status === 200) { var blobUrl = URL.createObjectURL(response.response); GM_download(blobUrl, newUrl.substring(newUrl.lastIndexOf('/') + 1)); } else { console.error('Download failed:', response.statusText); } }, }); GM_xmlhttpRequest({ method: 'POST', url: 'https://api.mossia.top/add/pPidQueue', headers: { 'Content-Type': 'application/json', }, data: JSON.stringify({ pidList: [pid], createBy: userName, }), onload: function (response) { let r###lt = JSON.parse(response.responseText); }, onerror: function (error) { console.error('Request failed:', error); }, }); }); document.getElementById(`share_${i}`).addEventListener('click', function () { let newUrl = original[i].replace('https://i.pximg.net', pixiv_proxy); GM_xmlhttpRequest({ method: 'POST', url: share_url, // 目标 URL headers: { 'Content-Type': 'application/json', }, data: JSON.stringify({ imageUrl: newUrl }), onload: function (response) { var responseData = JSON.parse(response.responseText); console.log('Received response:', responseData); }, onerror: function (error) { console.error('Request failed:', error); }, }); GM_xmlhttpRequest({ method: 'POST', url: share_url_two, // 目标 URL headers: { 'Content-Type': 'application/json', }, data: JSON.stringify({ urls: [newUrl] }), onload: function (response) { var responseData = JSON.parse(response.responseText); console.log('Received response:', responseData); }, onerror: function (error) { console.error('Request failed:', error); }, }); }); }); }, }; function main() { // 匹配当前页面 for (let i = 0; i < PageType.PageTypeCount; i++) { if (Pages[i].CheckUrl(location.href)) { g_pageType = i; break; } } if (g_pageType >= 0) { iLog.i('当前页面类型:' + Pages[g_pageType].PageTypeString); } else { iLog.i('当前页面类型:未知'); clearInterval(mainInterval); return; } // 执行操作 Pages[g_pageType].ProcessPageElements(); } function getUserName() { var div = document.querySelectorAll('.sc-pkfh0q-0.kYDpSN .sc-1asno00-0.feBRRY'); div.forEach((e, i) => { userName = e.getAttribute('title'); console.log(userName); }); } let mainInterval = setInterval(main, 200);