Greasy Fork

Greasy Fork is available in English.

获取竞价数据(shop.48.cn)

自动提取 Cookie 并请求竞价数据接口

当前为 2025-06-27 提交的版本,查看 最新版本

// ==UserScript==
// @name         获取竞价数据(shop.48.cn)
// @namespace    http://tampermonkey.net/
// @version      0.4
// @description  自动提取 Cookie 并请求竞价数据接口
// @author       GPT
// @match        https://shop.48.cn/pai/item/*
// @grant        none
// @license      MIT
// ==/UserScript==

(function () {
    'use strict';

    // ✅ 获取 URL 中的商品 ID
    function getItemIdFromURL() {
        const match = window.location.href.match(/item\/(\d+)/);
        return match ? match[1] : null;
    }

    // ✅ 构建 POST 参数
    function buildParams(itemId) {
        return new URLSearchParams({
            id: itemId,
            numPerPage: 100,
            pageNum: 0,
            r: Math.random().toString()
        });
    }

    // ✅ 获取指定 Cookie 值
    function getCookie(name) {
        const cookies = document.cookie.split("; ");
        for (const cookie of cookies) {
            const [key, value] = cookie.split("=");
            if (key === name) return value;
        }
        return null;
    }

    // ✅ 构建 Cookie 请求头
    function buildCookieHeader() {
        const cookieNames = [
            "Hm_lvt_f32737cfa62ed971bb3185792d3204eb",
            "route",
            ".AspNet.ApplicationCookie",
            "HMACCOUNT",
            "__RequestVerificationToken",
            "Hm_lpvt_f32737cfa62ed971bb3185792d3204eb"
        ];

        const cookieMap = {};
        cookieNames.forEach(name => {
            const value = getCookie(name);
            if (value) {
                cookieMap[name] = value;
            } else {
                console.warn(`未找到 cookie: ${name}`);
            }
        });

        if (Object.keys(cookieMap).length === 0) return null;

        return Object.entries(cookieMap)
            .map(([k, v]) => `${k}=${v}`)
            .join("; ");
    }

    // ✅ 发起 POST 请求
    async function fetchBids(params, cookieHeader) {
        const response = await fetch("https://shop.48.cn/pai/GetShowBids", {
            method: "POST",
            headers: {
                "Content-Type": "application/x-www-form-urlencoded",
                "Cookie": cookieHeader
            },
            body: params
        });

        if (!response.ok) {
            throw new Error(`请求失败,状态码 ${response.status}`);
        }

        return await response.json();
    }
    
    

    // 创建按钮
    function createFetchButton() {
        // 包裹容器
        const container = document.createElement("div");
        container.id = "bid-fetch-container";
        Object.assign(container.style, {
            position: "fixed",
            top: "80px",
            right: "20px",
            zIndex: "9999",
            display: "flex",
            flexDirection: "column",
            alignItems: "center",
            gap: "8px",
            backgroundColor: "white",
            padding: "12px",
            borderRadius: "10px",
            boxShadow: "0 0 10px rgba(0,0,0,0.2)"
        });
    
        // 输入框
        const input = document.createElement("input");
        input.type = "number";
        input.id = "positionInput";
        input.placeholder = "输入第几位";
        input.min = "1";
        Object.assign(input.style, {
            padding: "6px",
            width: "140px",
            fontSize: "14px",
            borderRadius: "6px",
            border: "1px solid #ccc"
        });
    
        // 按钮
        const btn = document.createElement("button");
        btn.innerText = "📥 获取竞价数据";
        btn.id = "fetchBidsBtn";
        Object.assign(btn.style, {
            padding: "10px 16px",
            fontSize: "16px",
            backgroundColor: "#4CAF50",
            color: "white",
            border: "none",
            borderRadius: "8px",
            cursor: "pointer"
        });
    
        // 显示框
        const output = document.createElement("div");
        output.id = "bidAmtOutput";
        output.innerText = "等待结果...";
        Object.assign(output.style, {
            marginTop: "4px",
            fontSize: "14px",
            color: "#333"
        });
    
        // 按钮点击逻辑
        btn.addEventListener("click", async () => {
            btn.innerText = "⏳ 正在获取...";
            btn.disabled = true;
    
            try {
                const index = parseInt(input.value.trim());
                if (isNaN(index) || index < 1) {
                    output.innerText = "请输入有效的位置(>=1)";
                    return;
                }
    
                const itemId = getItemIdFromURL();
                const params = buildParams(itemId);
                const cookieHeader = buildCookieHeader();
    
                if (!cookieHeader) {
                    output.innerText = "未获取到 cookie";
                    return;
                }
    
                const data = await fetchBids(params, cookieHeader);
                const validList = data.list.filter(entry => entry.auction_status === 1);
    
                const target = validList[index - 1];
                const bidAmt = target ? target.bid_amt : 0;
                output.innerText = `第 ${index} 位出价金额:¥${bidAmt}`;
    
            } catch (err) {
                console.error(err);
                output.innerText = "请求出错,请查看控制台";
            } finally {
                btn.innerText = "📥 获取竞价数据";
                btn.disabled = false;
            }
        });
    
        // 添加到容器
        container.appendChild(input);
        container.appendChild(btn);
        container.appendChild(output);
        document.body.appendChild(container);
    }


    // ✅ 主执行函数
    async function run() {
        const itemId = getItemIdFromURL();
        if (!itemId) {
            console.warn("未找到商品 ID");
            return;
        }

        const params = buildParams(itemId);
        const cookieHeader = buildCookieHeader();

        if (!cookieHeader) {
            console.error("未能获取必要的 cookie,可能是未登录");
            return;
        }

        try {
            const data = await fetchBids(params, cookieHeader);
            console.log("竞价数据:", data);
        } catch (error) {
            console.error("竞价请求失败:", error);
        }
    }
    
    // 主入口
    function init() {
        createFetchButton(); // 添加按钮
    }
    
    // ✅ 启动脚本
    init();

})();