Google 地理编码 API OVER_QUERY_LIMIT 问题
Google Geocoding API OVER_QUERY_LIMIT issue
我正在尝试 运行 一个脚本来将地址(大约 1,000 个)更改为地理坐标,但出于某种原因,我在输入输入中的第 50 个地址后收到 OVER_QUERY_LIMIT 响应列表。
为了避免查询限制,我已经在循环中添加了一个 time.sleep 命令,但出于某种原因,它说我再次超出限制。
有人可以帮忙吗? (仅供参考,我 运行 在我的笔记本电脑上安装它)
import pandas as pd
import requests
import logging
import time
logger = logging.getLogger("root")
logger.setLevel(logging.DEBUG)
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
logger.addHandler(ch)
API_KEY = my_key #using my API key
BACKOFF_TIME = 5
output_filename = 'result.csv'
input_filename = 'input.csv'
address_column_name = "Address"
RETURN_FULL_RESULTS = False
data = pd.read_csv(input_filename, encoding='utf8')
if address_column_name not in data.columns:
raise ValueError("Missing Address column in input data")
addresses = data[address_column_name].tolist()
def get_google_results(address, api_key=my_key, return_full_response=False):
geocode_url = "https://maps.googleapis.com/maps/api/geocode/json?address={}".format(address)
if api_key is not None:
geocode_url = geocode_url + "&key={}".format(api_key)
results = requests.get(geocode_url)
results = results.json()
if len(results['results']) == 0:
output = {
"formatted_address" : None,
"latitude": None,
"longitude": None,
"accuracy": None,
"google_place_id": None,
"type": None,
"postcode": None
}
else:
answer = results['results'][0]
output = {
"formatted_address" : answer.get('formatted_address'),
"latitude": answer.get('geometry').get('location').get('lat'),
"longitude": answer.get('geometry').get('location').get('lng'),
"accuracy": answer.get('geometry').get('location_type'),
"google_place_id": answer.get("place_id"),
"type": ",".join(answer.get('types')),
"postcode": ",".join([x['long_name'] for x in answer.get('address_components')
if 'postal_code' in x.get('types')])
}
output['input_string'] = address
output['number_of_results'] = len(results['results'])
output['status'] = results.get('status')
if return_full_response is True:
output['response'] = results
return output
results = []
for address in addresses:
geocoded = False
while geocoded is not True:
try:
geocode_result = get_google_results(address, API_KEY,
return_full_response=RETURN_FULL_RESULTS)
time.sleep(5)
except Exception as e:
logger.exception(e)
logger.error("Major error with {}".format(address))
logger.error("Skipping!")
geocoded = True
if geocode_result['status'] == 'OVER_QUERY_LIMIT':
logger.info("Hit Query Limit! Backing off for a bit.")
time.sleep(BACKOFF_TIME * 60) # sleep
geocoded = False
else:
if geocode_result['status'] != 'OK':
logger.warning("Error geocoding {}: {}".format(address, geocode_result['status']))
logger.debug("Geocoded: {}: {}".format(address, geocode_result['status']))
results.append(geocode_result)
geocoded = True
if len(results) % 100 == 0:
logger.info("Completed {} of {} address".format(len(results), len(addresses)))
if len(results) % 50 == 0:
pd.DataFrame(results).to_csv("{}_bak".format(output_filename))
logger.info("Finished geocoding all addresses")
pd.DataFrame(results).to_csv(output_filename, encoding='utf8')
地理编码 API 具有每秒查询 (QPS) 限制。您不能发送超过 50 QPS。
此限制记录在
https://developers.google.com/maps/documentation/geocoding/usage-and-billing#other-usage-limits
While you are no longer limited to a maximum number of requests per day (QPD), the following usage limits are still in place for the Geocoding API:
- 50 requests per second (QPS), calculated as the sum of client-side and server-side queries.
为了解决您的问题,我建议对 Google 地图 API Web 服务使用 Python 客户端库:
https://github.com/googlemaps/google-maps-services-python
此库在内部控制 QPS,因此您的请求将正确排队。
希望对您有所帮助!
我正在尝试 运行 一个脚本来将地址(大约 1,000 个)更改为地理坐标,但出于某种原因,我在输入输入中的第 50 个地址后收到 OVER_QUERY_LIMIT 响应列表。
为了避免查询限制,我已经在循环中添加了一个 time.sleep 命令,但出于某种原因,它说我再次超出限制。
有人可以帮忙吗? (仅供参考,我 运行 在我的笔记本电脑上安装它)
import pandas as pd
import requests
import logging
import time
logger = logging.getLogger("root")
logger.setLevel(logging.DEBUG)
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
logger.addHandler(ch)
API_KEY = my_key #using my API key
BACKOFF_TIME = 5
output_filename = 'result.csv'
input_filename = 'input.csv'
address_column_name = "Address"
RETURN_FULL_RESULTS = False
data = pd.read_csv(input_filename, encoding='utf8')
if address_column_name not in data.columns:
raise ValueError("Missing Address column in input data")
addresses = data[address_column_name].tolist()
def get_google_results(address, api_key=my_key, return_full_response=False):
geocode_url = "https://maps.googleapis.com/maps/api/geocode/json?address={}".format(address)
if api_key is not None:
geocode_url = geocode_url + "&key={}".format(api_key)
results = requests.get(geocode_url)
results = results.json()
if len(results['results']) == 0:
output = {
"formatted_address" : None,
"latitude": None,
"longitude": None,
"accuracy": None,
"google_place_id": None,
"type": None,
"postcode": None
}
else:
answer = results['results'][0]
output = {
"formatted_address" : answer.get('formatted_address'),
"latitude": answer.get('geometry').get('location').get('lat'),
"longitude": answer.get('geometry').get('location').get('lng'),
"accuracy": answer.get('geometry').get('location_type'),
"google_place_id": answer.get("place_id"),
"type": ",".join(answer.get('types')),
"postcode": ",".join([x['long_name'] for x in answer.get('address_components')
if 'postal_code' in x.get('types')])
}
output['input_string'] = address
output['number_of_results'] = len(results['results'])
output['status'] = results.get('status')
if return_full_response is True:
output['response'] = results
return output
results = []
for address in addresses:
geocoded = False
while geocoded is not True:
try:
geocode_result = get_google_results(address, API_KEY,
return_full_response=RETURN_FULL_RESULTS)
time.sleep(5)
except Exception as e:
logger.exception(e)
logger.error("Major error with {}".format(address))
logger.error("Skipping!")
geocoded = True
if geocode_result['status'] == 'OVER_QUERY_LIMIT':
logger.info("Hit Query Limit! Backing off for a bit.")
time.sleep(BACKOFF_TIME * 60) # sleep
geocoded = False
else:
if geocode_result['status'] != 'OK':
logger.warning("Error geocoding {}: {}".format(address, geocode_result['status']))
logger.debug("Geocoded: {}: {}".format(address, geocode_result['status']))
results.append(geocode_result)
geocoded = True
if len(results) % 100 == 0:
logger.info("Completed {} of {} address".format(len(results), len(addresses)))
if len(results) % 50 == 0:
pd.DataFrame(results).to_csv("{}_bak".format(output_filename))
logger.info("Finished geocoding all addresses")
pd.DataFrame(results).to_csv(output_filename, encoding='utf8')
地理编码 API 具有每秒查询 (QPS) 限制。您不能发送超过 50 QPS。
此限制记录在
https://developers.google.com/maps/documentation/geocoding/usage-and-billing#other-usage-limits
While you are no longer limited to a maximum number of requests per day (QPD), the following usage limits are still in place for the Geocoding API:
- 50 requests per second (QPS), calculated as the sum of client-side and server-side queries.
为了解决您的问题,我建议对 Google 地图 API Web 服务使用 Python 客户端库:
https://github.com/googlemaps/google-maps-services-python
此库在内部控制 QPS,因此您的请求将正确排队。
希望对您有所帮助!