Using Python to grab Google Street View imagery

Update: I have been asked several times over the years for help on this. In response I have made a simple GUI tool, given a list of addresses and a download folder location, will download all of the images. Applications are websites listing properties and marketers for mailings.

The tool costs $300, Check out the CRIME De-Coder Store to purchase.


I am at it again with using Google data. For a few projects I was interested in downloading street view imagery data. It has been used in criminal justice applications as a free source for second hand systematic social observation by having people code aspects of disorder from the imagery (instead of going in person) (Quinn et al., 2014), as estimates of the ambient walking around population (Yin et al., 2015), and examining criminogenic aspects of the built environment (Vandeviver, 2014).

I think it is just a cool source of data though to be honest. See for example Phil Cohen’s Family Inequality post in which he shows examples of auctioned houses in Detroit over time.

Using the Google Street View image API you can submit either a set of coordinates or an address and have the latest street view image returned locally. This ends up being abit simpler than my prior examples (such as the street distance API or the places API) because it just returns the image blob, no need to parse JSON.

Below is a simple example in python, using a set of addresses in Detroit that are part of a land bank. This function takes an address and a location to download the file, then saves the resulting jpeg to your folder of choice. I defaulted for the image to be 1200×800 pixels.

import urllib, os

myloc = r"C:\Users\andrew.wheeler\Dropbox\Public\ExampleStreetView" #replace with your own location
key = "&key=" + "" #got banned after ~100 requests with no key

def GetStreet(Add,SaveLoc):
  base = "https://maps.googleapis.com/maps/api/streetview?size=1200x800&location="
  MyUrl = base + urllib.quote_plus(Add) + key #added url encoding
  fi = Add + ".jpg"
  urllib.urlretrieve(MyUrl, os.path.join(SaveLoc,fi))

Tests = ["457 West Robinwood Street, Detroit, Michigan 48203",
         "1520 West Philadelphia, Detroit, Michigan 48206",
         "2292 Grand, Detroit, Michigan 48238",
         "15414 Wabash Street, Detroit, Michigan 48238",
         "15867 Log Cabin, Detroit, Michigan 48238",
         "3317 Cody Street, Detroit, Michigan 48212",
         "14214 Arlington Street, Detroit, Michigan 48212"]

for i in Tests:
  GetStreet(Add=i,SaveLoc=myloc)

Dropbox has a nice mosaic view for a folder of pictures, you can view all seven photos here. Here is the 457 West Robinwood Street picture:

In my tests my IP got banned after around 100 images, but you can get a verified google account which allows 25,000 image downloads per day. Unfortunately the automatic API only returns the most recent image – there is no way to return older imagery nor know the date-stamp of the current image. (You technically could download the historical data if you know the pano id for the image. I don’t see any way though to know the available pano id’s though.) Update — as of 2018 there is now a Date associated with the image, specifically a Year-Month, but no more specific than that. Not being able to figure out historical pano id’s is still a problem as far as I can tell as well.

But this is definitely easier for social scientists wishing to code images as opposed to going into the online maps. Hopefully the API gets extended to have dates and a second API to return info. on what image dates are available. I’m not sure if Mike Bader’s software app is actually in the works, but for computer scientists there is a potential overlap with social scientists to do feature extraction of various social characteristics, in addition to manual coding of the images.


Update: here is a version that works for python 3+. Currently you need to have a key, no more getting a few free images before being cut off.

# For Python Versions 3+
# Tested V3.10 on 12/15/2021
import os
import urllib.parse
import urllib.request

myloc = r"??????????????" #replace with your own location
key = "&key=" + "????????????" #you need an actual key now!!

def GetStreet(Add,SaveLoc):
  base = "https://maps.googleapis.com/maps/api/streetview?size=1200x800&location="
  MyUrl = base + urllib.parse.quote_plus(Add) + key #added url encoding
  fi = Add + ".jpg"
  urllib.request.urlretrieve(MyUrl, os.path.join(SaveLoc,fi))

Tests = ["457 West Robinwood Street, Detroit, Michigan 48203",
         "1520 West Philadelphia, Detroit, Michigan 48206",
         "2292 Grand, Detroit, Michigan 48238",
         "15414 Wabash Street, Detroit, Michigan 48238",
         "15867 Log Cabin, Detroit, Michigan 48238",
         "3317 Cody Street, Detroit, Michigan 48212",
         "14214 Arlington Street, Detroit, Michigan 48212"]

for i in Tests:
  GetStreet(Add=i,SaveLoc=myloc)
Leave a comment

44 Comments

  1. Joe Devlin

     /  March 20, 2018

    Thanks for this, really useful! I initially got – AttributeError: module ‘urllib’ has no attribute ‘urlretrieve’ – so amended the code slightly to import urllib.request and also added request to – urllib.request.urlretrieve(MyUrl, os.path.join(SaveLoc,fi)) – but am now getting – HTTP Error 400: Bad Request – any ideas why that might be?

    Reply
    • Sorry, not sure. Code works as is for me still (just ran it) — I am using V2.7 – are you using V3? Might be a good question for stackoverflow.

      Reply
    • I see the ping-back someone answered your question — it needs to be encoded. I have updated the code snippet, as this is a good idea when passing arbitrary strings into the api, as other characters could cause problems as well.

      Reply
      • Joe Devlin

         /  March 23, 2018

        Thanks Andrew! I was thinking these images would be good to use for machine learning, maybe to try and identify certain stores/brands/signs or something like that. What do you think? Have you heard of anything like that being done? Also, do you know how I can remove the link to my facebook profile from these posts?

    • IANAL, so view the terms of service for your own application to see if you think you are OK. I cited a few applications that are similar to machine vision applications in this post already (Yin paper and work of Mike Bader), another I am familiar with is this Streetscore, http://ieeexplore.ieee.org/document/6910072/?tp=&arnumber=6910072&url=http:%2F%2Fieeexplore.ieee.org%2Fxpls%2Fabs_all.jsp%3Farnumber%3D6910072.

      I just manually took out the link to your facebook profile from your comment.

      Reply
  2. Andrew Campbell

     /  March 20, 2018

    This is great! I’m aware that Google Street View has a bunch of cameras that form the panoramas. I’m interested in getting the images for selected locations taken from the camera facing in the frontward direction. I’m relatively new to python so i’m wondering if you have any suggestions on whether it’s possible?

    Thanks!

    Reply
  3. Andrew Campbell

     /  March 21, 2018

    The images that download to the specified destination from the code are taken from a view looking at houses along a street. Is there a way in which the images can be oriented to face the road? I’m interested in looking at roadside assets in google street view imagery

    Reply
    • Ok, to do that it takes alittle bit of GIS know-how. First you need to find the orientation of the street, then you can identify which direction to point the camera. If you submit a lat-lon (and orientation) you can get an image for anywhere in the panorama.

      I did this for another project in which I needed to take running images of whole streets. What I did was generate a fine sample of points along the street (like every meter), in a GIS. From that data you can calculate the local orientation of the street. Then I sampled google street view images about every 40 meters (so there was little to no overlap between shots). But I requested images at 90 degrees to the street orientation (so I got the sidewalk), whereas here you would want to just look straight ahead (or backwards?).

      Reply
      • Andrew Campbell

         /  March 27, 2018

        Thanks for your response Andrew.

        This is actually for a GIS project so my GIS know-how is solid. You’re correct in that I do want to look straight ahead (90 degrees, give or take accounting for optimal viewing) of the street. My question would be, where do i need to define the lat longs and orientation for each individual image location in the code?

      • Just using a street-centerline file I created sample points regularly along the segment. Is that your question? You can email and I can share code if you want (I just made the regularly sampled point in ArcGIS).

  4. Simon Ghislain

     /  May 12, 2018

    Hello,

    i just installed python 3.5 and pyCharm, pasted the code, and got relatively same error at run as Joe Devlin:
    AttributeError: module ‘urllib’ has no attribute ‘quote_plus’

    Btw thank you very much for getting me on tracks…and sharing your code.
    I’m trying to
    1) define an itinerary from point A to point B
    2) generate, like in your reply to Andrew Campbell, a set of points every 40m or so
    3) use those points to calculate local direction of road
    4) generate google street screenshots with your code

    (I would like to make an animated GIF of that itinerary)

    But i don’t know where to start…i would like NOT to use ArcGIS (i used to use it but i don’t have it anymore). Also i’m new to Python too, altough i have some background in programmation and coding.
    Is it possible to use the Google itinerary tool to extract the set of points? (instead of a street-centerline file, whiwh I suppose is generated with ArcGIS?)
    Could you please help me in telling me the main steps I should follow in order to achieve that?
    I would be so thankful…

    Thank you very much in advance for any help, and already for sharing your knowledge

    Reply
  5. Simon Ghislain

     /  May 12, 2018

    Ok, the library urllib has been split into urllib.request, urllib.parse ans urllib.error from Python 2.x to Python 3.x

    So only change is to write “urllib.parse.quote_plus” instead of “urllib.quote_plus”
    and write
    “urllib.request.urlretrieve” instead of “urllib.urlretrieve”

    But then i got another error:
    line 258, in urlretrieve
    tfp = open(filename, ‘wb’)
    FileNotFoundError: [Errno 2] No such file or directory: ‘C:\\tests\\ExampleStreetView\\457 West Robinwood Street, Detroit, Michigan 48203.jpg’

    So looks like urlretrieve, instead of copying url content to a new file, tries to access the file beeing created?

    Reply
  6. Simon Ghislain

     /  May 12, 2018

    Yeah it works!
    Simply the destination directory didn’t exist yet…
    Wow so magical…I tried with my own adress, get the .jpg in less than one second…

    Now the last thing I would like to do is instead of a list of addresses, generate a set of coordinates and determine direction alongside road from a Google Map itinerary…with Direction aAPI? Is is possible?

    Reply
  7. ganesh

     /  October 15, 2018

    am having this error could any one help me Error interpreting JPEG image file (Not a JPEG file: starts with 0x89 0x50)4

    Reply
  8. john

     /  April 4, 2019

    I am working on a project that requires me to gather aerial views of specific locations within larger developments. Due to the areas being located on the interior of the sites, street view images will not always give me the appropriate view. You mentioned in the article that you can use street addresses or coordinates. Is there a way to use the coordinates to gather aerial images as opposed to the street view?

    Reply
  9. Angel R

     /  May 7, 2019

    Finally got this to work for me, however, the resulting jpegs cannot be opened by any of my photo/image viewer programs. All show to be 259 byte (1kb), JPG files. Not sure what is happening.

    Reply
    • See some of the earlier comments, it may be the same problem (saved as a jpeg extension but is actually a PNG file).

      Reply
      • Juan Marrugo

         /  November 1, 2019

        I found out that you have to enable billing in the Google Cloud Console. If you enter the API key and run the program, you get those tiny files. Open any of the files using notepad, it should say “The Google Maps Platform server rejected your request. You must enable Billing on the Google Cloud Project at https://console.cloud.google.com/project/_/billing/enable Learn more at https://developers.google.com/maps/gmp-get-started“. On the other hand, if you do not enter an API key you get “The Google Maps Platform server rejected your request. You must use an API key to authenticate each request to Google Maps Platform APIs. For additional information, please refer to http://g.co/dev/maps-no-account“.

      • Yes, to enable billing you need to provide a credit card for verification. But that does not mean you will actually be billed, you can set the API so it will cut off before the free limits run out (or just not submit that many requests).

        If you have many more requests than the free billing allows, you should use a local geocoder or street centerlines to figure out the orientation stuff. But the streetview images are unique with no alternative that I am aware of.

  10. Juan Marrugo

     /  November 1, 2019

    Hi Andrew, hope you are doing fine. I searched for a way to grab Google Streetview images automatically and I was sent to your post. However I have a few questions:
    1) Should I enable any specifics in the google console for it to work better on your script? I enabled Street View Static API, is that enough?
    2) I have a set of randomly assorted points over a map, all set to fall in the center of a building. I need a photo of such building. Do you a way to batch reverse geocode the lat long coordinates into local directions? My main concern is that the pictures end up facing the wrong direction, and hence not showing the buildings.
    3) If I were to use the Lat Long coordinates, what format should I use for it?

    Thanks in advance,

    Juan

    Reply
  11. thejodyfall

     /  November 18, 2021

    Hello, thanks for this post – really interesting. Is there a way to get a list of locations linked from an initial location in google maps/street view? So if I had a starting location, could I find out programmatically the linked locations, similar to the way street view works with the control arrows?

    Reply
  12. thejodyfall

     /  November 18, 2021

    Wow, that’s amazing! Will take a look through – thank you so much.

    Reply
  13. I tried the code and I am using python 3.10 version and it gives me this error. raise HTTPError(req.full_url, code, msg, hdrs, fp)
    urllib.error.HTTPError: HTTP Error 403: Forbidden

    I am not sure what is causing this error.
    Thank you for your help. If anyone has a new version of this code. I would be appreciated to share it with me.
    Thanks.

    Reply
  14. Cristian

     /  April 7, 2022

    Hi, nice post. I am trying to get every image on GSV from my city. As is saw on one of your replys, you said you take images every 30m. How did you do that? Is there another library for that?

    Reply
  15. gadapwar sai

     /  August 29, 2023

    can any drop project code here

    Reply
    • What do you mean project code? An API key perhaps?

      Reply
      • Saiprasad Gadapwar

         /  August 29, 2023

        No complete code of this project i said to share

      • I don’t know what you want — the blog post has the code examples. The GUI tool I created I am selling for $300, I am not going to give that away for free.

  1. Python, Google street view API – HTTP Error 400: Bad Request – program faq
  2. Drawing Google Streetview images down an entire street using python | Andrew Wheeler
  3. Using the Google Vision and Streetview API to Explore Hotspots | Andrew Wheeler
  4. Using google places API in criminology research? | Andrew Wheeler
  5. GUI Tool to download Google Streetview Imagery | Andrew Wheeler

Leave a comment