Greasy Fork

来自缓存

Greasy Fork is available in English.

Facebook 相册一键下载

Bulk download Facebook album photos in full resolution with background support and auto-refresh prevention.

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         Facebook 相册一键下载
// @namespace    麦克
// @version      2.1.6
// @description  Bulk download Facebook album photos in full resolution with background support and auto-refresh prevention.
// @author       麦克
// @match        https://www.facebook.com/*/photos/*
// @match        https://www.facebook.com/photo.php?*
// @match        https://www.facebook.com/photo?*
// @match        https://www.facebook.com/photo/*
// @grant        GM_download
// @grant        GM_notification
// @license      GPL-3.0-or-later
// ==/UserScript==

let iter = 0;
let MAXITER = 10000;
let stopDownload = false;

// 防止页面自动刷新
window.addEventListener('beforeunload', function (e) {
    e.preventDefault();
    e.returnValue = '';
});

// 创建 Fetch 按钮
(function () {
    const observer = new MutationObserver(() => {
        if (document.body && !document.querySelector('#fetch-button')) {
            let fetchBtn = document.createElement("div");
            fetchBtn.id = "fetch-button";
            fetchBtn.textContent = "⇩ Fetch Photos";
            fetchBtn.style.cssText = 'position:fixed;top:10px;right:10px;z-index:9999;padding:8px;background-color:#4caf50;color:white;border-radius:5px;cursor:pointer;';
            fetchBtn.onclick = startBatchDownload;
            document.body.appendChild(fetchBtn);
        }
    });
    observer.observe(document.body, { childList: true, subtree: true });
})();

// 获取当前图片 URL
function getImageUrl() {
    const imgElement = document.querySelector('img[src*="scontent"]');
    return imgElement ? imgElement.src : null;
}

// 点击“下一张”按钮
function clickNextImage() {
    const nextBtn = document.querySelector('div[aria-label="下一张"], div[aria-label="Next"]');
    if (nextBtn) {
        nextBtn.click();
        return true;
    } else {
        const complexNextBtn = document.querySelector('div[role="button"][tabindex="0"] div[style*="background-image"]');
        if (complexNextBtn) {
            complexNextBtn.click();
            return true;
        }
    }
    return false;
}

// 下载图片的异步函数
async function downloadImage(imgUrl) {
    return new Promise((resolve) => {
        if (imgUrl) {
            const filename = imgUrl.split('?')[0].split('/').pop();
            console.log(`Downloading: ${filename}`);
            GM_download({
                url: imgUrl,
                name: filename,
                saveAs: false,
                onload: () => resolve(true),
                onerror: () => resolve(false),
            });
        } else {
            console.error('Failed to fetch image URL.');
            resolve(false);
        }
    });
}

// 批量下载的递归函数
async function batchDownload() {
    if (iter >= MAXITER || stopDownload) {
        console.log('Download process completed or stopped.');
        GM_notification({
            text: `Download completed: ${iter} photos`,
            title: 'Facebook Bulk Downloader',
            timeout: 5000
        });
        return;
    }

    const imgUrl = getImageUrl();
    if (imgUrl) {
        const success = await downloadImage(imgUrl);
        iter++;
        if (success && clickNextImage()) {
            console.log(`Moving to image ${iter + 1}`);
            setTimeout(batchDownload, 1000); // 等待 1 秒后继续下载
        } else {
            console.log('No more images found or failed to click next.');
            GM_notification({
                text: `Download completed: ${iter} photos`,
                title: 'Facebook Bulk Downloader',
                timeout: 5000
            });
        }
    } else {
        console.error('Retry fetching image...');
        setTimeout(batchDownload, 1000);
    }
}

// 开始批量下载
function startBatchDownload() {
    iter = 0;
    stopDownload = false;
    const input = parseInt(prompt("Enter the number of photos to download:", "10000"));
    MAXITER = isNaN(input) ? 10000 : input;
    console.log(`Starting download of ${MAXITER} photos...`);
    GM_notification({
        text: 'Download started...',
        title: 'Facebook Bulk Downloader',
        timeout: 3000
    });
    batchDownload();
}

// 用户按下 Escape 键可随时停止下载
document.addEventListener('keydown', function (e) {
    if (e.key === 'Escape') {
        stopDownload = true;
        console.log('Download stopped by user.');
        GM_notification({
            text: 'Download stopped by user.',
            title: 'Facebook Bulk Downloader',
            timeout: 3000
        });
    }
});

// 监听页面刷新和导航更改,防止下载中断
window.addEventListener('visibilitychange', function () {
    if (document.visibilityState === 'hidden' && !stopDownload) {
        console.log('Attempting to prevent tab from unloading...');
        window.stop(); // 阻止页面刷新或导航
    }
});