-
Star
(157)
You must be signed in to star a gist -
Fork
(19)
You must be signed in to fork a gist
-
-
Save bryant988/9510cff838d86dcefa3b9ea3835b8552 to your computer and use it in GitHub Desktop.
| /** | |
| * NOTE: this specifically works if the house is for sale since it renders differently. | |
| * This will download the highest resolution available per image. | |
| */ | |
| /** | |
| * STEP 1: Make sure to *SCROLL* through all images so they appear on DOM. | |
| * No need to click any images. | |
| */ | |
| /** | |
| * STEP 2: Open Dev Tools Console. | |
| * Copy and paste code below | |
| */ | |
| const script = document.createElement('script'); | |
| script.src = "https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"; | |
| script.onload = () => { | |
| $ = jQuery.noConflict(); | |
| const imageList = $('ul.media-stream li picture source[type="image/jpeg"]').map(function () { | |
| const srcset = $(this).attr('srcset').split(' '); // get highest res urls for each image | |
| return srcset[srcset.length - 2] | |
| }).toArray(); | |
| const delay = ms => new Promise(res => setTimeout(res, ms)); // promise delay | |
| // get all image blobs in parallel first before downloading for proper batching | |
| Promise.all(imageList.map(i => fetch(i)) | |
| ).then(responses => | |
| Promise.all(responses.map(res => res.blob())) | |
| ).then(async (blobs) => { | |
| for (let i = 0; i < blobs.length; i++) { | |
| if (i % 10 === 0) { | |
| console.log('1 sec delay...'); | |
| await delay(1000); | |
| } | |
| var a = document.createElement('a'); | |
| a.style = "display: none"; | |
| console.log(i); | |
| var url = window.URL.createObjectURL(blobs[i]); | |
| a.href = url; | |
| a.download = i + ''; | |
| document.body.appendChild(a); | |
| a.click(); | |
| setTimeout(() => { | |
| window.URL.revokeObjectURL(url); | |
| }, 100); | |
| } | |
| }); | |
| }; | |
| document.getElementsByTagName('head')[0].appendChild(script); |
@SabinVI this worked on Edge. Thank you!
@SabinVI this worked on Chrome for a "for Sale" house. Thank you!
It is mid-October 2025 and I'm running Firefox current version (143.0.4 64-bit for ARM64). I was happily surprised to find that the script works perfectly. I used the version @SabinVI posted three weeks ago. Below is the exact procedure I followed:
- Navigated to the listing page for the house, whose status is 'under contract' (note I was on the main listing page, not the lightbox)
- Scrolled to the very bottom of the page without jumping, so as to load every picture that is available
- In Firefox, select the 'Tools' menu => 'Browser Tools' => 'Web Developer Tools'
- Within the Dev Tools popup that opens there are several tabs across the top. Select the 'Console' tab. Hit the Trash icon to clear the workspace (this won't harm anything)
- Type 'allow pasting' into the dialog
- Paste the @SabinVI code into the dialog and hit 'return'
- Wait a second while the magic happens. You may see some error lines and 'Found Image URLs'.
- After about 5 seconds, Firefox presented me with the 'save file' option. The resulting download was a .zip containing all of the pictures from the listing in high-resolution (~225kb avg in my case).
I was happy to find the script made it easy to archive the images - thanks to everyone who took the time to advance and refine this helpful bit of code. I hope my pedantic write-up is of use to fellow Firefox users who may be equally unfamiliar with using .js in console.
Confirming that @SabinVI 's script and @reworkednyc worked perfectly on Brave v1.85.120 on 1/9/2026. Thanks, folks!
This is a little bit of a smaller script that works if you open all images and scroll to the bottom, then run the script.
Works in active listings and sold listings as long as it has a modal with all of the pictures.
// === Zillow Vertical Media Wall Downloader ===
(async () => {
// Scroll the wall so every lazy-loaded photo appears
const wall = document.querySelector('ul[aria-label="media wall images"]');
if (!wall) {
alert("Couldn’t find the photo wall. Open the full gallery and scroll through all images first.");
return;
}
wall.scrollIntoView({ behavior: "smooth" });
await new Promise(r => setTimeout(r, 1200));
// Get every JPEG source and pick the highest-resolution URL
const sources = wall.querySelectorAll('picture source[type="image/jpeg"]');
const urls = Array.from(sources).map(source => {
const srcset = source.getAttribute('srcset');
const parts = srcset.split(',').map(p => p.trim());
const highest = parts[parts.length - 1].split(' ')[0]; // last entry = biggest size
return highest;
}).filter(Boolean);
if (urls.length === 0) {
alert("No photos found. Make sure you scrolled through the entire gallery.");
return;
}
console.log(`Found ${urls.length} photos. Starting download...`);
// Fetch all images as blobs (parallel, but browser is fine with it)
const blobs = await Promise.all(
urls.map(url => fetch(url).then(r => r.blob()))
);
// Download one by one with a small delay to keep Chrome happy
for (let i = 0; i < blobs.length; i++) {
const filename = `zillow-photo-${String(i + 1).padStart(3, '0')}.jpg`;
const blobUrl = URL.createObjectURL(blobs[i]);
const a = document.createElement('a');
a.href = blobUrl;
a.download = filename;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(blobUrl);
console.log(`✅ Downloaded ${filename}`);
await new Promise(r => setTimeout(r, 350)); // gentle on the browser
}
console.log(`🎉 All ${urls.length} photos saved!`);
})();
Just used it and it worked perfectly, thanks!