Search code examples
pythonnested-listsgeopy

Geopy Google v3 - Extracting address components from location.raw


I have this python script where I get a list of addresses from a SQL table and then pass them to googles api using Geopy to get them Geocoded then write the data back to a different SQL table.

I'm currently stuck trying to extract out the address parts from address_components.

I've tried quite a few things like converting location.raw to Json, using other address parsers (but i'm not in the US) and my python is not strong. I also can't just reference the list part directly as different addresses will have different lengths so when I apply it to the dataframe later it fails as the lists arent all the same length. eg loc_raw0.append(location.raw['address_components'][0]['long_name'])

I'm currently trying to use a nested For loop just to get the street number out and then will replicate fo the other parts.

Whats happening is k will equal 'address_components' however v will equal '{'long_name': '46', 'short_name': '46', 'types': ['street_number']}' and not just 'street_number'.

        for k, v in location.raw.items():
            if k == 'address_components' and 'street_number' in v:
                loc_street_number.append(location.raw['long_name'])
                print(loc_street_number)

pic of list v contents

df = pd.DataFrame(SQL_Query, columns=['address'])


loc_Inputaddress = []
loc_Longitude = []
loc_Latitude = []
loc_Matchedaddress = []

loc_subpremise = []
loc_street_number = []
loc_road = []
loc_locality = []
loc_AdminArea1 = []
loc_AdminArea2 = []
loc_postcode = []
loc_type = []


for address in df.address:
    try:
        inputAddress = address
        location = g.geocode(inputAddress, timeout=15)

        loc_Inputaddress.append(inputAddress)
        loc_Longitude.append(location.longitude)
        loc_Latitude.append(location.latitude)
        loc_Matchedaddress.append(location.address)
        loc_type.append(location.raw['types'][0])

        #get address type
        print(loc_type.append(location.raw['types'][0]))

        #print(location.raw['address_components'])

  
        for k, v in location.raw.items():
            if k == 'address_components' and 'street_number' in v:
                loc_street_number.append(location.raw['long_name'])
                print(loc_street_number)

    except Exception as e:
        print('Error, skipping address...', e)

Solution

  • In your code, v is a list of dictionaries and, as far as I understand, you want the long_name of the dictionary that has a street_number type. This example should help you:

    v = [{
        "long_name": "40",
        "short_name": "40",
        "types": ["subpremise"]
    },
    {
        "long_name": "46",
        "short_name": "46",
        "types": ["street_number"]
    },
    {
        "long_name": "Aongatete",
        "short_name": "Aongatete",
        "types": ["locality", "political"]
    }]
    
    # Iterate over v because it is a list
    for address_component in v:
        # Check if one of the address component types is "street_number"
        if "street_number" in address_component["types"]:
            print(address_component["long_name"])
            break
    
    # Output:
    # 46
    

    Demo in myCompiler