您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
获取pixiv的排行数据,并新增到mio
当前为
// ==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 // ==/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 + ` <div class="mio-pro-msg" style="display: flex;flex-direction: column;gap: 10px;"> <p>当前排行榜类型为:${params.rankType}</p> <p>过滤一些非插画类型,实际抓取数据量为:${params.rankList.length}条</p> <p>开始发送数据...</p> <p style="color: #69f769;" class="mio-result-message"></p> </div> `; request({ method: "POST", url: "https://kasuie.cc/apis/prank/newDate", headers: { "Content-Type": "application/json" }, data: JSON.stringify(params), }) .then((res) => { console.log("请求mio结果:", res); let msg = document.querySelector(".mio-result-message"); if (res.success) { msg.innerHTML = "🎉好耶!发送数据成功~"; if (mioDates) { GM.setValue("mio-dates", `${mioDates},${date}`); mioDates = `${mioDates},${date}`; } else { GM.setValue("mio-dates", date); mioDates = data; } } else { msg.style.color = "red"; msg.innerHTML = "💔发送失败惹"; } GM.notification(res.message); }) .finally(() => { onLoading(false); }); }) .finally(() => { onLoading(false); }); }; const NOW = getDate(); /** 操作按钮组 */ const actions = document.createElement("div"); /** 弹框内容 */ const content = document.createElement("div"); /** 提交到mio按钮 */ const addMio = document.createElement("button"); /** 提交到mio按钮 */ const prevBtn = document.createElement("button"); /** 提交到mio按钮 */ const nextBtn = document.createElement("button"); /** 关闭弹框按钮 */ const span = document.createElement("span"); const html = document.querySelector("html"); /** 弹框遮罩 */ const div = document.createElement("div"); div.id = "mio-tools"; /** 弹框 */ const main = document.createElement("div"); main.className = "mio-tools-main"; const onLoading = (loading) => { if (loading) { addMio.disabled = true; } else { addMio.disabled = false; } }; const onModalChange = async () => { if (div.classList.contains("mio-tools-open")) { html.style.overflow = "unset"; div.classList.remove("mio-tools-open"); content.innerHTML = null; } else { mioDates = await GM.getValue("mio-dates", ""); html.style.overflow = "hidden"; div.classList.add("mio-tools-open"); if (!DATE) { DATE = getDate(); } if (NOW == DATE) { nextBtn.disabled = true; } content.innerHTML = ` <p style="color: #f5765c;" class="mio-error"></p> <p>将要获取排行榜数据日期为:<span style="color: #69f769;" class="mio-date">${DATE}</span></p> `; 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 = ` <svg width="24" height="24" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M11.7816 4.03157C12.0062 3.80702 12.0062 3.44295 11.7816 3.2184C11.5571 2.99385 11.193 2.99385 10.9685 3.2184L7.50005 6.68682L4.03164 3.2184C3.80708 2.99385 3.44301 2.99385 3.21846 3.2184C2.99391 3.44295 2.99391 3.80702 3.21846 4.03157L6.68688 7.49999L3.21846 10.9684C2.99391 11.193 2.99391 11.557 3.21846 11.7816C3.44301 12.0061 3.80708 12.0061 4.03164 11.7816L7.50005 8.31316L10.9685 11.7816C11.193 12.0061 11.5571 12.0061 11.7816 11.7816C12.0062 11.557 12.0062 11.193 11.7816 10.9684L8.31322 7.49999L11.7816 4.03157Z" fill="currentColor" fill-rule="evenodd" clip-rule="evenodd"></path></svg> `; 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); })();