Skip to content

Instantly share code, notes, and snippets.

@abraxas86
Created September 4, 2024 18:32
Show Gist options
  • Save abraxas86/f02dcbf0632c3c0e819d1aad17148dbf to your computer and use it in GitHub Desktop.
Save abraxas86/f02dcbf0632c3c0e819d1aad17148dbf to your computer and use it in GitHub Desktop.
Facebook Bulk Image Downloader
// ==UserScript==
// @name Facebook meme dump yanker
// @namespace http://tampermonkey.net/
// @version 1.1
// @description Downloads all the webp images from a Facebook mobile list as a .zip (does not handle lazy-loading, so you need to scroll to the bottom to get the whole collection)
// @author Abraxas86
// @match *://*.facebook.com/*
// @grant none
// @require https://cdnjs.cloudflare.com/ajax/libs/jszip/3.7.1/jszip.min.js
// @require https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/2.0.5/FileSaver.min.js
// ==/UserScript==
(function() {
'use strict';
// Check if the user-agent corresponds to a mobile browser
const isMobile = /Mobi|Android|iPhone|iPad/i.test(navigator.userAgent);
if (isMobile) {
// Create a button and add it to the top of the page
const button = document.createElement('button');
button.textContent = 'DANK MEMES PLX';
button.style.position = 'fixed';
button.style.top = '10px';
button.style.right = '10px';
button.style.zIndex = '1000';
button.style.padding = '10px 20px';
button.style.backgroundColor = '#007bff';
button.style.color = '#FFF';
button.style.border = 'none';
button.style.borderRadius = '5px';
button.style.cursor = 'pointer';
button.addEventListener('click', async () => {
const script = document.createElement('script');
script.src = 'https://cdnjs.cloudflare.com/ajax/libs/jszip/3.7.1/jszip.min.js';
script.onload = () => {
const fileSaverScript = document.createElement('script');
fileSaverScript.src = 'https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/2.0.5/FileSaver.min.js';
fileSaverScript.onload = async () => {
// Fetch and ZIP .webp images
const imgElements = document.querySelectorAll('img');
const zip = new JSZip();
console.log('Starting to fetch .webp images...');
const downloadPromises = Array.from(imgElements).map(async (img, index) => {
const src = img.getAttribute('src');
try {
const response = await fetch(src);
if (response.ok) {
const contentType = response.headers.get('content-type');
if (contentType && contentType.includes('image/webp')) {
const blob = await response.blob();
zip.file(`image${index + 1}.webp`, blob);
console.log(`Added image${index + 1}.webp to ZIP.`);
} else {
console.log(`Skipping non-webp image ${src}`);
}
} else {
console.error(`Failed to fetch ${src}`);
}
} catch (error) {
console.error(`Error fetching ${src}:`, error);
}
});
await Promise.all(downloadPromises);
console.log('Generating ZIP file...');
zip.generateAsync({ type: 'blob' })
.then(function (content) {
saveAs(content, 'webp_images.zip');
console.log('ZIP file saved as webp_images.zip');
})
.catch(function (error) {
console.error('Error generating ZIP file:', error);
});
};
document.head.appendChild(fileSaverScript);
};
document.head.appendChild(script);
});
document.body.appendChild(button);
}
})();
@abraxas86
Copy link
Author

abraxas86 commented Sep 4, 2024

How To Use

This is a userscript that will require Tampermonkey (Chrome plugin) to work.

Once installed, you will need to switch your user agent to a mobile client:

  1. Hit F12 to open the Developer tools
  2. Go to "Network Conditions" (you may need to click on the >> to see that option)
  3. Uncheck "Use browser default"
  4. CHange the browser to Chrome -- Android Mobile (others mobile options should work too, but I never tested them)
  5. Refresh the page - it should now load in the mobile layout.

Now, load the full gallery you want to rip and scroll down to the very bottom of the page to ensure all of the images have been loaded) and then click on the "DANK MEMES PLX" button at the top-right.

Why though?

At least one friend of mine posts some pretty good meme dump frequently on Facebook. They're great, but Facebook is terribly inefficient when it comes to browsing these things.

I noticed that when you view the pages on Mobile, though, they open as a long list instead of the single-pic-at-a-time method that the desktop site uses.

This script just yanks all the images and convenientlly zips them and downloads the zip archive. Extract the zip and enjoy!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment