🏠 Home 

Pixiv Show Request Price

For each artwork on Pixiv, show the request price if available and sort artworks by price.


安装此脚本?
// ==UserScript==
// @name         Pixiv Show Request Price
// @author       MahdeenSky
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  For each artwork on Pixiv, show the request price if available and sort artworks by price.
// @match        https://www.pixiv.net/request/creators/works/illust
// @match        https://www.pixiv.net/request/creators/works/illust?*
// @match        https://www.pixiv.net/bookmark_new_illust.php
// @match        https://www.pixiv.net/discovery
// @icon         data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
// @grant        none
// @license      GNU GPLv3
// ==/UserScript==
(function () {
"use strict";
const button = document.createElement("button");
button.innerText = "Show Request Price (0/0)";
button.style.position = "fixed";
button.style.bottom = "10px";
button.style.left = "10px";
button.style.zIndex = "9999";
button.style.padding = "10px";
button.style.backgroundColor = "blue";
button.style.color = "white";
button.style.border = "none";
button.style.borderRadius = "5px";
button.style.cursor = "pointer";
document.body.appendChild(button);
const sortButton = document.createElement("button");
sortButton.innerText = "Sort by Price";
sortButton.style.position = "fixed";
sortButton.style.bottom = "50px";
sortButton.style.left = "10px";
sortButton.style.zIndex = "9999";
sortButton.style.padding = "10px";
sortButton.style.backgroundColor = "green";
sortButton.style.color = "white";
sortButton.style.border = "none";
sortButton.style.borderRadius = "5px";
sortButton.style.cursor = "pointer";
document.body.appendChild(sortButton);
const MAX_PARALLEL_IFRAMES = 2;
let activeIframes = 0;
let globalIndex = 0;
let artistUrls = [];
let artworks = [];
let updatedCount = 0;
function updateButtonText() {
button.innerText = `Show Request Price (${updatedCount}/${artworks.length})`;
}
function waitForRequestPriceElement(wrapperDiv, iframe, artistUrl, artwork) {
iframe.addEventListener('load', () => {
let requestPriceElement = iframe.contentDocument.querySelector("p.sc-a5e65548-7");
if (requestPriceElement) {
const requestPrice = requestPriceElement.innerText;
console.log(
"######################## " +
artistUrl +
" ##############" +
requestPrice
);
const priceElement = document.createElement("div");
priceElement.classList.add("request-price");
priceElement.innerText = `Request Price: ${requestPrice}`;
priceElement.style.backgroundColor = "#f0f0f0";
priceElement.style.color = "#333";
priceElement.style.padding = "10px";
priceElement.style.marginBottom = "10px";
priceElement.style.border = "1px solid #ccc";
priceElement.style.borderRadius = "5px";
priceElement.style.fontSize = "14px";
priceElement.style.fontWeight = "bold";
priceElement.style.boxShadow = "0 2px 4px rgba(0, 0, 0, 0.1)";
priceElement.style.opacity = "0";
priceElement.style.transition = "opacity 0.5s ease-in-out";
artwork.insertBefore(priceElement, artwork.firstChild);
requestAnimationFrame(() => {
priceElement.style.opacity = "1";
});
updatedCount++;
updateButtonText();
} else {
console.log("Request price element not found, skipping...");
}
activeIframes--;
console.log("Active iframes after decrement: " + activeIframes);
processArtist();
// reload the iframe then remove the wrapper div
iframe.src = "about:blank";
wrapperDiv.innerHTML = "<iframe style='display: none;'></iframe>";
setTimeout(() => {
wrapperDiv.remove();
}, 1000);
});
}
function processArtist() {
if (globalIndex >= artistUrls.length) {
console.log("All artists processed");
return; // All artists processed
}
if (activeIframes >= MAX_PARALLEL_IFRAMES) {
console.log("Max parallel iframes reached, retrying...");
setTimeout(processArtist, 100); // Retry after 100ms
return;
}
activeIframes++;
console.log("Processing " + artistUrls[globalIndex]);
const artistUrl = artistUrls[globalIndex];
const artwork = artworks[globalIndex];
const wrapperDiv = document.createElement("div");
const iframe = document.createElement("iframe");
iframe.style.display = "none";
iframe.src = artistUrl + "/request";
console.log("Visiting " + iframe.src);
globalIndex++;
wrapperDiv.appendChild(iframe);
document.body.appendChild(wrapperDiv);
waitForRequestPriceElement(wrapperDiv, iframe, artistUrl, artwork);
}
function scrapeArtworks() {
// do a case by case check for different kind of css selectors for artworks
const selectors = ["li.PKpFw", "li.kFAPOq"];
let selector = null;
if (document.querySelector(selectors[0])) {
selector = selectors[0];
} else if (document.querySelector(selectors[1])) {
selector = selectors[1];
} else {
console.error("No artworks found");
return { artistUrls: [], artworks: [] };
}
const artworks = document.querySelectorAll(selector);
const artistUrls = [];
artworks.forEach((artwork) => {
// Check if the artwork already has the price element with the class "request-price"
const existingPriceElement = artwork.querySelector('.request-price');
if (existingPriceElement) {
return; // Skip this artwork if it already has the price
}
let selector = "a.sc-1rx6dmq-2";
if (document.querySelector("a.pPtWa")) {
selector = "a.pPtWa";
}
const artistLink = artwork.querySelector(selector);
const artistUrl = artistLink.href;
artistUrls.push(artistUrl);
});
return { artistUrls, artworks };
}
function getPrices() {
let scrapedData = scrapeArtworks();
artistUrls = scrapedData.artistUrls;
artworks = scrapedData.artworks;
updateButtonText(); // Update button text with initial counts
// Start processing up to MAX_PARALLEL_IFRAMES artists initially
for (let i = 0; i < MAX_PARALLEL_IFRAMES; i++) {
setTimeout(processArtist, 300 * i);
}
}
function sortArtworksByPrice() {
const artworksContainer = document.querySelector("ul.sc-e6de33c8-0");
const artworksArray = Array.from(document.querySelectorAll("li.sc-9111aad9-0"));
const sortedArtworks = artworksArray.sort((a, b) => {
const priceA = parseFloat(a.querySelector(".request-price").innerText.replace(/[^0-9.-]+/g, ""));
const priceB = parseFloat(b.querySelector(".request-price").innerText.replace(/[^0-9.-]+/g, ""));
return priceA - priceB;
});
sortedArtworks.forEach((artwork) => {
artworksContainer.appendChild(artwork);
});
}
button.addEventListener("click", getPrices);
sortButton.addEventListener("click", sortArtworksByPrice);
})();