如何解析 Python 中的 JSON 对象
How to parse through JSON object in Python
我知道这里有很多确切的问题,但我找不到答案。
我正在尝试使用 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'
使用
jsongeocode = str(response.read())
jdata = json.loads(jsongeocode)
json.load()
用于类文件对象,如下所述:
https://docs.python.org/2/library/json.html#json.load
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"
}
你可以找到不同之处
顺便说一句:
你可以像这样使用 Requests 模块发送 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
您的代码在 Python 中运行良好 2. 您只需要使用 json.loads(jsongeocode)
.
解析 API 返回的 JSON 字符串
错误消息 TypeError: The JSON Object must be str, not 'bytes'
提示我您正在使用 Python 3。但是,您正在导入仅存在于 Python 中的 urllib2
模块 2 .我不确定你是怎么做到的。无论如何,假设 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
中包含的响应是一个字节字符串 - 它属于 class bytes
,但是,在 Python 3 json.loads()
中需要一个 str
是一个 Unicode 字符串。所以你需要将 json_byte_string
从字节字符串转换为 Unicode。为此,您需要知道字节串的编码。这里我使用 UTF8,因为这是 Content-Type
响应中指定的 header:
>>> 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'
好多了!
我知道这里有很多确切的问题,但我找不到答案。
我正在尝试使用 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'
使用
jsongeocode = str(response.read())
jdata = json.loads(jsongeocode)
json.load()
用于类文件对象,如下所述:
https://docs.python.org/2/library/json.html#json.load
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"
}
你可以找到不同之处
顺便说一句: 你可以像这样使用 Requests 模块发送 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
您的代码在 Python 中运行良好 2. 您只需要使用 json.loads(jsongeocode)
.
错误消息 TypeError: The JSON Object must be str, not 'bytes'
提示我您正在使用 Python 3。但是,您正在导入仅存在于 Python 中的 urllib2
模块 2 .我不确定你是怎么做到的。无论如何,假设 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
中包含的响应是一个字节字符串 - 它属于 class bytes
,但是,在 Python 3 json.loads()
中需要一个 str
是一个 Unicode 字符串。所以你需要将 json_byte_string
从字节字符串转换为 Unicode。为此,您需要知道字节串的编码。这里我使用 UTF8,因为这是 Content-Type
响应中指定的 header:
>>> 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'
好多了!