2015-05-13 3 views
0

Я относительно новый пользователь Python и пытаюсь использовать функцию, чтобы вернуть широту и долготу для города и страны, используя модуль «геофизика». У меня были ошибки, потому что у моего города была ошибка, которую мне удалось поймать. Проблема, с которой я сталкиваюсь сейчас, заключается в том, что я столкнулся с ошибкой тайм-аута. Я прочитал этот вопрос Geopy: catch timeout error и соответствующим образом скорректировал свой параметр таймаута. Однако он теперь работает в течение различной продолжительности времени, прежде чем я получу ошибку тайм-аута. Я попытался запустить его по более быстрым сетям, и он работает в некоторой степени. Проблема в том, что мне нужно сделать это для строк в 100 тыс., А максимальные строки, которые он выполнил, до истечения времени 20 кбит. Любая помощь/советы о том, как решить эту проблему, очень ценится.Ошибка таймаута в геокодере геопространства Python

import os 
from geopy.geocoders import Nominatim 
os.getcwd() #check current working directory 
os.chdir("C:\Users\Philip\Documents\HDSDA1\Project\Global Terrorism Database") 

#import file as a csv 
import csv 
gtd=open("gtd_original.csv","r") 
csv_f=csv.reader(gtd) 
outf=open("r_ready.csv","wb") 
writer=csv.writer(outf,dialect='excel') 
for row in csv_f: 
    if row[13] in ("","NA") or row[14] in ("","NA"): 
     lookup = row[12] + "," + row[8] # creates a city,country 
     geolocator = Nominatim() 
     location = geolocator.geocode(lookup, timeout = None) #looks up the city/country on maps 
     try: 
      location.latitude 
     except: 
      lookup = row[8] 
      location = geolocator.geocode(lookup) 
     row[13] = location.latitude 
     row[14] = location.longitude 
    writer.writerow(row)  
gtd.close() 
outf.close() 

ответ

5

Я ожидаю, что вы exceded политики использования для обслуживания Nominatim (http://wiki.openstreetmap.org/wiki/Nominatim_usage_policy). Попробуйте поспать на 1 секунду между запросами и кешем результатов, вероятно, много дубликатов.

Спящий часть:

from time import sleep 
### your code 
row[14] = location.longitude 
sleep(1) # after last line in if 

Кэширование:

coords = {} 
if coords.has_key([row[8], row[12] ]): 
    row[13] , row[14] = coords[ [ row[8], row[12] ] ] 
else: 
    #geolocate 

Обновление

производительность: 1 запрос/сек -> 3600 Reqs/час -> 36K/10h

import os 
from time import sleep 
from geopy.geocoders import Nominatim 
os.getcwd() #check current working directory 
os.chdir("C:\Users\Philip\Documents\HDSDA1\Project\Global Terrorism Database") 

#import file as a csv 
import csv 
gtd=open("gtd_original.csv","r") 
csv_f=csv.reader(gtd) 
outf=open("r_ready.csv","wb") 
writer=csv.writer(outf,dialect='excel') 
coords = {} 
for row in csv_f: 
    if row[13] in ("","NA") or row[14] in ("","NA"): 
     lookup = row[12] + "," + row[8] # creates a city,country 

     if coords.has_key((row[8], row[12])): ## test if result is already cached 
      row[13] , row[14] = coords[ (row[8], row[12]) ] 
     else:  
      geolocator = Nominatim() 
      location = geolocator.geocode(lookup, timeout = None) #looks up the city/country on maps 
      try: 
       location.latitude 
      except: 
       lookup = row[8] 
       location = geolocator.geocode(lookup) 
      row[13] = location.latitude 
      row[14] = location.longitude 
      coords[ (row[8], row[12]) ] = (row[13] , row[14]) # cache the new coords 
      sleep(1) # sleep for 1 sec (required by Nominatim usage policy) 

    writer.writerow(row)  
gtd.close() 
outf.close() 
+0

Спасибо за быстрый ответ. Можете ли вы объяснить, как спать между результатами? И привести пример того, как я мог его реализовать? Я просто немного чувствую себя из глубины –

+0

Спасибо за подробный ответ и ваше время для ответа на этот вопрос. к сожалению, я все же получил ошибку таймаута, используя этот код. –

+0

@pitts_brother Я предполагаю, что у вас есть это, но: ** время импорта **, то в вашей петле - time.sleep (seconds) –

0

вы можете использовать GeocoderTimedOut

здесь пример функции, которая может помочь вам

import geopy 
from geopy.geocoders import Nominatim 
from geopy.exc import GeocoderTimedOut 

def do_geocode(address): 
    geopy = Nominatim() 
    try: 
     return geopy.geocode(address) 
    except GeocoderTimedOut: 
     return do_geocode(address) 

его довольно просто, если тайм-аут происходит, то он будет пытаться повторить. Надеюсь, это поможет