【问题标题】:403 Error while geocoding with GoogleMaps使用 Google 地图进行地理编码时出现 403 错误
【发布时间】:2013-10-05 12:12:46
【问题描述】:

我正在尝试使用以下代码,但它不起作用。

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

【问题讨论】:

标签: python google-maps python-2.7


【解决方案1】:

阅读 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)

【讨论】:

    【解决方案2】:

    在此处阅读有关您遇到的错误的一些内容,表明这可能是由于请求未传递足够的标头以使响应正确返回。

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

    查看GoogleMaps 包的源代码,可以看到fetch_json 在没有headers 参数的情况下被调用:

    ...
        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 软件包的源代码并尝试对其进行修补。

    【讨论】:

    • 我尝试将以下行从:url, response = fetch_json(self._GEOCODE_QUERY_URL, params=params) 替换为:url, response = fetch_json(self._GEOCODE_QUERY_URL, params=params, headers=headers) 仍然有问题。请纠正我。
    • @GokulkrishnaSurapureddy headers 设置为什么?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-18
    • 1970-01-01
    • 2021-01-26
    • 1970-01-01
    相关资源
    最近更新 更多