Using the Google geocoding API to find a new apartment

Written by Alex Chantavy

I used Google’s geocoding API to list the neighborhoods of all 200+ Seattle apartment buildings covered by WaveG gigabit internet:


Here’s why I bothered: I’m moving to Seattle in a little under a month and I’m pretty excited to find that gigabit internet can be had for 80 bucks a month. The service provider gives this huge list of available buildings, but since it’s not grouped by neighborhood I don’t find it very helpful.

Sure, I could search for an apartment on Craigslist in the neighborhood of my choice and then Ctrl+F the list to see if the building is covered, but that’s no fun.

I wanna use magic instead.

Step 1: Get the data

First I need to get the building names and addresses off the webpage. This is easy - open up a browser web console and abuse JavaScript’s document.querySelectorAll() (also described in my previous post).

// grab all the building DOM elements
var bldgs = document.querySelectorAll('div.bldg_cel')

// test if we can get a building's name
bldgs[37].querySelector('a.bldg_title').textContent
>> "Avalon Co-op Apartments"

So far so good, now let’s grab only the names and addresses.

var result = [];

// grab all the seattle buildings; the seattle listings start at index 36
for (i = 36; i < bldgs.length; i++) {
  result.push( {'name': bldgs[i].querySelector('a.bldg_title').textContent
             ,  'addr': bldgs[i].querySelector('p').textContent.split('\n')[0]});
}

Let’s see if it worked.

JSON.stringify(result)

>> [{"name": "Smith & Burns Apartments",
     "addr": "4455 Interlake Ave N Seattle WA 98102"},
    {"name": "Avalon Co-op Apartments",
     "addr": "22 John St Seattle, WA 98109"},
    ...,
    {blahblahblah}]

Easy.

Step 2: Ask Google what neighborhood each address belongs to

I have a list of 222 addresses, now what? I remembered that Google Maps draws a red box around a neighborhood when you click on its name - I should be able to query that information programmatically…

StackOverflow pointed me toward Google’s Geocoding API, which ended up being super easy to use. All I needed to do was set up a Google developer account, generate an API key, and run an HTTP GET request of the form:

https://maps.googleapis.com/maps/api/geocode/json?address={ADDRESS}&key={API_KEY}.

As an example, running a GET with address set to 1525 Harvard Ave E Seattle WA gives me this beautiful JSON data:

{
   "results" : [
      {
         "address_components" : [
            {
               "long_name" : "1525",
               "short_name" : "1525",
               "types" : [ "street_number" ]
            },
            {
               "long_name" : "Harvard Avenue East",
               "short_name" : "Harvard Ave E",
               "types" : [ "route" ]
            },
            {
               "long_name" : "Capitol Hill",
               "short_name" : "Capitol Hill",
               "types" : [ "neighborhood", "political" ]
            }
      }
    ]
}

All I need to do now is run the query on all of my 222 addresses. Lucky for me, the Geocoding API limits free accounts to 2500 queries per day so I’m well under the limit. I’ll use python here.

import json, requests, urllib

#...data from step 1 goes here...# 
data = []  

api_key = 'YOUR_API_KEY'

for bldg in data:
    # properly urlencode the GET request
    params = {'address':bldg['addr'], 'key': api_key}
    encoded_req = 'https://maps.googleapis.com/maps/api/geocode/json?%s' % 
                  urllib.urlencode(params)

    # run the GET request and load the json into memory
    returnedobj = requests.get(encoded_req)    
    returneddata = json.loads(returnedobj.content)

    # save the neighborhood name to our original address list
    # (yeah the json structure here is really ugly)
    neighborhood = returneddata[u'results'][0][u'address_components'][2][u'long_name']    
    bldg['neighborhood'] = neighborhood

# print it out as comma separated values list, ready to paste into spreadsheet
for bldg in data:
    print '"{_name}","{_addr}","{_neig}"'.format( _name=bldg['name']
                                                , _addr=bldg['addr']
                                                , _neig=bldg['neighborhood'] )

And that gives me…

"Smith & Burns Apartments","4455 Interlake Ave N Seattle WA 98102","Wallingford"
"Avalon Co-op Apartments","22 John St Seattle, WA 98109","Lower Queen Anne"
"Decibel Apartments (Pre-sign)","301 12th Ave, Seattle WA","Downtown"
... etc ...

Pretty neat right? Now I need to stop procrastinating and actually find an apartment I want.

If you’re interested in the actual list data, feel free to contact me.