使用 Python 从 JSON 资源导入数据
介绍
正如本系列的第一篇指南中所述,可以使用列表和字典轻松操作 JSON 资源(本地文件或 API 响应)。Python 标准库提供了我们读取文件、通过 HTTP 请求查询 API 端点以及处理 JSON 输出所需的所有实用程序。
分析 API 响应格式
为了说明这一点,我们将使用teams ,这是 NBA Open API中可用的端点之一,如图 1 所示
teams API 调用返回两个字典,其键分别为_internal和league。后者由一系列键值对组成,其中键是联赛名称,对应的值是每个联赛中的球队列表。如果我们使用 Web 浏览器访问 URL 并展开standard ,如图 2 所示,我们将识别出熟悉的 Python 字典和列表格式:
严格来说,JSON 由对象和数组组成,它们分别被解码为 Python 字典和列表。同样,JSON 值true、false和null被转换为True、False和None。
图 2 中列表中的每个元素都是一个字典。具体来说,第六项具有以下键值对:
{'isNBAFranchise':True,'isAllStar':False,'city':'Boston','altCityName':'Boston','fullName':'Boston Celtics','tricode':'BOS','teamId':'1610612738','urlName':'celtics','confName':'East','divName':'Atlantic'}
现在我们知道了所选 API 的功能,我们将解释如何使用 Python 进行查询。
从 API 检索数据
虽然有第三方工具可以执行相同的任务(例如请求模块),但在本指南中,我们将使用 Python 现成的实用程序:urllib.request库。
首先,我们将导入库和json模块:
import urllib.request as request
import json
接下来,我们将使用.urlopen()函数打开 URL ,将响应读入名为source的变量,然后使用.loads()将其转换为 JSON 格式。
with request.urlopen('http://data.nba.net/prod/v2/2018/teams.json') as response:
source = response.read()
data = json.loads(source)
或者,您可以选择在继续操作之前检查请求是否成功。为此,请用以下套件替换前一个块:
with request.urlopen('http://data.nba.net/prod/v2/2018/teams.json') as response:
if response.getcode() == 200:
source = response.read()
data = json.loads(source)
else:
print('An error occurred while attempting to retrieve data from the API.')
图 3 显示了数据中的键(_internal和league,正如预期的那样)。由于后者也是一个字典,我们也可以检查它的键:
type(data)
data.keys()
type(data['league'])
data['league'].keys()
最后,我们将更深入地检查标准,如图 4 所示。同一张图片显示了我们之前通过浏览器查询 API 时突出显示的项目:
type(data['league']['standard'])
len(data['league']['standard'])
data['league']['standard'][5]
为了仅包含 NBA 球队,我们可以使用列表推导创建一个名为nba_teams的新列表:
nba_teams = [team for team in data['league']['standard'] if team['isNBAFranchise']]
json模块还提供了一个名为.dump()的方法,用于将 Python 对象写入文件。为了提高可读性,我们可以传递indent = 4和sort_keys = True作为参数,按字母顺序对键进行排序,并使用每个级别的四个空格缩进输出。以下两行将执行此任务并将输出保存到名为nba_teams.json的文件中,其内容部分如图 5 所示:
with open('nba_teams.json', 'w') as f:
json.dump(nba_teams, f, indent = 4, sort_keys = True)
到目前为止,我们已经探索了如何查询 API、操作响应以及将输出保存到本地文件。但如果 JSON 对象首先是从文件提供的,该怎么办?我们现在将学习如何在这种情况下进行操作。
从文件读取 JSON
如果我们需要读取JSON 格式的文件并将其内容转换为 Python 对象,我们将使用json模块中的.load()方法。与以字符串为参数的.loads()相反, .load()需要一个文件对象。简而言之,这两个函数执行相同的任务,但它们处理的输入类型不同。同样,.dumps()将 Python 对象转换为字符串,而.dump()将它们保存到文件中。
以最简单的形式,我们将使用以下套件将nba_teams.json读入名为data的列表类型变量中:
with open('nba_teams.json') as f:
data = json.load(f)
但是,.loads()和.load()都接受一个可用于实现自定义解码器的函数作为可选参数。假设我们想将球队分组到各个赛区(大西洋、中部、东南、西北、太平洋和西南),并返回每个赛区的球队列表。
首先,我们将定义一个名为group_teams_by_division()的函数。此函数将获取文件对象中的每个团队,并将其解码为包含团队名称和部门的元组:
def group_teams_by_division(team):
return (team['fullName'], team['divName'])
接下来,我们将打开文件并传递object_hook = team_by_division作为参数。
with open('nba_teams.json') as f:
data = json.load(f, object_hook = group_teams_by_division)
最后,我们将创建一个字典,其中的键是部门名称,相应的值是该部门中所有团队的列表:
teams_by_division = {}
for i in range(len(data)):
team, division = data[i]
if division not in teams_by_division.keys():
teams_by_division[division] = []
teams_by_division[division].append(team)
请记住,您可以打印字典或使用.dump()将其保存到名为teams_by_division.json的文件中,如图 6 所示:
with open('teams_by_division.json', 'w') as f:
json.dump(teams_by_division, f, indent = 4, sort_keys = True)
此时,您可以使用我们在使用Python 从 Microsoft Excel 文件导入数据中学到的知识来创建电子表格,以便更轻松地进行可视化。
概括
在本指南中,我们学习了如何使用 Python 操作 JSON 资源,包括如何实现自定义解码器。
请随意从Github下载本指南中使用的文件。
免责声明:本内容来源于第三方作者授权、网友推荐或互联网整理,旨在为广大用户提供学习与参考之用。所有文本和图片版权归原创网站或作者本人所有,其观点并不代表本站立场。如有任何版权侵犯或转载不当之情况,请与我们取得联系,我们将尽快进行相关处理与修改。感谢您的理解与支持!
请先 登录后发表评论 ~