Skip to content

Instantly share code, notes, and snippets.

@bryant988
Last active April 28, 2024 02:28
Show Gist options
  • Save bryant988/9510cff838d86dcefa3b9ea3835b8552 to your computer and use it in GitHub Desktop.
Save bryant988/9510cff838d86dcefa3b9ea3835b8552 to your computer and use it in GitHub Desktop.
Zillow Image Downloader
/**
* 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);
@T150
Copy link

T150 commented Dec 28, 2023

Also, props to raghucbz November 18 2022 wisdom in this GitHub thread, for how to batch convert webp to jpg. That website works great too. TY!

@frederickjansen
Copy link

@T150 Can you share a listing it doesn't work on? I just tested it on an open listing and no problems downloading the images.

@knowyourrivals
Copy link

This worked for me, but only after clicking to load the first image in the lightbox, and then advancing through each photo individually using the arrow key. Once I was on the last image, I then ran the script through the console, and was successful. Using: Mac Chrome Version 120.0.6099.199 (Official Build) (arm64)

const script = document.createElement("script");
script.src = "https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js";

script.onload = async () => {
  $ = jQuery.noConflict();

  const delay = (ms) => new Promise((res) => setTimeout(res, ms)); // promise delay

  // can't map since there isn't a list, so just push as we find more.
  const imageList = [];

  // while there is a next button
  while (
    $(".photo-carousel-icon-wrapper .icon-arrow-right").length ||
    $(".photo-carousel-icon-wrapper .icon-reload").length
  ) {
    // Wait a little to make sure the next image source is loaded. If you get an error, increasing the timeout might help
    await delay(200);
    // Last image, break out of loop
    if ($(".photo-carousel-icon-wrapper .icon-reload").length) {
      break;
    }
    const srcs = $('.hdp-gallery-image-content .image:visible source[type="image/jpeg"]').attr("srcset").split(" ");
    const src = srcs[srcs.length - 2];
    // just in case... let make sure the src is not already in the list.
    if (imageList.indexOf(src) === -1) {
      imageList.push(src);
    }

    // go to the next slide
    $(".photo-carousel-icon-wrapper .icon-arrow-right").parent().click();
  }

  // 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);
        }

        let a = document.createElement("a");
        a.style = "display: none";
        console.log(i);

        let 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);

@T150
Copy link

T150 commented Jan 9, 2024

@frederickjansen @knowyourrivals Okay, working as advertised. Perhaps I was not drilling down enough into the Lightbox (pictures only) feature of the Zillow webpages (so I followed the process @knowyourrivals described). And all looks good now. Thanks for responding and motivating me to keep trying. Cheers!

@medosf
Copy link

medosf commented Mar 19, 2024

here is the new script to download the highest resolution images, the issue with opening the list view it will show a highest resolution of 380 x 280. in the code below i replaced the the image url with uncropped_scaled_within_1344_1008.jpg which is the highest resolution available

const highRes = srcset[0].replace("-cc_ft_192.jpg","-uncropped_scaled_within_1344_1008.jpg")

use the same script and just replace imageList with this below code

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
const highRes = srcset[0].replace("-cc_ft_192.jpg","-uncropped_scaled_within_1344_1008.jpg")
return highRes
}).toArray();

@eek2022
Copy link

eek2022 commented Apr 1, 2024

April 2024 was able to get this to work! I had to individually go through each image, but if I stopped and did it on the last image I only got the final photo downloaded. When going back to the first image, the code went through all the images for me and began download. I had to agree on chrome to allow "multiple downloads." Thank you SO much for posting about this. Saved me so much time.

@wtcipher
Copy link

This does not work for me. I do not see any pop-up windows. Also, if the pictures are being downloaded, did the code mention where the pictures will be stored at?

@ANONDOTCDOT
Copy link

@medosf Which above script is this for?

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