Greasy Fork is available in English.
Bulk download Facebook album photos in full resolution, supports background downloading
当前为
// ==UserScript==
// @name Facebook Photos Bulk Downloader (Background Support)
// @namespace 麦克
// @version 2.1.2
// @description Bulk download Facebook album photos in full resolution, supports background downloading
// @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 = 10;
const isDebug = true;
let isDownloading = false;
let stopDownload = false;
// 防止页面自动刷新或导航导致下载中断
window.addEventListener('beforeunload', function (event) {
if (isDownloading) {
event.preventDefault();
event.returnValue = '';
}
});
// 监听 Facebook 异步导航并恢复下载
window.addEventListener('popstate', function () {
if (isDownloading) {
console.log('Page navigation detected, resuming download...');
setTimeout(batchDownload, 1000);
}
});
// 创建 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;
}
// 下载图片并确保完成后翻页
function downloadImage(imgUrl, callback) {
if (imgUrl) {
const filename = imgUrl.split('?')[0].split('/').pop();
console.log(`Downloading: ${filename}`);
GM_download({
url: imgUrl,
name: filename,
saveAs: false,
onload: callback, // 下载完成后翻页
onerror: callback, // 即使下载失败也继续下一张
});
} else {
console.error('Failed to fetch image URL.');
callback();
}
}
// 批量处理函数(支持后台运行)
function batchDownload() {
if (iter >= MAXITER || stopDownload) {
console.log('Download limit reached or stopped by user.');
GM_notification({
text: `Download completed: ${iter} photos`,
title: 'Facebook Bulk Downloader',
timeout: 5000
});
isDownloading = false;
return;
}
const imgUrl = getImageUrl();
if (imgUrl) {
downloadImage(imgUrl, () => {
iter++;
if (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
});
isDownloading = false;
}
});
} else {
console.error('Retry fetching image...');
setTimeout(() => {
if (!stopDownload) batchDownload();
}, 1000);
}
}
// 开始批量下载
function startBatchDownload() {
if (isDownloading) {
console.warn('Download already in progress.');
return;
}
iter = 0;
stopDownload = false;
MAXITER = parseInt(prompt("Enter the number of photos to download:", "10")) || 10;
console.log(`Starting download of ${MAXITER} photos...`);
isDownloading = true;
GM_notification({
text: 'Download started...',
title: 'Facebook Bulk Downloader',
timeout: 3000
});
batchDownload();
}
// 监听页面切换时继续执行
window.addEventListener('visibilitychange', function () {
if (document.visibilityState === 'hidden' && isDownloading) {
console.log('Running in the background...');
} else if (document.visibilityState === 'visible' && isDownloading) {
console.log('Resuming download...');
}
});
// 用户随时可停止下载
document.addEventListener('keydown', function (e) {
if (e.key === 'Escape' && isDownloading) {
stopDownload = true;
isDownloading = false;
console.log('Download stopped by user.');
GM_notification({
text: 'Download stopped by user.',
title: 'Facebook Bulk Downloader',
timeout: 3000
});
}
});