Pixieset Bulk Image Downloader

Automatically download all images from Pixieset gallery with auto-scroll

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         Pixieset Bulk Image Downloader
// @namespace    http://tampermonkey.net/
// @version      2.0
// @description  Automatically download all images from Pixieset gallery with auto-scroll
// @author       sharmanhall
// @match        https://*.pixieset.com/*
// @grant        none
// @license      MIT 
// ==/UserScript==

(function() {
    'use strict';

    // Configuration
    const DELAY_BETWEEN_DOWNLOADS = 2000; // 2 seconds between each download
    const SCROLL_DELAY = 1000; // 1 second between scrolls
    let currentIndex = 0;
    let downloadButtons = [];
    let isRunning = false;
    let isScrolling = false;

    // Create control panel
    function createControlPanel() {
        const panel = document.createElement('div');
        panel.id = 'pixieset-download-panel';
        panel.style.cssText = `
            position: fixed;
            top: 20px;
            right: 20px;
            background: #fff;
            border: 2px solid #333;
            border-radius: 8px;
            padding: 15px;
            z-index: 10000;
            box-shadow: 0 4px 6px rgba(0,0,0,0.3);
            font-family: Arial, sans-serif;
            min-width: 280px;
        `;

        panel.innerHTML = `
            <h3 style="margin: 0 0 10px 0; font-size: 16px;">Pixieset Downloader</h3>
            <div style="margin-bottom: 10px;">
                <strong>Total Images:</strong> <span id="total-images">0</span>
            </div>
            <div style="margin-bottom: 10px;">
                <strong>Progress:</strong> <span id="current-image">0</span> / <span id="total-images-2">0</span>
            </div>
            <div style="margin-bottom: 10px;">
                <div style="background: #e0e0e0; border-radius: 4px; height: 20px; overflow: hidden;">
                    <div id="progress-bar" style="background: #4CAF50; height: 100%; width: 0%; transition: width 0.3s;"></div>
                </div>
            </div>
            <button id="auto-scroll-btn" style="
                width: 100%;
                padding: 10px;
                background: #2196F3;
                color: white;
                border: none;
                border-radius: 4px;
                cursor: pointer;
                font-size: 14px;
                margin-bottom: 5px;
            ">Auto-Scroll to Load All</button>
            <button id="refresh-btn" style="
                width: 100%;
                padding: 10px;
                background: #FF9800;
                color: white;
                border: none;
                border-radius: 4px;
                cursor: pointer;
                font-size: 14px;
                margin-bottom: 5px;
            ">Refresh Image List</button>
            <button id="start-download-btn" style="
                width: 100%;
                padding: 10px;
                background: #4CAF50;
                color: white;
                border: none;
                border-radius: 4px;
                cursor: pointer;
                font-size: 14px;
                margin-bottom: 5px;
            ">Start Download</button>
            <button id="stop-download-btn" style="
                width: 100%;
                padding: 10px;
                background: #f44336;
                color: white;
                border: none;
                border-radius: 4px;
                cursor: pointer;
                font-size: 14px;
                display: none;
            ">Stop</button>
            <div id="status-message" style="margin-top: 10px; font-size: 12px; color: #666; line-height: 1.4;"></div>
        `;

        document.body.appendChild(panel);
        return panel;
    }

    // Refresh/scan for download buttons
    function refreshImageList() {
        const previousCount = downloadButtons.length;
        downloadButtons = Array.from(document.querySelectorAll('.image-download-btn'));
        
        document.getElementById('total-images').textContent = downloadButtons.length;
        document.getElementById('total-images-2').textContent = downloadButtons.length;
        
        const newImages = downloadButtons.length - previousCount;
        if (newImages > 0) {
            document.getElementById('status-message').textContent = 
                `Found ${newImages} new images! Total: ${downloadButtons.length}`;
        } else if (previousCount === 0) {
            document.getElementById('status-message').textContent = 
                `Found ${downloadButtons.length} images`;
        } else {
            document.getElementById('status-message').textContent = 
                `No new images found. Total: ${downloadButtons.length}`;
        }
        
        return downloadButtons.length;
    }

    // Auto-scroll to load all images
    function autoScrollToLoadAll() {
        if (isScrolling) {
            document.getElementById('status-message').textContent = 'Already scrolling...';
            return;
        }

        isScrolling = true;
        document.getElementById('auto-scroll-btn').disabled = true;
        document.getElementById('auto-scroll-btn').style.opacity = '0.5';
        document.getElementById('status-message').textContent = 'Auto-scrolling to load images...';

        let lastHeight = document.body.scrollHeight;
        let scrollAttempts = 0;
        const maxScrollAttempts = 100; // Prevent infinite loop

        function scrollStep() {
            // Scroll to bottom
            window.scrollTo(0, document.body.scrollHeight);
            
            setTimeout(() => {
                const newHeight = document.body.scrollHeight;
                const currentImages = document.querySelectorAll('.image-download-btn').length;
                
                document.getElementById('status-message').textContent = 
                    `Loading images... Found: ${currentImages}`;
                
                scrollAttempts++;
                
                // Check if we've reached the bottom (no new content loaded)
                if (newHeight === lastHeight || scrollAttempts >= maxScrollAttempts) {
                    // Scroll back to top
                    window.scrollTo(0, 0);
                    
                    // Refresh the image list
                    setTimeout(() => {
                        refreshImageList();
                        isScrolling = false;
                        document.getElementById('auto-scroll-btn').disabled = false;
                        document.getElementById('auto-scroll-btn').style.opacity = '1';
                        document.getElementById('status-message').textContent = 
                            `Loading complete! Found ${currentImages} images. Ready to download.`;
                    }, 500);
                } else {
                    lastHeight = newHeight;
                    scrollStep();
                }
            }, SCROLL_DELAY);
        }

        // Start scrolling
        scrollStep();
    }

    // Update progress display
    function updateProgress() {
        document.getElementById('current-image').textContent = currentIndex;
        document.getElementById('progress-bar').style.width = 
            ((currentIndex / downloadButtons.length) * 100) + '%';
    }

    // Download images sequentially
    function downloadImages() {
        if (currentIndex >= downloadButtons.length || !isRunning) {
            document.getElementById('status-message').textContent = 
                currentIndex >= downloadButtons.length ? 'All downloads complete!' : 'Download stopped';
            document.getElementById('start-download-btn').style.display = 'block';
            document.getElementById('stop-download-btn').style.display = 'none';
            document.getElementById('auto-scroll-btn').disabled = false;
            document.getElementById('refresh-btn').disabled = false;
            document.getElementById('auto-scroll-btn').style.opacity = '1';
            document.getElementById('refresh-btn').style.opacity = '1';
            isRunning = false;
            return;
        }

        const button = downloadButtons[currentIndex];
        document.getElementById('status-message').textContent = 
            `Downloading image ${currentIndex + 1} of ${downloadButtons.length}...`;
        
        // Scroll the button into view
        button.scrollIntoView({ behavior: 'smooth', block: 'center' });
        
        // Click the download button
        button.click();
        
        currentIndex++;
        updateProgress();

        // Schedule next download
        setTimeout(downloadImages, DELAY_BETWEEN_DOWNLOADS);
    }

    // Initialize the script
    function init() {
        // Wait for page to load
        setTimeout(() => {
            // Create control panel
            const panel = createControlPanel();
            
            // Initial scan
            refreshImageList();

            // Auto-scroll button handler
            document.getElementById('auto-scroll-btn').addEventListener('click', () => {
                autoScrollToLoadAll();
            });

            // Refresh button handler
            document.getElementById('refresh-btn').addEventListener('click', () => {
                refreshImageList();
            });

            // Start button handler
            document.getElementById('start-download-btn').addEventListener('click', () => {
                if (downloadButtons.length === 0) {
                    alert('No images found! Try "Auto-Scroll to Load All" first.');
                    return;
                }
                
                isRunning = true;
                currentIndex = 0;
                updateProgress();
                document.getElementById('start-download-btn').style.display = 'none';
                document.getElementById('stop-download-btn').style.display = 'block';
                document.getElementById('auto-scroll-btn').disabled = true;
                document.getElementById('refresh-btn').disabled = true;
                document.getElementById('auto-scroll-btn').style.opacity = '0.5';
                document.getElementById('refresh-btn').style.opacity = '0.5';
                document.getElementById('status-message').textContent = 'Starting download...';
                downloadImages();
            });

            // Stop button handler
            document.getElementById('stop-download-btn').addEventListener('click', () => {
                isRunning = false;
                document.getElementById('start-download-btn').style.display = 'block';
                document.getElementById('stop-download-btn').style.display = 'none';
                document.getElementById('auto-scroll-btn').disabled = false;
                document.getElementById('refresh-btn').disabled = false;
                document.getElementById('auto-scroll-btn').style.opacity = '1';
                document.getElementById('refresh-btn').style.opacity = '1';
                document.getElementById('status-message').textContent = 'Download stopped';
            });

        }, 2000); // Wait 2 seconds for page to fully load
    }

    // Run when page is ready
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', init);
    } else {
        init();
    }
})();