// ==UserScript== // @name Pixiv Mio Tools // @namespace http://tampermonkey.net/ // @version 1.0.5 // @license MIT // @description 获取pixiv的排行数据,并新增到mio // @author kasuie // @match https://www.pixiv.net/ranking.php* // @icon https://www.google.com/s2/favicons?sz=64&domain=pixiv.net // @grant GM.xmlHttpRequest // @grant GM.notification // @grant GM.addStyle // @grant GM.getValue // @grant GM.setValue // @run-at document-end // @downloadURL none // ==/UserScript== (function () { "use strict"; let DEV = false; let DATE = ""; let mioDates = ""; const format = (v, date, mode, uid, uploadName) => { let tags = v?.tags || []; let pageCount = +v.illust_page_count; let pathDate = null, pixAvatar = null, exts = []; if (v.attr == "original" && !tags.includes("original")) { tags.push("原创"); tags.push("original"); } if (tags?.length) { tags = tags.filter((vv) => { return ( vv && !vv.includes("收藏") && !vv.includes("users") && !vv.includes("bookmarks") && !vv.includes("Bookmarks") && !vv.includes("R-18") ); }); } const matches = v.url.match( /\/(\d{4}\/\d{2}\/\d{2}\/\d{2}\/\d{2}\/\d{2})\// ); if (matches && matches[1]) { pathDate = matches[1]; } const extArr = v.url?.split("."); if (extArr?.length) { const ext = extArr[extArr.length - 1]; for (let index = 0; index < pageCount; index++) { exts.push(ext); } } if (v.profile_img && !v.profile_img.includes("no_profile")) { pixAvatar = v.profile_img ?.replace("https://i.pximg.net/user-profile/img/", "") ?.replace("_50", ""); } return { pid: v.illust_id, uid: v.user_id, author: v.user_name ?.replace(/@(.*)/, "") ?.replace(/@(.*)/, "") ?.replace(/❤(.*)/, "") ?.replace(/■(.*)/, "") ?.replace(/▶(.*)/, "") || v.user_name, rankType: mode, tags: tags?.join(","), exts: exts[0], pageCount: pageCount, title: v.title, datePath: pathDate, pixAvatar, width: v.width, height: v.height, aspectRatio: Math.round((v.width / v.height) * 1000) / 1000, createDate: new Date( new Date(v.illust_upload_timestamp * 1000).toLocaleString("chinese", { hour12: false, }) ), viewCount: v.view_count, ratingCount: v.rating_count, illusType: +v.illust_type, uploadName: uploadName, uploadUid: uid, status: v?.is_bookmarked ? v.yes_rank - 101 : v.yes_rank, startDate: v.yes_rank == 0 ? `${date}_${v.yes_rank}:${v.rank}` : null, endDate: v.yes_rank > 0 ? `${date}_${v.yes_rank}:${v.rank}` : null, }; }; const getDate = (prev, next, date) => { let currentDate = new Date(); if (!prev && !next) { if ( currentDate.getHours() > 12 || (currentDate.getHours() === 12 && currentDate.getMinutes() > 0) ) { currentDate.setDate(currentDate.getDate() - 1); } else { currentDate.setDate(currentDate.getDate() - 2); } } else if (date) { const year = date.slice(0, 4); const month = date.slice(4, 6) - 1; const day = date.slice(6, 8); currentDate = new Date(year, month, day); if (prev) { currentDate.setDate(currentDate.getDate() - 1); } else { currentDate.setDate(currentDate.getDate() + 1); } } const year = currentDate.getFullYear(); const month = String(currentDate.getMonth() + 1).padStart(2, "0"); const day = String(currentDate.getDate()).padStart(2, "0"); return `${year}${month}${day}`; }; const request = (data) => { return new Promise((resolve, reject) => { if (!data.method) { data.method = "get"; } if (!data.timeout) { data.timeout = 10000; } data.onload = function (res) { try { resolve(JSON.parse(res.responseText)); } catch (error) { reject(false); } }; data.onerror = function (e) { reject(false); }; data.ontimeout = function () { reject(false); }; GM.xmlHttpRequest(data); }); }; const getRankAndToMio = (_e) => { if (!onCheckDate()) return; const urlParams = new URLSearchParams(window.location.search); let mode = urlParams.get("mode"), date = DATE; let data = [], url = `/ranking.php?format=json`, uid = null; if (mode) url = `${url}&mode=${mode}`; if (date) url = `${url}&date=${date}`; const userDom = document.querySelector("div.sc-1asno00-0"); const uploadName = userDom.getAttribute("title"); onLoading(true); const page_1 = request({ method: "GET", url: `${url}&p=1`, headers: { referer: "https://www.pixiv.net/", "Accept-Language:": "zh-CN,zh-CN;q=0.9,zh;q=0.8,en-US;q=0.7,en,en-CN;q=0.6", }, }); const page_2 = request({ method: "GET", url: `${url}&p=2`, headers: { referer: "https://www.pixiv.net/", "Accept-Language:": "zh-CN,zh-CN;q=0.9,zh;q=0.8,en-US;q=0.7,en,en-CN;q=0.6", }, }); Promise.all([page_1, page_2]) .then(([res_1, res_2]) => { if (res_1 && res_2) { if (DEV) { console.log("page1:", res_1, "page_2", res_2); } const { contents: page1, date: date1, mode: mode1 } = res_1; const { contents: page2, date: date2, mode: mode2, prev_date, next_date, } = res_2; if (date1 == date2 && mode1 == mode2) { [...page1, ...page2].forEach((ele) => { // if (+ele?.illust_type == 0) { data.push(format(ele, date1, mode1, uid, uploadName)); // } }); return { rankDate: date1, prevDate: prev_date, nextDate: next_date, rankType: mode1, uploadName, rankList: data, }; } } }) .then((params) => { if (DEV) { console.log("请求mio参数:", params); return null; } content.innerHTML = content.innerHTML + `
当前排行榜类型为:${params.rankType}
过滤一些非插画类型,实际抓取数据量为:${params.rankList.length}条
开始发送数据...
将要获取排行榜数据日期为:${DATE}
`; onCheckDate(); } }; const onCheckDate = () => { if (mioDates && mioDates.includes(DATE)) { const error = document.querySelector(".mio-error"); error.innerText = "💤当前日期已抓取过~"; return false; } else { const error = document.querySelector(".mio-error"); error.innerText = ""; return true; } }; span.innerHTML = ` `; span.className = "mio-tools-main-close"; span.addEventListener("click", (_e) => onModalChange()); addMio.innerText = "抓取并提交Mio"; addMio.className = "mio-btn-add"; addMio.addEventListener("click", (_e) => { getRankAndToMio(_e); }); prevBtn.innerText = "前一天"; prevBtn.className = "mio-btn-prev"; prevBtn.addEventListener("click", (_e) => { const mioDate = document.querySelector(".mio-date"); const proMsg = content.querySelector(".mio-pro-msg"); DATE = getDate(true, null, DATE); if (NOW != DATE && nextBtn.disabled) { nextBtn.disabled = false; } if (proMsg) { content.removeChild(proMsg); } mioDate.innerText = DATE; onCheckDate(); }); nextBtn.innerText = "后一天"; nextBtn.className = "mio-btn-next"; nextBtn.addEventListener("click", (_e) => { const mioDate = document.querySelector(".mio-date"); if (NOW == DATE) { nextBtn.disabled = true; } else { DATE = getDate(null, true, DATE); const proMsg = content.querySelector(".mio-pro-msg"); if (proMsg) { content.removeChild(proMsg); } mioDate.innerText = DATE; onCheckDate(); } }); actions.className = "mio-tools-main-btns"; actions.appendChild(prevBtn); actions.appendChild(nextBtn); actions.appendChild(addMio); content.className = "mio-tools-main-content"; main.appendChild(span); main.appendChild(content); main.appendChild(actions); div.appendChild(main); const btn = document.createElement("button"); btn.id = "mio-tools-btn"; btn.addEventListener("click", (_e) => onModalChange()); btn.innerHTML = "Mio"; document.querySelector("body").appendChild(btn); GM.addStyle(` html { &::-webkit-scrollbar { width: 4px; transition: all .3s ease-in-out; } &::-webkit-scrollbar-thumb { cursor: pointer; border-radius: 10px; transition: all .15s ease-in-out; background: rgba(255, 255, 255, 0.15); box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.1); } &::-webkit-scrollbar-track { border-radius: 10px; box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.1); background: rgba(255, 255, 255, 0.05); } &::-webkit-scrollbar-thumb:hover { @apply bg-[#64d1e2]; } } #mio-tools-btn { position: fixed; right: 0px; top: 85%; border-radius: 16px; width: 36px; height: 36px; outline: none; border: none; padding: 6px 10px; z-index: 10; background: #0097fac7; display: flex; align-items: center; justify-content: center; cursor: pointer; color: #fff; } #mio-tools { position: fixed; display: flex; align-items: center; justify-content: center; width: 0; height: 0; overflow: hidden; top: 0; right: 0; background: #00000080; backdrop-filter: blur(2px); z-index: 99; } .mio-tools-open { width: 100% !important; height: 100vh !important; > .mio-tools-main { position: relative; background: #010101; width: 600px; height: 300px; border-radius: 16px; padding: 32px; transition: all .1s ease-in-out; display: flex; flex-direction: column; justify-content: space-between; gap: 16px; .mio-tools-main-close { position: absolute; right: 10px; top: 10px; color: #ffffff; cursor: pointer; rotate: 0deg; transition: all .3s ease-in-out; &:hover { transform: scale(1.1); color: #0097fa; rotate: 180deg; } } .mio-tools-main-content { flex: 1; color: #ffffff; display: flex; flex-direction: column; gap: 10px; } .mio-tools-main-btns { display: flex; justify-content: flex-end; gap: 16px; .mio-btn-add, .mio-btn-prev, .mio-btn-next { outline: none; border: none; padding: 6px 10px; border-radius: 10px; cursor: pointer; background: #0097fa; color: #ebebeb; } button:disabled { opacity: 0.7; cursor: not-allowed; } } } } `); document.querySelector("body").appendChild(div); })();