2015-05-22 2 views
0

Я работаю над личным проектом, визуализирующим данные о местоположении, и здесь я удаляю данные геокодирования из Google через Geocoding API, подавая его координаты и получая название города и страну.API-интерфейс Google Geocoding для Python - IndexError: индекс индекса за пределами диапазона?

Это CSV-файл с двумя столбцами: «Местоположение» (широта и долгота) и «Время» (дата + время). Есть 8533 строки.

Образец данных:

Location    Time 
-------------------------------------------------- 
| 41.2911084,2.0779035 | 4/15/2015 10:58   | 
-------------------------------------------------- 
| 41.2885014,2.0725591 | 4/15/2015 10:07   | 
-------------------------------------------------- 
| 41.3484125,2.1442487 | 4/15/2015 9:56   | 
-------------------------------------------------- 

У меня возникли проблемы с API где я получаю сообщение об ошибке. Позвольте мне сначала показать код.

# import necessary modules 
import pandas as pd 
import json, requests, logging 

# configure logging for our tool 
lfh = logging.FileHandler('reverseGeocoder.log') 
lfh.setFormatter(logging.Formatter('%(levelname)s %(asctime)s %(message)s')) 
log = logging.getLogger('reverseGeocoder') 
log.setLevel(logging.INFO) 
log.addHandler(lfh) 

# load the gps coordinate data 
df = pd.read_csv('LocationHistory.csv') 

# create new columns 
df['geocode_data'] = '' 
df['city'] = '' 
df['country'] = '' 


df.head() 

# function that handles the geocoding requests 
def reverseGeocode(latlng): 

    result = {} 
    url = 'https://maps.googleapis.com/maps/api/geocode/json?latlng={0}&key={1}' 
    apikey = 'API_KEY_GOES_HERE' 

    request = url.format(latlng, apikey) 
    log.info(request) 
    data = json.loads(requests.get(request).text) 
    log.info(data) 
    result = data['results'][0]['address_components'] 
    return { 
     'city': result[3]['long_name'], 
     'country': result[6]['long_name'] 
    } 

# comment out the following line of code to geocode the entire dataframe 
#df = df.head() 

for i, row in df.iterrows(): 
    # for each row in the dataframe, geocode the lat-long data 
    revGeocode = reverseGeocode(df['Location'][i]) 
    df['geocode_data'][i] = revGeocode 
    df['city'] = revGeocode['city'] 
    df['country'] = revGeocode['country'] 


    # once every 100 loops print a counter 
    #if i % 100 == 0: 
    print i 

df.head() 

df.to_csv('LocationHistory2.csv', encoding='utf-8', index=False) 

Ошибка в вопросе, что я все время получаю:

Traceback (most recent call last): 
    File "D:\...\ReverseGeocoding.py", line 45, in <module> 
    revGeocode = reverseGeocode(df['Location'][i]) 
    File "D:\...\ReverseGeocoding.py", line 37, in reverseGeocode 
    'country': result[6]['long_name'] 
IndexError: list index out of range 

Я думаю, что часть проблемы заключается в том, что мне нужно проверить на месте, в-случае API не возвращает ничего для местоположения. Почему он ничего не вернет, я понятия не имею.

Я довольно новичок в мире API (и Python), но как я могу получить этот код в рабочем состоянии?

ответ

1

Возможно, вам захочется выполнить проверку ключей типов для требуемого атрибута адреса. Так что попробуйте что-нибудь вроде;

result = data['results'][0]['address_components'] 
    city = '' 
    country = '' 

    for item in result: 
     if 'administrative_area_level_1' in item[types]: 
      city = item['long_name'] 
     elif 'country' in item[types]: 
      country = item['long_name'] 
    return { 
     'city': city, 
     'country': country 
    } 
+0

это работало для меня. просто изменил 'item [type]' to 'item ['type']' – Silas

0

I think that part of the problem is that I need a check in place, in-case the API doesn't return anything for the locations.

Действительно. Первое, что вы хотите сделать, это поместить ваш requests вызов в блок try/except, чтобы поймать possible exceptions во время фазы запроса (и при выполнении HTTP-запроса существует немало вещей, которые могут пойти не так).

BTW вы не должны строить строку запроса вручную - requeststakes care of it более безопасным способом (побег и т.д.), и вы все еще будете иметь доступ к итоговому URL в response объекта, если вы хотите. Так как стартер вы хотите:

url = 'https://maps.googleapis.com/maps/api/geocode/json' 
apikey = 'API_KEY_GOES_HERE' 
try: 
    response = requests.get(url, params={"key":apikey, "latlng":latlng}) 
except requests.exceptions.RequestException as e: 
    # this will log the whole traceback 
    logger.exception("call failed with %s", e) 
    # here you either re-raise the exception, raise your own exception, 
    # or return anything 
    return None 

Теперь вы хотите проверить response's status code - ничего, кроме 200 означает, что вы не имеете ваши данные

if response.status_code != 200: 
    logger.error("got status code %s", response.status_code) 
    # idem, either raise your own exception or 
    # return anything 
    return None 

FWIW, response имеет raise_for_status() method, что будет поднять RequestException если вы получаете 4xx или 5xx ответ, так что вы можете упростить все дело в:

try: 
    response = requests.get(url, params={"key":apikey, "latlng":latlng}) 
    response.raise_for_status() 
except requests.exceptions.RequestException as e: 
    # this will log the whole traceback 
    logger.exception("call failed with %s", e) 
    # here you either re-raise the exception, raise your own exception, 
    # or return anything 
    return None 

Теперь вы можете ожидать, вы ВГА e действительный ответ, поэтому давайте получим наши данные json. Здесь опять requests уже предлагает ярлык. Обратите внимание, что если тип содержимого вашего ответа не является «применение/JSON» или содержательная ответа является недействительным JSON, вы получите ValueError, но хорошо, я думаю, что мы можем доверять Google, чтобы сделать работу здесь;)

data = response.json() 

Я не совсем точно помню весь API геокодирования, поэтому должен действительно дважды проверить документ, но IIRC, пока у вас есть 200, вы должны , если у есть достоверные данные.

«Почему это ничего не вернет, я понятия не имею».

Соединение потеряно, пределы API, сервер вниз (да, это происходит), есть много возможных причин. С приведенным выше кодом вы должны хотя бы получить подсказку.

Теперь вы можете еще не все, что вы ожидаете в результате данных - здесь снова, проверьте документацию, вручную переигрывать запросы на geoloc, которые не удалось и проверить реакцию и данные и т.д.

+0

Спасибо за быстрый ответ, я продолжаю получать ошибки отступов, когда пытаюсь поместить блок try/except в reverseGeocode() под apikey. Он должен работать, но продолжает говорить «неожиданный отступ». Что я делаю не так? – thejesteroftortuga

+0

Редактировать: Исправлено это, но продолжайте получать мою предыдущую ошибку. – thejesteroftortuga

 Смежные вопросы

  • Нет связанных вопросов^_^