使用Web API

处理API响应

1
2
3
4
5
6
7
8
9
10
11
12
import requests

# 执行API调用并存储响应
url = 'https://api.github.com/search/repositories?q=language:python&sort=stars'
r = requests.get(url)
print("Status code:", r.status_code)

# 将API响应存储在一个变量中
response_dict = r.json()

# 处理结果
print(response_dict.keys())
Status code: 200
dict_keys(['total_count', 'incomplete_results', 'items'])
  • requests.get(url) 发送一个 HTTP GET 请求到指定的 URL
  • r.status_code:返回 HTTP 响应的状态码(例如,200 表示成功)。
  • r.text:返回服务器响应的内容,通常是字符串格式。
  • r.json():如果响应是 JSON 格式,这个方法会将其解析为 Python 字典。
  • r.headers:返回一个字典,包含 HTTP 响应头。
1
print(r.json() == r.text)
False

处理响应字典

1
2
3
# 指出了GitHub总共包含多少个Python仓库
response_dict = r.json()
print("Total repositories:", response_dict['total_count'])
Total repositories: 19262141
1
2
3
# 探索有关仓库的信息,打印出返回的仓库数量
repo_dicts = response_dict['items']
print("Repositories returned:", len(repo_dicts))
Repositories returned: 30
1
2
3
4
5
# 研究第一个仓库,展示第一个仓库的所有信息字段名称
repo_dict = repo_dicts[0]
print("Keys:", len(repo_dict))
for key in sorted(repo_dict.keys()):
print(key)
Keys: 80
allow_forking
archive_url
archived

--snip--

watchers_count
web_commit_signoff_required
1
2
3
4
5
6
7
8
print("Selected information about first repository:")
print('Name:', repo_dict['name']) # 项目名称
print('Owner:', repo_dict['owner']['login']) # 所有者的登录名
print('Stars:', repo_dict['stargazers_count']) # 星数
print('Repository:', repo_dict['html_url']) # url
print('Created:', repo_dict['created_at']) # 创建时间
print('Updated:', repo_dict['updated_at']) # 更新时间
print('Description:', repo_dict['description']) # 描述
Selected information about first repository:
Name: public-apis
Owner: public-apis
Stars: 335516
Repository: https://github.com/public-apis/public-apis
Created: 2016-03-20T23:49:42Z
Updated: 2025-04-13T10:16:49Z
Description: A collective list of free APIs

概述最受欢迎的仓库们

1
2
3
4
5
6
7
8
9
10
print("\nSelected information about each repository:")
for repo_dict in repo_dicts:
print('Name:', repo_dict['name']) # 项目名称
print('Owner:', repo_dict['owner']['login']) # 所有者的登录名
print('Stars:', repo_dict['stargazers_count']) # 星数
print('Repository:', repo_dict['html_url']) # url
print('Created:', repo_dict['created_at']) # 创建时间
print('Updated:', repo_dict['updated_at']) # 更新时间
print('Description:', repo_dict['description']) # 描述
print()
Selected information about each repository:
Name: public-apis
Owner: public-apis
Stars: 335516
Repository: https://github.com/public-apis/public-apis
Created: 2016-03-20T23:49:42Z
Updated: 2025-04-13T10:16:49Z
Description: A collective list of free APIs

Name: awesome-python
Owner: vinta
Stars: 240274
Repository: https://github.com/vinta/awesome-python
Created: 2014-06-27T21:00:06Z
Updated: 2025-04-13T10:19:56Z
Description: An opinionated list of awesome Python frameworks, libraries, software and resources.

Name: Python
Owner: TheAlgorithms
Stars: 199370
Repository: https://github.com/TheAlgorithms/Python
Created: 2016-07-16T09:44:01Z
Updated: 2025-04-13T10:20:03Z
Description: All Algorithms implemented in Python

--snip--

Name: private-gpt
Owner: zylon-ai
Stars: 55613
Repository: https://github.com/zylon-ai/private-gpt
Created: 2023-05-02T09:15:31Z
Updated: 2025-04-13T10:11:15Z
Description: Interact with your documents using the power of GPT, 100% privately, no data leaks

使用Pygal可视化仓库

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import requests
import pygal
from pygal.style import LightColorizedStyle as LCS, LightenStyle as LS
from IPython.display import SVG

# 执行API调用并存储响应
URL = 'https://api.github.com/search/repositories?q=language:python&sort=stars'
r = requests.get(URL)
print("Status code:", r.status_code)

# 将API响应存储在一个变量中
response_dict = r.json()
print("Total repositories:", response_dict['total_count'])

# 研究有关仓库的信息
repo_dicts = response_dict['items']

names, stars = [], []
for repo_dict in repo_dicts:
names.append(repo_dict['name'])
stars.append(repo_dict['stargazers_count'])

# 可视化
my_style = LS('#333366', base_style=LCS)
chart = pygal.Bar(style=my_style, x_label_rotation=45, show_legend=False)
chart.title = 'Most-Starred Python Projects on GitHub'
chart.x_labels = names

chart.add('', stars)
chart.render_to_file('python_repos.svg')
SVG('python_repos.svg')
Status code: 200
Total repositories: 18404773

svg

改进Pygal图表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
my_config = pygal.Config()
my_config.x_label_rotation = 45
my_config.show_legend = False
my_config.title_font_size = 24
my_config.label_font_size = 14
my_config.major_label_font_size = 18
my_config.truncate_label = 15
my_config.show_y_guides = False
my_config.width = 1000

chart = pygal.Bar(my_config, style=my_style)
chart.title = 'Most-Starred Python Projects on GitHub'
chart.x_labels = names

chart.add('', stars)
chart.render_to_file('python_repos.svg')
SVG('python_repos.svg')

svg

  • pygal.Config() 创建了一个Pygal类Config的实例
    • x_label_rotation = 45 将 x 轴标签旋转 45 度
    • show_legend = False 不显示图例
    • title_font_size 图标便签字体大小
    • label_font_size 标签的字体大小
    • major_label_font_size 主标签的字体大小
    • truncate_label = 15 如果标签太长,将其截断为 15 个字符
    • show_y_guides = False 不显示 y 轴的辅助线
    • width 宽度
    • height 高度

添加自定义工具提示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import pygal
from pygal.style import LightColorizedStyle as LCS, LightenStyle as LS
from IPython.display import SVG

my_style = LS('#333366', base_style=LCS)
chart = pygal.Bar(style=my_style, x_label_rotation=45, show_legend=False)

chart.title = 'Python Projects'
chart.x_labels = ['httpie', 'django', 'flask']

plot_dicts = [
{'value': 16101, 'label': 'Description of httpie.'},
{'value': 15028, 'label': 'Description of django.'},
{'value': 14798, 'label': 'Description of flask.'},
]

chart.add('', plot_dicts)
chart.render_to_file('bar_descriptions.svg')
SVG('bar_descriptions.svg')

svg

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import requests
import pygal
from pygal.style import LightColorizedStyle as LCS, LightenStyle as LS
from IPython.display import SVG

URL = 'https://api.github.com/search/repositories?q=language:python&sort=stars'
r = requests.get(URL)
print("Status code:", r.status_code)

response_dict = r.json()
print("Total repositories:", response_dict['total_count'])

repo_dicts = response_dict['items']

names, plot_dicts = [], []
for repo_dict in repo_dicts:
names.append(repo_dict['name'])

plot_dict = {
'value': repo_dict['stargazers_count'],
'label': repo_dict['description'],
}
plot_dicts.append(plot_dict)

my_style = LS('#333366', base_style=LCS)
chart = pygal.Bar(style=my_style, x_label_rotation=45, show_legend=False)
chart.title = 'Most-Starred Python Projects on GitHub'
chart.x_labels = names

chart.add('', plot_dicts)
chart.render_to_file('python_repos.svg')
SVG('python_repos.svg')
Status code: 200
Total repositories: 18714822

svg

在图表中添加可单击的链接

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
names, plot_dicts = [], []
for repo_dict in repo_dicts:
names.append(repo_dict['name'])

plot_dict = {
'value': repo_dict['stargazers_count'],
'label': repo_dict['description'],
'xlink': repo_dict['html_url'], # 添加链接
}
plot_dicts.append(plot_dict)

my_style = LS('#333366', base_style=LCS)
chart = pygal.Bar(style=my_style, x_label_rotation=45, show_legend=False)
chart.title = 'Most-Starred Python Projects on GitHub'
chart.x_labels = names

chart.add('', plot_dicts)
chart.render_to_file('python_repos.svg')
SVG('python_repos.svg')

svg

Hacker News API

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import requests

from operator import itemgetter

# Make an API call, and store the response.
url = 'https://hacker-news.firebaseio.com/v0/topstories.json'
r = requests.get(url)
print("Status code:", r.status_code)

# Process information about each submission.
submission_ids = r.json()
submission_dicts = []
for submission_id in submission_ids[:30]:
# Make a separate API call for each submission.
url = ('https://hacker-news.firebaseio.com/v0/item/' +
str(submission_id) + '.json')
submission_r = requests.get(url)
print(submission_r.status_code)
response_dict = submission_r.json()

submission_dict = {
'title': response_dict['title'],
'link': 'http://news.ycombinator.com/item?id=' + str(submission_id),
'comments': response_dict.get('descendants', 0)
}
submission_dicts.append(submission_dict)

submission_dicts = sorted(submission_dicts, key=itemgetter('comments'),
reverse=True)

for submission_dict in submission_dicts:
print("\nTitle:", submission_dict['title'])
print("Discussion link:", submission_dict['link'])
print("Comments:", submission_dict['comments'])

Status code: 200
200
--snip--

Title: Experimental release of GrapheneOS for Pixel 9a
Discussion link: http://news.ycombinator.com/item?id=43669185
Comments: 152

Title: I ditched my laptop for a pocketable mini PC and a pair of AR glasses
Discussion link: http://news.ycombinator.com/item?id=43668192
Comments: 146

Title: The Bitter Prediction
Discussion link: http://news.ycombinator.com/item?id=43662686
Comments: 108

Title: YAML: The Norway Problem (2022)
Discussion link: http://news.ycombinator.com/item?id=43668290
Comments: 105

Title: Open source and self hostable/private file converter
Discussion link: http://news.ycombinator.com/item?id=43663865
Comments: 102

Title: BPS is a GPS alternative that nobody's heard of
Discussion link: http://news.ycombinator.com/item?id=43669308
Comments: 94

Title: CERN releases report on the feasibility of a possible Future Circular Collider
Discussion link: http://news.ycombinator.com/item?id=43632828
Comments: 82

Title: Nice things with SVG
Discussion link: http://news.ycombinator.com/item?id=43666439
Comments: 81

Title: WebTUI – A CSS Library That Brings the Beauty of Terminal UIs to the Browser
Discussion link: http://news.ycombinator.com/item?id=43668250
Comments: 64

Title: ArkType: Ergonomic TS validator 100x faster than Zod
Discussion link: http://news.ycombinator.com/item?id=43665540
Comments: 59

Title: Tunarr: Create and configure live TV channels from media on your servers
Discussion link: http://news.ycombinator.com/item?id=43665201
Comments: 49

Title: Emacs Lisp Elements
Discussion link: http://news.ycombinator.com/item?id=43665046
Comments: 39

Title: Why is there a “small house” in IBM's Code page 437?
Discussion link: http://news.ycombinator.com/item?id=43667010
Comments: 39

Title: Whenever – typed and DST-safe datetimes for Python
Discussion link: http://news.ycombinator.com/item?id=43671308
Comments: 38

Title: Go channels are bad (2016)
Discussion link: http://news.ycombinator.com/item?id=43670373
Comments: 36

Title: Show HN: memEx, a personal knowledge base inspired by zettlekasten and org-mode
Discussion link: http://news.ycombinator.com/item?id=43667061
Comments: 29

Title: Philip K. Dick: Stanisław Lem Is a Communist Committee
Discussion link: http://news.ycombinator.com/item?id=43660520
Comments: 20

Title: How to not build a two stage model rocket
Discussion link: http://news.ycombinator.com/item?id=43669981
Comments: 19

Title: Show HN: Chonky – a neural approach for text semantic chunking
Discussion link: http://news.ycombinator.com/item?id=43652968
Comments: 16

Title: How to repair the parts that explode in Lenovo Yoga laptops (2019)
Discussion link: http://news.ycombinator.com/item?id=43669887
Comments: 15

Title: A Farewell to the ArcoLinux University
Discussion link: http://news.ycombinator.com/item?id=43669990
Comments: 11

Title: Facebook is just Craigslist now
Discussion link: http://news.ycombinator.com/item?id=43671994
Comments: 7

Title: Microgravity 101
Discussion link: http://news.ycombinator.com/item?id=43648423
Comments: 6

Title: How I install personal versions of programs on Unix
Discussion link: http://news.ycombinator.com/item?id=43662031
Comments: 3

Title: Nominal Aphasia: Problems in Name Retrieval
Discussion link: http://news.ycombinator.com/item?id=43648536
Comments: 3

Title: Cross-Entropy and KL Divergence
Discussion link: http://news.ycombinator.com/item?id=43670171
Comments: 3

Title: The Dark Side of the Moomins
Discussion link: http://news.ycombinator.com/item?id=43672593
Comments: 2

Title: Dust in the wind: How cities alter natural airborne particles
Discussion link: http://news.ycombinator.com/item?id=43631398
Comments: 1

Title: RNA interference and nanomedicine team up to fight dangerous fungal infections
Discussion link: http://news.ycombinator.com/item?id=43645925
Comments: 0

Title: How to Structure a B2B Marketplace Venture
Discussion link: http://news.ycombinator.com/item?id=43668876
Comments: 0

在本章中,你学习了:如何使用API来编写独立的程序,它们自动采集所需的数据并对其进行可视化;使用GitHub API来探索GitHub上星级最高的Python项目,还大致地了解了Hacker News API;如何使用requests包来自动执行GitHub API调用,以及如何处理调用的结果。我们还简要地介绍了一些Pygal设置,使用它们可进一步定制生成的图表的外观。 在本书的最后一个项目中,我们将使用Django来创建一个Web应用程序。