如何在Python

时间:2015-06-19 02:51:57

标签: python json google-geocoding-api

我知道这里有很多这个确切的问题,但我找不到答案。

我正在尝试使用Google Maps API for Geocoding查看草率地址列表,并获取格式化地址。

我有来自Google文档的确切代码:

import urllib2

address="1600+Amphitheatre+Parkway,+Mountain+View,+CA"
url="https://maps.googleapis.com/maps/api/geocode/json?address=%s" % address

response = urllib2.urlopen(url)
jsongeocode = response.read()

然后它说jsongeocode是一个JSON对象。但是,从我在网上看到的是,这不是一个JSON对象。 如果我在这里错了并且它是JSON对象,我该如何解析它?

如果我调用print(jsongeocode),它会在我的终端中打印出具有正确属性的JSON对象。

所以我尝试将jsongeocode对象转换为JSON对象:

jdata = json.load(jsongeocode)

这给了我这个错误:

AttributeError: 'bytes' object has no attribute 'read'

修改

我已将json函数调用切换为jdata = json.loads(jsongeocode),但现在我得到的错误是:

TypeError: The JSON Object must be str, not 'bytes'

3 个答案:

答案 0 :(得分:2)

您的代码在Python 2中运行良好。您只需要使用json.loads(jsongeocode)解析API返回的JSON字符串。

错误消息TypeError: The JSON Object must be str, not 'bytes'向我建议您正在使用Python 3.但是,您正在导入仅存在于Python 2中的urllib2模块。我不确定您是如何实现的。无论如何,假设Python 3:

import json
from urllib.request import urlopen

address="1600+Amphitheatre+Parkway,+Mountain+View,+CA"
url="https://maps.googleapis.com/maps/api/geocode/json?address=%s" % address
response = urlopen(url)
json_byte_string = response.read()

>>> type(json_byte_string)
<class 'bytes'>
>>> jdata = json.loads(json_byte_string)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib64/python3.4/json/__init__.py", line 312, in loads
    s.__class__.__name__))
TypeError: the JSON object must be str, not 'bytes'

所以有你见过的例外情况。 json_byte_string中包含的响应是一个字节字符串 - 它是类bytes,但是,在Python 3中json.loads()期望str是一个Unicode字符串。因此,您需要将json_byte_string从字节字符串转换为Unicode。要做到这一点,您需要知道字节字符串的编码。这里我使用UTF8,因为这是Content-Type响应头中指定的内容:

>>> response.headers['Content-Type']
'application/json; charset=UTF-8'

>>> json_string = str(json_byte_string, 'utf8')
>>> type(json_string)
<class 'str'>

现在可以传递给json.loads()

>>> jdata = json.loads(json_string)
>>> jdata
{'results': [{'types': ['street_address'], 'address_components': [{'types': ['street_number'], 'long_name': '1600', 'short_name': '1600'}, {'types': ['route'], 'long_name': 'Amphitheatre Parkway', 'short_name': 'Amphitheatre Pkwy'}, {'types': ['locality', 'political'], 'long_name': 'Mountain View', 'short_name': 'Mountain View'}, {'types': ['administrative_area_level_2', 'political'], 'long_name': 'Santa Clara County', 'short_name': 'Santa Clara County'}, {'types': ['administrative_area_level_1', 'political'], 'long_name': 'California', 'short_name': 'CA'}, {'types': ['country', 'political'], 'long_name': 'United States', 'short_name': 'US'}, {'types': ['postal_code'], 'long_name': '94043', 'short_name': '94043'}], 'formatted_address': '1600 Amphitheatre Parkway, Mountain View, CA 94043, USA', 'geometry': {'location_type': 'ROOFTOP', 'viewport': {'northeast': {'lng': -122.0828811197085, 'lat': 37.4236854802915}, 'southwest': {'lng': -122.0855790802915, 'lat': 37.4209875197085}}, 'location': {'lng': -122.0842301, 'lat': 37.4223365}}, 'place_id': 'ChIJ2eUgeAK6j4ARbn5u_wAGqWA'}], 'status': 'OK'}

你有解码的JSON字符串作为字典。格式化的地址可用:

>>> jdata['results'][0]['formatted_address']
'1600 Amphitheatre Parkway, Mountain View, CA 94043, USA'

有一种更好的方法:使用requests

import requests

address="1600+Amphitheatre+Parkway,+Mountain+View,+CA"
url="https://maps.googleapis.com/maps/api/geocode/json?address=%s" % address

r = requests.get(url)
jdata = r.json()

>>> jdata['results'][0]['formatted_address']
'1600 Amphitheatre Parkway, Mountain View, CA 94043, USA'

好多了!

答案 1 :(得分:-2)

使用

jsongeocode = str(response.read())
jdata = json.loads(jsongeocode)

json.load()用于类文件对象,如下所述: https://docs.python.org/2/library/json.html#json.load

答案 2 :(得分:-2)

this is my jsongeocode:

 {
   "results" : [
      {
         "address_components" : [
            {
               "long_name" : "1600",
               "short_name" : "1600",
               "types" : [ "street_number" ]
            },
            {
               "long_name" : "Amphitheatre Parkway",
               "short_name" : "Amphitheatre Pkwy",
               "types" : [ "route" ]
            },
            {
               "long_name" : "Mountain View",
               "short_name" : "Mountain View",
               "types" : [ "locality", "political" ]
            },
            {
               "long_name" : "Santa Clara County",
               "short_name" : "Santa Clara County",
               "types" : [ "administrative_area_level_2", "political" ]
            },
            {
               "long_name" : "California",
               "short_name" : "CA",
               "types" : [ "administrative_area_level_1", "political" ]
            },
            {
               "long_name" : "United States",
               "short_name" : "US",
               "types" : [ "country", "political" ]
            },
            {
               "long_name" : "94043",
               "short_name" : "94043",
               "types" : [ "postal_code" ]
            }
         ],
         "formatted_address" : "1600 Amphitheatre Parkway, Mountain View, CA 94043, USA",
         "geometry" : {
            "location" : {
               "lat" : 37.4223365,
               "lng" : -122.0842301
            },
            "location_type" : "ROOFTOP",
            "viewport" : {
               "northeast" : {
                  "lat" : 37.4236854802915,
                  "lng" : -122.0828811197085
               },
               "southwest" : {
                  "lat" : 37.4209875197085,
                  "lng" : -122.0855790802915
               }
            }
         },
         "place_id" : "ChIJ2eUgeAK6j4ARbn5u_wAGqWA",
         "types" : [ "street_address" ]
      }
   ],
   "status" : "OK"
}

你可以找到差异

顺便说一下: 您可以发送http请求使用请求模块:

import requests

address="1600+Amphitheatre+Parkway,+Mountain+View,+CA"
url="https://maps.googleapis.com/maps/api/geocode/json?address=%s" % address

response = requests.get(url)
jsongeocode = response.text