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);
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址