Skip to content

Instantly share code, notes, and snippets.

@darinalleman
Last active March 30, 2024 20:29
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save darinalleman/b4cc60bed013cbd7a46b286640ea1c94 to your computer and use it in GitHub Desktop.
Save darinalleman/b4cc60bed013cbd7a46b286640ea1c94 to your computer and use it in GitHub Desktop.
Google Sheets Zillow Import Script
function writeZestimateToSheet() {
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheets = spreadsheet.getSheets();
var zillowSheet = sheets.find(sheet => sheet.getSheetName() == 'Zillow');
if (zillowSheet) {
var html = UrlFetchApp.fetch('https://www.zillow.com/homes/%%%%%%%%%_zpid/').getContentText();
const divRegex = /(<div class="zestimate-value">)(\$)(\d{1,3})(,\d{3})*(<\/div>)/g;
const moneyRegex = /(\$)(\d{1,3})(,\d{3})*/g;
var div = html.match(divRegex);
var zestimate;
if (div && div[0]) {
zestimate = div[0].match(moneyRegex)[0];
if (zestimate) {
var row = [];
row[0] = zestimate;
row[1] = new Date();
zillowSheet.appendRow(row);
MailApp.sendEmail('me@email.com', 'Zestimate Update', 'As of '.concat(row[1].toDateString().concat(' the Zestimate of your home was ').concat(row[0])));
}
else {
throw new Error("Zestimate not found");
}
}
else {
throw new Error("Zestimate div not found on page");
}
}
else {
throw new Error("Could not find Zillow sheet");
}
}
@darinalleman
Copy link
Author

darinalleman commented Dec 24, 2020

  1. Create a sheet inside your spreadsheet called "Zillow".
  2. Open Tools -> Script Editor.
  3. Paste the code snippet above into the editor.
  4. Change your zpid on line 6 (it's the 9 digit number at the end of the URL here: https://www.zillow.com/homedetails/1600-Pennsylvania-Ave-NW-Washington-DC-20006/84074482_zpid/, so you'd put 84074482 in where I have the %%% holder).
  5. Change your email address on line 19 (or remove this line if you don't want an email)
  6. Click Run and verify it worked by checking your sheet. (Shouldn't take more than 10s to run), check the editor for errors.
  7. Go to the triggers tab on the left, click Add Trigger in the bottom right.
  8. Make sure 'writeZestimatetoSheet' is the selected function. Head deployment is fine. I picked 'Time-drive' for event source, but here you can just see what option works best for you.

I've found that for some reason it won't work if you run it too quickly in succession, so if you get the "Zestimate div not found on page" error, wait a minute and try again.

@benito334
Copy link

@darinalleman How would you modify this script to do more than one Zpid?

@darinalleman
Copy link
Author

@benito334 I suppose it depends on the integration you're looking for. Using this script below, just put your zpid's in the zillowIds array and it'll add it in another column on the Zillow sheet.

function writeZestimateToSheet() {
  var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  var sheets = spreadsheet.getSheets();
  var zillowSheet = sheets.find(sheet => sheet.getSheetName() == 'Zillow');
  var balanceHistory = sheets.find(sheet => sheet.getSheetName() == 'Balance History');
  if (zillowSheet && balanceHistory) {
    var zillowIds = ['51946308','51919001', '84074482'];
    var row = [];
    for (i = 0; i < zillowIds.length; i++) {
      if (zillowIds[i] != undefined){
        var html = UrlFetchApp.fetch('https://www.zillow.com/homes/' + zillowIds[i] + '_zpid/').getContentText();
        const divRegex = /(<div class="zestimate-value">)(\$)(\d{1,3})(,\d{3})*(<\/div>)/g;
        const moneyRegex = /(\$)(\d{1,3})(,\d{3})*/g;
        var div = html.match(divRegex);
        var zestimate;
        if (div && div[0]) {
          zestimate = div[0].match(moneyRegex)[0];
          if (zestimate) {
            try {
              var today = new Date();
              var lastSunday = new Date();
              lastSunday.setDate(today.getDate() - today.getDay());
              let rowIndex = (i * 2);
              row[rowIndex] = zestimate;
              row[rowIndex + 1] = today;
            } catch(error) {
              throw new Error('Setting values failed');
            }
          }
          else {
            throw new Error("Zestimate not found");
          }
        }
        else {
          throw new Error("Zestimate div not found on page");
        }
      }
      Utilities.sleep(10000);//wait 10 seconds before doing the next request, zillow doesn't like requests too fast
    }
    zillowSheet.appendRow(row);

  }
  else {
    throw new Error("Could not find Zillow sheet");
  }
}

@benito334
Copy link

@darinalleman That worked perfect. Thanks!

@rbuentello
Copy link

I have run into a problem. I added 20 ZPIDs to @benito334 script. It runs successfully 70% when run from script editor. The error when failing is "Zestimate div not found on page." Curiously, when I setup a time trigger or When Open trigger it fails 100%. I even ran with just 1 ZPID. When triggered execution, its an instant failure.

@darinalleman
Copy link
Author

darinalleman commented Apr 13, 2021

I have run into a problem. I added 20 ZPIDs to @benito334 script. It runs successfully 70% when run from script editor. The error when failing is "Zestimate div not found on page." Curiously, when I setup a time trigger or When Open trigger it fails 100%. I even ran with just 1 ZPID. When triggered execution, its an instant failure.

@rbuentello - mine is failing sort of randomly it seems too. I've debugged it a bit and found that it has to do with Zillow's "Are you a robot" checks. Sometimes Zillow shows the captcha and sometimes it does not. Definitely a bummer!

@rbuentello
Copy link

rbuentello commented Apr 24, 2021 via email

@darinalleman
Copy link
Author

Yep. Experiencing the same issue. Unfortunately something I can't fix. Like I said in the comment above, the "Are you a robot" check will always fail because, well, this is a robot. Nothing I can do.

@rbuentello
Copy link

rbuentello commented Apr 26, 2021 via email

@darinalleman
Copy link
Author

Not that I'm aware of at this point.

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