Google Geocoding API закрывает соединение без ответа - PullRequest
2 голосов
/ 25 мая 2020

В настоящее время я работаю над сценарием для геокодирования списка адресов, чтобы подготовить его для анализа и визуализации. Я впервые работаю с геокодированием, поэтому я борюсь и не уверен, есть ли что-то очевидное, что мне здесь не хватает. Я работаю с Google Geocoding API.

Общая схема моего (не оптимизированного) процесса состоит в том, чтобы превратить столбец в DataFrame, содержащий адреса, в список. Затем я создаю новый список из этого списка, используя понимание списка, где каждый элемент является подмножеством данных, которые я получил.

key = ...
city = "Long Beach"
state = "CA"

addresses = df["Address"].values.tolist()
geocodes = [geocode(x,city,state,key) for x in addresses]

Фактическая функция, которую я использую для геокодирования, приведена ниже. Требуется мой ключ API, адрес и параметры города / штата, чтобы дать полный адрес переезда. Затем он просто выполняет вызов и возвращает список из трех элементов, которые я ищу в ответе.

def geocode(address, city, state, key):
    time.sleep(.05)
    params = f"{address.lower()} {city}, {state}".replace(" ","+")
    request_url = "https://maps.googleapis.com/maps/api/geocode/json?address="+params+f"&key={key}"
    response = requests.get(request_url).json()
    neighborhood = response["results"][0]["address_components"][2]["long_name"]
    lat = response["results"][0]["geometry"]["location"]["lat"]
    lon = response["results"][0]["geometry"]["location"]["lng"]
    return [neighborhood, lat, lon]

Когда я запускаю его, сценарий некоторое время работает, а затем терпит неудачу. Когда это происходит, трассировка дает мне исключения, которые я включаю ниже. До сих пор мне не удалось найти информацию о том, в чем может заключаться эта проблема или как мне подойти к диагностике проблемы для API геокодирования Google. Они предоставляют информацию о том, как интерпретировать статусы запросов, но когда я проверяю статусы, которые я возвращаю до сбоя, все они имеют значение 'OK', и ни один из них не указывает, почему соединение закрывается.

RemoteDisconnected: Remote end closed connection without response

During handling of the above exception, another exception occurred:

ProtocolError                             Traceback (most recent call last)
----------
ProtocolError: ('Connection aborted.', RemoteDisconnected('Remote end closed connection without response'))

During handling of the above exception, another exception occurred:

ConnectionError                           Traceback (most recent call last)
----------
ConnectionError: ('Connection aborted.', RemoteDisconnected('Remote end closed connection without response'))

Я поигрался с этим и пока исключил пару вещей: 1. Я успешно пробовал это с одиночными вызовами и получил то, что мне нужно. Проблемы возникают, когда я запускаю его по списку. 2. Я использовал TQDM и распечатал статусы (в разных точках), и сценарий успешно выполняет вызов, возвращает данные и много раз переходит к следующему, прежде чем он выйдет из строя. 3. Я не думаю, что это проблема ограничения скорости. У этого API нет дневных ограничений, только ограничение на количество запросов в секунду, равное 50. Примерное значение time.sleep(.05) в моей функции должно поддерживать его примерно на уровне 20 запросов в секунду, а у меня меньше этого лимита.

Кто-нибудь знает, какой у меня проблема может быть? Или кто-нибудь объяснит, какую дополнительную диагностику мне следует сделать? Опять же, я новичок в геокодировании и раньше не сталкивался с этой проблемой с API, с которыми у меня есть опыт, поэтому даже помощь в понимании того, что происходит, чтобы я мог решить ее сам, был бы очень признателен, если никто не может найти проблему. .

1 Ответ

2 голосов
/ 28 мая 2020

Попробуйте использовать официальный модуль py googlemaps. Он также использует requests.Session под капотом, но у меня никогда не было проблем с этим. Вам может понадобиться несколько multithreading в дальнейшем, но если у вас не слишком много адресов, это должно помочь:

import time
import logging
import googlemaps


key = '...'
gmaps_client = googlemaps.Client(key=key)

addresses = [
    ["8473 Manor Station Street", "Cartersville", "GA"],
    ["14 Edgewater Ave.", "Ottumwa", "IA"],
    ["42 Aspen Court", "San Diego", "CA"]
]


def geocode(address, city, state):
    time.sleep(.05)
    params = f"{address.lower()} {city}, {state}".replace(" ", "+")

    try:
        response = gmaps_client.geocode(params)[0]

        neighborhood = response["address_components"][2]["long_name"]
        lat = response["geometry"]["location"]["lat"]
        lon = response["geometry"]["location"]["lng"]

        return [neighborhood, lat, lon]
    except Exception as e:
        logging.error(e)
        return [None, None, None]


geocodes = [geocode(*group) for group in addresses]

print(geocodes)

...