下载Pexels图片合集
当前为 
// ==UserScript==
// @name         Pexels合集下载器
// @namespace    Tampermonkey Scripts
// @version      1.0
// @description  下载Pexels图片合集
// @author       FOX
// @match        https://www.pexels.com/zh-cn/collections/*
// @match        https://www.pexels.com/collections/*
// @grant        GM_download
// @license      MIT
// ==/UserScript==
(function() {
    'use strict';
    let downloadedCount = 0;
    let totalImages = 0;
    let progressBarContainer, progressBarFill, progressText, progressTitle;
    function getCollectionTitle() {
        const collectionTitleElement = document.querySelector('.Text_text___5YSC.Text_size-h60__Rp_92.Text_size-h28-mobile__XHsPm.Text_weight-semibold__jKPqr.Text_color-midnight2C343E__UNUpO.spacing_noMargin__Q_PsJ.Text_center__mweKj');
        let collectionTitle = collectionTitleElement ? collectionTitleElement.textContent.trim() : 'Unknown_Collection';
        // 替换掉文件名中不允许的字符
        collectionTitle = collectionTitle.replace(/[\W_]+/g,"_");
        return collectionTitle;
    }
    function updateProgressText() {
    if (progressText) {
        progressText.textContent = `当前进度:${downloadedCount}/${totalImages}`;
        progressBarFill.style.width = totalImages > 0 ? `${(downloadedCount / totalImages) * 100}%` : '0%'; // 更新进度条宽度
        // 检查下载是否完成
        if (downloadedCount >= totalImages) {
            // 设置2秒后自动关闭进度条
            setTimeout(() => {
                if (progressBarContainer && progressBarContainer.parentNode) {
                    progressBarContainer.parentNode.removeChild(progressBarContainer);
                }
            }, 2000); // 2秒后执行
        }
    }
}
    function downloadImage(url, name) {
        GM_download({
            url: url,
            name: name,
            onerror: function(error) {
                console.error(`Download failed:`, error);
                downloadedCount++;
                updateProgressText();
            },
            ontimeout: function() {
                console.error(`Download timed out:`, url);
                downloadedCount++;
                updateProgressText();
            },
            onload: function() {
                downloadedCount++;
                updateProgressText();
            }
        });
    }
    function getImageUrls() {
        const downloadButtons = document.querySelectorAll('.Button_button__L4pRn.spacing_noMargin__Q_PsJ.spacing_pr20___fNFe.spacing_pl20__9AOLh.DownloadButton_downloadButton__aqAsr.DownloadButton_fullButtonOnDesktop__mofT7.Button_clickable__WBdod.Button_white__snM9f.Link_link__mTUkz.spacing_noMargin__Q_PsJ');
        totalImages = downloadButtons.length;
        return Array.from(downloadButtons).map(button => {
            const thumbUrl = button.getAttribute('href');
            if (thumbUrl) {
                const photoIdMatch = thumbUrl.match(/photo-(\d+)/i);
                if (photoIdMatch && photoIdMatch[1]) {
                    return `https://images.pexels.com/photos/${photoIdMatch[1]}/pexels-photo-${photoIdMatch[1]}.jpeg`;
                }
            }
            return null;
        }).filter(url => url !== null);
    }
      function startDownloadProcess() {
        // 确保所有图片加载完毕后再开始下载
        autoScroll(() => {
            const imageUrls = getImageUrls();
            totalImages = imageUrls.length;
            updateProgressText();
            const collectionName = getCollectionTitle(); // 获取合集名称
            imageUrls.forEach((url, index) => {
                // 包含合集名称在文件名中
                setTimeout(() => downloadImage(url, `${collectionName}-${index + 1}.jpg`), index * 1000);
            });
        });
    }
function autoScroll(callback) {
    const intervalDelay = 350;
    const pauseDuration = 2000;
    const scrollIncrement = 100; // 每次循环时增加的额外滚动量
    let lastScrollHeight = 0;
    let sameScrollCounter = 0; // 计数器,用于跳过因内容加载导致的滚动高度不变
    let incrementalScrollDistance = window.innerHeight; // 开始时等于一个窗口的高度
    const scrollInterval = setInterval(() => {
        const currentScrollHeight = document.documentElement.scrollHeight;
        window.scrollBy(0, incrementalScrollDistance);
        if (currentScrollHeight === lastScrollHeight) {
            sameScrollCounter++;
        } else {
            sameScrollCounter = 0; // 如果检测到滚动高度改变,重置计数器
            incrementalScrollDistance += scrollIncrement; // 增加滚动距离
        }
        if (sameScrollCounter >= 3) { // 如果连续3次滚动高度未改变,则认为已到达底部
            clearInterval(scrollInterval);
            setTimeout(() => {
                window.scrollTo(0, 0); // 返回顶部
                if (typeof callback === "function") {
                    callback();
                }
            }, pauseDuration);
        }
        lastScrollHeight = currentScrollHeight; // 更新最后的滚动高度
    }, intervalDelay);
}
    // 添加下载按钮
    function addProgressBar() {
        progressBarContainer = document.createElement('div');
        Object.assign(progressBarContainer.style, {
            position: 'fixed',
            bottom: '50px', // 距离底部的像素
            right: '5px', // 距离右侧的像素
            backgroundColor: 'rgba(0,125,250,0.7)', // 0.7的半透明色
            borderRadius: '10px',
            padding: '10px',
            width: '480px', // 进度条宽度
            height: '65px', // 进度条高度
            zIndex: '9999',
            boxShadow: '0 2px 4px rgba(0,0,0,0.2)',
            color: 'white', // 进度条文字颜色
            fontFamily: 'Arial, sans-serif',
            fontSize: '13px',
            lineHeight: '1.4'
        });
        const collectionTitleElement = document.querySelector('.Text_text___5YSC.Text_size-h60__Rp_92.Text_size-h28-mobile__XHsPm.Text_weight-semibold__jKPqr.Text_color-midnight2C343E__UNUpO.spacing_noMargin__Q_PsJ.Text_center__mweKj');
        const collectionTitle = collectionTitleElement ? collectionTitleElement.textContent.trim() : 'Unknown Collection';
        progressTitle = document.createElement('div');
        progressTitle.textContent = `正在下载合集:${collectionTitle}`;
        progressBarContainer.appendChild(progressTitle);
        progressText = document.createElement('div');
        progressText.textContent = '当前进度:0%';
        progressBarContainer.appendChild(progressText);
        const progressBarBackground = document.createElement('div');
        Object.assign(progressBarBackground.style, {
            width: '100%',
            backgroundColor: 'rgba(255,255,255,0.2)', //进度槽背景色
            borderRadius: '5px',
            margin: '5px 0'
        });
        progressBarContainer.appendChild(progressBarBackground);
        progressBarFill = document.createElement('div');
        Object.assign(progressBarFill.style, {
            height: '5px',
            width: '0%',
            backgroundColor: '#1afff7', // 进度线条色
            borderRadius: '5px',
            transition: 'width 0.5s ease-in-out'
        });
        progressBarBackground.appendChild(progressBarFill);
        document.body.appendChild(progressBarContainer);
    }
    function addDownloadButton() {
        const userInfoElement = document.querySelector('.Page_users__AU7hn.Flex_flex__wNlof.spacing_noMargin__Q_PsJ.spacing_mmb30__p12Ri.spacing_tmb30__xG92k');
        if (userInfoElement) {
            const downloadBtnContainer = document.createElement('div');
            downloadBtnContainer.style.display = 'inline-flex';
            downloadBtnContainer.style.alignItems = 'center';
            downloadBtnContainer.style.marginLeft = '10px';
            const downloadBtn = document.createElement('button');
            downloadBtn.textContent = '下载合集';
            downloadBtn.id = 'downloadBtn';
            Object.assign(downloadBtn.style, {
                fontSize: '16px',
                color: 'white',
                background: '#05a081',
                border: 'none',
                borderRadius: '30px',
                height: '45px',
                width: '100px',
                cursor: 'pointer',
                padding: '8px 15px',
                margin: '0 10px'
            });
            downloadBtnContainer.appendChild(downloadBtn);
            userInfoElement.parentNode.insertBefore(downloadBtnContainer, userInfoElement.nextSibling);
            downloadBtn.addEventListener('click', () => {
                addProgressBar();
                startDownloadProcess();
            });
        } else {
            console.error('User information element not found.');
        }
    }
    function checkAndInsertButton() {
        if (!document.getElementById('downloadBtn')) {
            addDownloadButton();
        }
    }
    setInterval(checkAndInsertButton, 1000);
})();