🏠 Home 

Facebook 相册一键下载

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

// ==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(); // 阻止页面刷新或导航
}
});