在从今天开始的学习中,我将学习如何编写一个独立的程序,并对其获取的数据进行可视化。这个程序将使用Web应用编程接口 (API)自动请求网站的特定信息而不是整个网页,再对这些信息进行可视化。由于这样编写的程序始终使用最新的数据来生成可视化,因此即便数据瞬息万变,它呈现的信息也都是最新的。
5.1 使用web API:
Web API 是网站的一部分,用于与使用非常具体的URL请求特定信息的程序交互。这种请求称为API调用。请求的数据将以易于处理的格式(如JSON或CSV)返回。依赖于外部数据源的大多数应用程序都依赖于API调用,如集成社交媒体网站的应用程序。
5.1.1 请求API调用请求数据:
GitHub的API让你能够通过API调用来请求各种信息。要知道API调用是什么样的,请在浏览器的地址栏中输入如下地址并按回车键:
https://api.github.com/search/repositories?q=language:python&sort=stars
这个调用返回GitHub当前托管了多少个Python项目,还有有关最受欢迎的Python仓库的信息。下面来仔细研究这个调用。第一部分(https://api.github.com/
)将请求发送到GitHub网站中响应API调用的部分;接下来的一部分(search/repositories
)让API搜索GitHub上的所有仓库。 repositories
后面的问号指出我们要传递一个实参。q
表示查询,而等号让我们能够开始指定查询(q=
)。通过使用language:python
,我们指出只想获取主要语言为 Python的仓库的信息。最后一部分(&sort=stars
)指定将项目按其获得的星级进行排序。 下面显示了响应的前几行。从响应可知,该URL并不适合人工输入:
从第二行输出可知,在写这篇博客时,GitHub总共有5479229个Python项目。其中包含GitHub上最受欢迎的Python项目的详细信息。
5.1.2 处理API响应:
requests
包让Python程序能够轻松地向网站请求信息,以及检查返回的响应。要安装requests
,请执行类似于下面的命令:
pip3 install requests -i http://pypi.tuna.tsinghua.edu.cn/simple —trusted-host pypi.tuna.tsinghua.edu.cn
下面来编写一个程序,它执行API调用并处理结果,找出GitHub上星级最高的Python项目:
# -*- coding:utf-8 -*-
import requests
# 执行API调用并存储响应
url = 'https://api.github.com/search/repositories?q=language:python&sort=stars'
r = requests.get(url)
print('Staus code:', r.status_code)
# 将API响应存储在一个变量中
response_dict = r.json()
# 处理结果
print(response_dict.keys())
在第3行处,我们导入了模块requests
。在第6行处,我们存储API调用的URL,然后使用requests
来执行调用(见第7行)。我们调用get()
并将URL传递给它,再将响应对象存储在变量r
中。响应对象包含一个名为status_code
的属性,它让我们知道请求是否成功了(状态码200表示请求成功)。在第8行处,我们打印status_code
,核实调用是否成功。这个API返回JSON格式的信息,因此我们使用方法json()
将这些信息转换为一个Python字典(见第11行)。我们将转换得到的字典存储在response_dict
中。最后,我们打印response_dict
中的键。
但是我在运行时却出现了如下的报错:
于是我开启了我电脑上的VPN,问题便得到了解决:
状态码为200,因此请求成功了。响应字典只包含三个键:'items'
、'total_count'
和'incomplete_results'
。
5.1.3 处理响应字典:
将API调用返回的信息存储到字典中后,就可以处理这个字典中的数据了。下面来生成一些概述这些信息的输出。这是一种不错的方式,可确认收到了期望的信息,进而可以开始研究感兴趣的信息:
# -*- coding:utf-8 -*-
import requests
# 执行API调用并存储响应
url = 'https://api.github.com/search/repositories?q=language:python&sort=stars'
r = requests.get(url)
print('Staus code:', r.status_code)
# 将API响应存储在一个变量中
response_dict = r.json()
print('Total repositpries returned:', response_dict['total_count'])
# 探索有关仓库的信息
repo_dicts = response_dict['items']
print('Repositpries returned:', len(repo_dicts))
# 研究第一个仓库
repo_dict = repo_dicts[0]
print('\nKeys:', len(repo_dict))
for key in sorted(repo_dict.keys()):
print(key)
在第12行处,我们打印了与'total_count'
相关联的值,它指出了GitHub总共包含多少个Python仓库。 与'items'
相关联的值是一个列表,其中包含很多字典,而每个字典都包含有关一个Python仓库的信息。在第15行处,我们将这个字典列表存储在repo_dicts
中。接下来,我们打印repo_dicts
的长度,以获悉我们获得了多少个仓库的信息。 为更深入地了解返回的有关每个仓库的信息,我们提取了repo_dicts
中的第一个字典,并将其存储在repo_dict
中(见第20行)。接下来,我们打印这个字典包含的键数,看看其中有多少信息(见第21行)。在第22行处,我们打印这个字典的所有键,看看其中包含哪些信息。 输出让我们对实际包含的数据有了更清晰的认识:
GitHub的API返回有关每个仓库的大量信息:repo_dict
包含74个键。通过仔细查看这些键,可大致知道可提取有关项目的哪些信息。
下面来提取repo_dict
中与一些键相关联的值:
# -*- coding:utf-8 -*-
import requests
# 执行API调用并存储响应
url = 'https://api.github.com/search/repositories?q=language:python&sort=stars'
r = requests.get(url)
print('Staus code:', r.status_code)
# 将API响应存储在一个变量中
response_dict = r.json()
print('Total repositpries returned:', response_dict['total_count'])
# 探索有关仓库的信息
repo_dicts = response_dict['items']
print('Repositpries returned:', len(repo_dicts))
# 研究第一个仓库
repo_dict = repo_dicts[0]
print('\nSelected information about the first repository:')
print('Name:', repo_dict['name'])#打印了项目的名称
print('Owner:',repo_dict['owner']['login'])#用键owner来访问表示所有者的字典,再使用键key来获取所有者的登录名。
print('Stars:', repo_dict['stargazers_count'])#打印项目获得了多少个星的评级
print('Repository:', repo_dict['html_url'])#项目在GitHub仓库的URL
print('Created:', repo_dict['created_at'])#显示项目的创建时间
print('Updated:', repo_dict['updated_at'])#最后一次更新的时间
print('Description:', repo_dict['description'])#打印仓库的描述
在这里,我们打印了表示第一个仓库的字典中与很多键相关联的值。在第23行处,我们打印了项目的名称。项目所有者是用一个字典表示的,因此在第24行处,我们使用键owner
来访问表示所有者的字典,再使用键key
来获取所有者的登录名。在第 25行处,我们打印项目获得了多少个星的评级,以及项目在GitHub仓库的URL。接下来,我们显示项目的创建时间 (见第27行)和最后一次更新的时间(见第28行)。最后,打印仓库的描述。输出如下面这样:
从上述输出可知,在写这篇博客时,GitHub上星级最高的Python项目为system-design-primer,其所有者为用户donnemartin,有106190个GitHub用户给这个项目加星。我们可以看到这个项目的仓库的 URL,其创建时间为2017年2月,且最近更新了。最后,描述指出system-design-primer是用于学习如何设计大规模系统。