403使用Google地图进行地理编码时出错

时间:2013-10-05 12:12:46

标签: python google-maps python-2.7

我正在尝试使用以下代码,但它无效。

from googlemaps import GoogleMaps
gmaps = GoogleMaps(api_key='mykey')
reverse = gmaps.reverse_geocode(38.887563, -77.019929)
address = reverse['Placemark'][0]['address']
print(address)

当我尝试运行此代码时,我遇到了错误。请帮我解决这个问题。

Traceback (most recent call last):
  File "C:/Users/Gokul/PycharmProjects/work/zipcode.py", line 3, in <module>
    reverse = gmaps.reverse_geocode(38.887563, -77.019929)
  File "C:\Python27\lib\site-packages\googlemaps.py", line 295, in reverse_geocode
    return self.geocode("%f,%f" % (lat, lng), sensor=sensor, oe=oe, ll=ll, spn=spn, gl=gl)
  File "C:\Python27\lib\site-packages\googlemaps.py", line 259, in geocode
    url, response = fetch_json(self._GEOCODE_QUERY_URL, params=params)
  File "C:\Python27\lib\site-packages\googlemaps.py", line 50, in fetch_json
    response = urllib2.urlopen(request)
  File "C:\Python27\lib\urllib2.py", line 127, in urlopen
    return _opener.open(url, data, timeout)
  File "C:\Python27\lib\urllib2.py", line 410, in open
    response = meth(req, response)
  File "C:\Python27\lib\urllib2.py", line 523, in http_response
    'http', request, response, code, msg, hdrs)
  File "C:\Python27\lib\urllib2.py", line 448, in error
    return self._call_chain(*args)
  File "C:\Python27\lib\urllib2.py", line 382, in _call_chain
    result = func(*args)
  File "C:\Python27\lib\urllib2.py", line 531, in http_error_default
    raise HTTPError(req.get_full_url(), code, msg, hdrs, fp)
urllib2.HTTPError: HTTP Error 403: Forbidden

2 个答案:

答案 0 :(得分:2)

阅读2010年写的“Python网络编程基础”一书,我发现自己处理了类似的错误。稍微更改代码示例,我得到了以下错误消息:

  

Geocoding API v2已于2013年9月9日被拒绝。现在应该使用Geocoding API v3。请访问https://developers.google.com/maps/documentation/geocoding/

了解详情

显然,网址中所需的params和网址本身也发生了变化。 曾经是:

params = {'q': '27 de Abril 1000, Cordoba, Argentina',
          'output': 'json', 'oe': 'utf8'}
url = 'http://maps.google.com/maps/geo?' + urllib.urlencode(params)

现在是:

params = {'address': '27 de Abril 1000, Cordoba, Argentina',                    
          'sensor': 'false'}                                                   

url = 'http://maps.googleapis.com/maps/api/geocode/json?' + urllib.urlencode(params)

我认为googlemaps python包还没有更新。

这对我有用。

在一个完整的例子之下,GoogleMap()在幕后所做的更多或更少是什么:

import urllib, urllib2                                                          
import json                                                                     

params = {'address': '27 de Abril 1000, Cordoba, Argentina',                    
          'sensor': 'false'}                                                   

url = 'http://maps.googleapis.com/maps/api/geocode/json?' + urllib.urlencode(params)

rawreply = urllib2.urlopen(url).read()                                          
reply = json.loads(rawreply)                                                    

lat = reply['results'][0]['geometry']['location']['lat']                        
lng = reply['results'][0]['geometry']['location']['lng']                        

print '[%f; %f]' % (lat, lng)

答案 1 :(得分:0)

在这里阅读一些关于你得到的错误的东西,表明它可能是由于请求没有传递足够的标题以使响应正确回归所致。

https://stackoverflow.com/a/13303773/220710

查看GoogleMaps包的来源,您可以看到在没有标头参数的情况下调用了fetch_json

...
    url, response = fetch_json(self._GEOCODE_QUERY_URL, params=params)
    status_code = response['Status']['code']
    if status_code != STATUS_OK:
        raise GoogleMapsError(status_code, url, response)
    return response

以下是fetch_json函数,因此似乎headers参数为空{}所以可能是问题所在:

def fetch_json(query_url, params={}, headers={}):       # pylint: disable-msg=W0102
    """Retrieve a JSON object from a (parameterized) URL.

    :param query_url: The base URL to query
    :type query_url: string
    :param params: Dictionary mapping (string) query parameters to values
    :type params: dict
    :param headers: Dictionary giving (string) HTTP headers and values
    :type headers: dict 
    :return: A `(url, json_obj)` tuple, where `url` is the final,
    parameterized, encoded URL fetched, and `json_obj` is the data 
    fetched from that URL as a JSON-format object. 
    :rtype: (string, dict or array)

    """
    encoded_params = urllib.urlencode(params)    
    url = query_url + encoded_params
    request = urllib2.Request(url, headers=headers)
    response = urllib2.urlopen(request)
    return (url, json.load(response))

您可以复制GoogleMaps包的来源并尝试修补它。