Skip to content

Instantly share code, notes, and snippets.

@DenisCarriere
Created December 14, 2015 19:04
Show Gist options
  • Save DenisCarriere/1a56ac970f91e90e9f46 to your computer and use it in GitHub Desktop.
Save DenisCarriere/1a56ac970f91e90e9f46 to your computer and use it in GitHub Desktop.
MLS Scraper
import geocoder
import requests
import unicodecsv as csv
import time
container = {}
g = geocoder.google("New Brunswick, Canada")
url = "https://www.realtor.ca/api/Listing.svc/PropertySearch_Post"
PropertySearchType = {
1: "Residential",
2: "Recreational",
3: "Condo/Strata",
8: "Multi Family",
4: "Agriculture",
5: "Parking",
6: "Vacant Land"
}
LandSizeRange = ["0-10", "10-50", "50-100", "100-320", "320-640", "640-1000", "1000-0"]
interval = 250000
intervals = 2
max_results = 350
for PropertySearch in PropertySearchType.keys():
Prices = list((i * interval, i * interval + interval) for i in range(intervals))
for PriceMin, PriceMax in Prices:
print('Looking for {} ({}$-{}$)...'.format(
PropertySearchType[PropertySearch],
PriceMin,
PriceMax
))
payload = {
"CultureId": "1",
"ApplicationId": "1",
"RecordsPerPage": max_results,
"MaximumResults": max_results,
"PropertySearchTypeId": PropertySearch,
"PriceMin": PriceMin,
"PriceMax": PriceMax,
"LandSizeRange": "0-0",
"TransactionTypeId": "2",
"StoreyRange": "0-0",
"BedRange": "0-0",
"BathRange": "0-0",
"LongitudeMin": g.west,
"LongitudeMax": g.east,
"LatitudeMin": g.south,
"LatitudeMax": g.north,
"SortOrder": "A",
"SortBy": "1",
"viewState": "m",
"Longitude": g.lng,
"Latitude": g.lat,
"ZoomLevel": "8",
}
while True:
try:
r = requests.post(url, data=payload)
break
except:
print(PriceMin, PriceMax)
time.sleep(1)
print('Connectin Fail...')
pass
if r.ok:
results = r.json()['Results']
print('Found {} results!'.format(len(results)))
if len(results) == max_results:
half = (PriceMax - PriceMin) / 2
Prices.append([PriceMin, int(PriceMin + half)])
Prices.append([int(PriceMin + half), PriceMax])
print('Price split {}$-{}$'.format(PriceMin, PriceMax))
for result in results:
data = {
'lng': result['Property']['Address']['Longitude'],
'lat': result['Property']['Address']['Latitude'],
'address': result['Property']['Address']['AddressText'],
'postal': result['PostalCode'],
'property_type': result['Property']['Type'],
'price': result['Property']['Price'],
'mls': result['MlsNumber'],
'bathrooms': result['Building'].get('BathroomTotal', 0),
'bedrooms': result['Building'].get('Bedrooms', 0),
'PriceMin': payload['PriceMin'],
'PriceMax': payload['PriceMax'],
'PropertySearch': PropertySearchType[PropertySearch],
'LandSize': result['Land'].get('SizeTotal'),
'url': 'https://www.realtor.ca' + result['RelativeDetailsURL']
}
container[result['MlsNumber']] = data
with open('mls.txt', 'wb') as f:
writer = csv.DictWriter(f, fieldnames=next(iter(container.values())), dialect='excel')
writer.writeheader()
for row in container.values():
writer.writerow(row)
@amitbhsingh
Copy link

I am facing below error! Please if you could direct me

StopIteration Traceback (most recent call last)
in ()
92
93 with open('mls.txt', 'wb') as f:
---> 94 writer = csv.DictWriter(f, fieldnames=next(iter(container.values())), dialect='excel')
95 writer.writeheader()
96 for row in container.values():

StopIteration:

@akasaki
Copy link

akasaki commented Oct 18, 2018

Same error as @amitbhsingh

@JordanMena
Copy link

@amitbhsingh, @akasaki - It seems like geocoder wasn't working for me. It was easier just to hardcode the min/max latitude and longitude for my search area. I also had to decrease the RecordsPerPage to 200 which @Froren has identified as the maximum value.

@TheCorp
Copy link

TheCorp commented Jun 4, 2019

Does this work for US MLS listings or just Canadian ones?

@Froren
Copy link

Froren commented Jun 4, 2019

Does this work for US MLS listings or just Canadian ones?

Realtor.ca is just for Canadian listings.

@TheCorp
Copy link

TheCorp commented Jun 4, 2019

Ok makes sense thank you!

@jagjeetgit
Copy link

Does this still work? I am getting a page

image

@j4sidhu
Copy link

j4sidhu commented Feb 14, 2021

I am getting a requests.exceptions.SSLError . Is it working for anyone else?

@DenisCarriere
Copy link
Author

This script most likely doesn’t work anymore

@j4sidhu
Copy link

j4sidhu commented Feb 16, 2021

This script most likely doesn’t work anymore

Hi Dennis, do you know why? Is it because "https://www.realtor.ca/api/Listing.svc/PropertySearch_Post" doesn't work anymore?

@sp0oon
Copy link

sp0oon commented Feb 17, 2021

You can check out https://github.com/Froren/realtorca for an up-to-date script.

@harry-s-grewal
Copy link

I've created an up-to-date wrapper for this in Python. Check here https://github.com/harry-s-grewal/realtorca

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