Search code examples
pythoncsvparsingstreet-address

IndexError: list index out of range when doing nested 'for'


I want to parsing Indonesian address using the tutorial I got here: https://codeburst.io/how-to-transform-unstructured-address-data-using-python-googles-maps-api-3eea326cb862

import requests
import json
import csv
from tqdm import *

def addresses_from_csv(path=None, column=None):

    addresses = []

    with open(path, 'r') as f:
        reader = csv.reader(f)
        for row in reader:
            addresses.append(row[column])

    return addresses

# Get addresses from CSV
addresses = addresses_from_csv(path='path/to/your/file.csv', column=0)

# Set Google Maps API key
api_key = YOUR_API_KEY

# Initialize array for transformed addresses
transformed = []
transformed.append(['Country', 'Post code', 'City', 'Street & No'])

for query in tqdm(addresses):

    # API call, storing information as JSON
    url = 'https://maps.googleapis.com/maps/api/geocode/json?address=' + query + '&lang=en&key=' + api_key
    r = requests.get(url)
    data = r.json()
    #print(data)

    # clear all values to avoid appending values from previous iterations a second time
    number = street = country = postal_code = city = '' 

    # looping over address components in JSON
    for component in data['results'][0]['address_components']:
        if 'street_number' in component['types']:
            number = component['long_name']
        elif 'route' in component['types']:
            street = component['long_name']
        elif 'country' in component['types']:
            country = component['long_name']
        elif 'postal_code' in component['types']:
            postal_code = component['long_name']
        elif 'locality' in component['types']:
            city = component['long_name']
        elif 'postal_town' in component['types']:
            city = component['long_name']
        else:
            continue

    street_and_no = street + ' ' + number
    transformed.append([country, postal_code, city, street_and_no])

with open('transformed_addresses.csv', 'w', newline='', encoding='utf-8') as f:
    writer = csv.writer(f)
    for row in transformed:
        writer.writerow(row)

print('done')

where my csv format look like this

to_address,booking_date
JL. RAYA PASIR PUTIH NO. 6 RT 05/RW 03 (DEPAN TOKO HANIMO) SAWANGAN,15-12-17
LEGENDA WISATA ZONA EINSTEIN BLOK R 12 NO 6 WANAHERANG DEPOK,15-12-17
"PERM CLUSTER TIDAR ASRI BLOK C7 NO 17 KEL RANGKAPAN JAYA PANCORANMAS,DEPOK",15-12-17
"CIBUNTU SAYURAN RT 12/06 KEL WARUNG MUNCANG BANDUNG KULON,BANDUN",15-12-17

But it raised an error

  0%|                                                                                         | 0/1001 [00:00<?, ?it/s]
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-5-f8eaa665c3a1> in <module>
     10 
     11     # looping over address components in JSON
---> 12     for component in data['results'][0]['address_components']:
     13         if 'street_number' in component['types']:
     14             number = component['long_name']

IndexError: list index out of range

Please tell me what to do to handle this error to make the script running smoothly?


Solution

  • You need to handle the case where data['results'] is empty, so before the loop add this line to your code:

        # This two lines added to your code
        if len(data['results']) == 0:
            continue
    
        # looping over address components in JSON
        for component in data['results'][0]['address_components']:
            if 'street_number' in component['types']:
                number = component['long_name']
            elif 'route' in component['types']:
                street = component['long_name']
            elif 'country' in component['types']:
                country = component['long_name']
            elif 'postal_code' in component['types']:
                postal_code = component['long_name']
            elif 'locality' in component['types']:
                city = component['long_name']
            elif 'postal_town' in component['types']:
                city = component['long_name']
            else:
                continue