使用Python requests
模块访问People in Space API,并创建一个指示灯,以显示当前在空间中的人数。
2015年12月15日,英国欧空局宇航员蒂姆·帕克(Tim Peake)起飞到国际空间站,他将在那里工作六个月。作为Astro Pi项目的一部分,Tim还将在太空中进行科学研究,他还将使用由两名Raspberry Pis学生学习的Python代码进行实验。通过这个资源,你可以保持蒂姆和他的宇航员在国际空间站上的数量。
API代表应用程序编程接口。一种形式的API是一种Web API,可用于从在线提供的服务中提取数据。一些API对公众开放,免费提供数据; 其他API需要登录才能访问它们,这可以通过应用程序获取,或者可以作为服务提供给客户收费。
通过API提供数据的目的是允许人们访问它以供自己使用或使用它来构建程序。一些API提供业务关键数据集或其他重要数据,例如天气,金融活动,甚至提供访问Twitter流或Flickr的照片等。其他API只是为了好玩,如口袋妖怪API,星球大战API或冒险时间API。虽然这些API是有趣的,但它们仍然可以用于有趣和有用的方式。您可以在Minecraft中建立一个宠物小精灵游戏,或在冒险时间内建立关于角色的问答游戏!
对于这个项目,您将使用Nathan Bergey免费维护和提供的People in Space API。
http://api.open-notify.org/astros.json
您正在查看API提供的数据。这是访问数据的手动方法。
{
"message": "success",
"number": 6,
"people": [
{
"craft": "ISS",
"name": "Mikhail Kornienko"
},
...
}
该数据的格式称为JSON(发音为“Jason”),代表JavaScript Object Notation。虽然这个名字是指JavaScript的编程语言,但它是一种标准的数据交换格式,可以在语言和应用程序之间移植。如果您熟悉Python的dictionary
数据结构,您将看到相似之处。在其他语言中,嵌套数组可以以相同的方式使用。
message
,number
,和people
。
message
是包含该单词的单个字符串 success
number
是整数值 6
people
是一群宇航员people
阵列中,有六个对象。每个对象包含两个数据:
craft
是宇航员在哪里的航天器name
是宇航员的全名现在您将使用requests
Python中的模块来访问API。
>>> import requests
Python
Copy
(注意>>>
不是键入,而是表示shell输入)
您正在使用Python shell的REPL(Read-Eval-Print Loop),这意味着每一行都会立即执行,而不是写入一个文件,保存并一次运行所有命令
url = "http://api.open-notify.org/astros.json"
Python
Copy
r = requests.get(url)
Python
Copy
r
并按Enter键 ; 这与输入print(r)
文件相同。REPL允许您以这种方式快速检查对象。您现在应该看到以下内容:
<Response [200]>
这表示r
包含一个Response
类型对象,并显示200
。这是请求的状态代码,这意味着“成功”。其他状态代码包括404
,这意味着“找不到文件”和500
– “服务器错误”。
help(r)
。这显示对象的docstring(文档字符串)Response
。你应该看到:
Help on Response in module requests.models object:
class Response(builtins.object)
| The :class:`Response <Response>` object, which contains a
| server's response to an HTTP request.
...
Data descriptors defined here
。您将看到可用属性及其描述的列表,包括:
这些属性本质上是一个对象内可访问的变量。例如,r.ok
是包含请求(True
或False
)的成功状态的变量。
apparent_encoding
content
is_permanent_redirect
is_redirect
links
ok
text
>>> r.okTrue>>> r.is_redirectFalse>>> r.text
'{\n "message": "success", \n "number": 6...
Python
Copy
你会看到r.text
似乎包含你需要的数据。然而,这被提供为使其难以使用的字符串。
Methods defined here
docstring 的部分,其中包括:
json(self, **kwargs)
Returns the json-encoded content of a response, if any.
Bash
Copy
这可以让您以JSON格式访问URL请求的内容,这将使其更有用。
一种方法是属于一个对象的函数。它以与属性相同的方式访问,但被称为像()
例如函数r.json()
r.json()
。你应该看到:
{'number': 6, 'message': 'success', 'people': [{'craft': 'ISS', 'name': 'Mikhail Kornienko'}, {'craft': 'ISS', 'name': 'Scott Kelly'}, {'craft': 'ISS', 'name': 'Oleg Kononenko'}, {'craft': 'ISS', 'name': 'Kimiya Yui'}, {'craft': 'ISS', 'name': 'Kjell Lindgren'}, {'craft': 'ISS', 'name': 'Sergey Volkov'}]}
Bash
Copy
j = r.json()
Python
Copy
type(j)
>>> type(j)<class 'dict'>
Python
Copy
你会看到这j
是一个字典,它是Python中非常有用的数据结构,基本上与JSON格式相同。
[]
:
>>> j['number']6
Python
Copy
而已!
import requests
url = "http://api.open-notify.org/astros.json"r = requests.get(url)j = r.json()n = j['number']print(n)
Python
Copy
接下来,您将连接一些LED到Pi的GPIO引脚,并使用它们来代表一个人在空间。
>>> from gpiozero import LED
Python
Copy
LED
在引脚2上创建一个对象的实例:
>>> led = LED(2)
Python
Copy
>>> led.on()
Python
Copy
LED现在应该点亮!
>>> led.close()
Python
Copy
>>> pins = [2, 3, 4, 14, 15, 17, 18, 27, 22, 23]
Python
Copy
>>> leds = [LED(pin) for pin in pins]
Python
Copy
这被称为列表理解:在一行中生成列表而不是使用传统的循环。
leds
列表:
>>> leds[<gpiozero.LED object on pin=2, is_active=False>,<gpiozero.LED object on pin=3, is_active=False>,<gpiozero.LED object on pin=4, is_active=False>,<gpiozero.LED object on pin=14, is_active=False>,...]
Python
Copy
这将打印列表中每个对象的表示,显示一些有用的信息。
leds
通过将它们全部打开来测试列表:
>>> [led.on() for led in leds]
Python
Copy
这是列表理解的另一个用途:在列表中的每个项目上运行命令
>>> [led.off() for led in leds]
Python
Copy
提示:使用Alt + P
(上一个)完成命令历史记录并编辑输入的最后一个命令。
现在,您将使用LED显示当前在空间中的人数。
File > New File
。astronauts.py
from gpiozero import LEDimport requests
Python
Copy
pins = [2, 3, 4, 14, 15, 17, 18, 27, 22, 23]leds = [LED(p) for p in pins]
Python
Copy
requests
代码:
url = "http://api.open-notify.org/astros.json"r = requests.get(url)j = r.json()n = j['number']
Python
Copy
n
,您可以使用它来确定应该点亮多少个LED。考虑以下循环:
for led in leds:
led.on()
Python
Copy
这允许您依次访问每个LED。但是,我们需要知道什么时候我们应该停止这样做。
n
每个LED号码(序列中的顺序,而不是GPIO引脚号)的数字。您将需要使用该enumerate
功能按顺序为每个LED分配一个数字。enumerate
通过在shell中尝试它(而不是文件)来查看它的工作原理:
>>> list(enumerate(leds))[(0, <gpiozero.LED object on pin=2, is_active=False>),
(1, <gpiozero.LED object on pin=3, is_active=False>),
(2, <gpiozero.LED object on pin=4, is_active=False>),...]
Python
Copy
您可以看到,它提供了与索引号相关联的LED列表,从0
。
enumerate
返回两个值,索引号和LED对象,您可以循环使用它并通过使用访问这两个值for i, led in enumerate(leds)
。将以下循环添加到文件中的代码中:
for i, led in enumerate(leds):
if n > i:
led.on()
else:
led.off()
Python
Copy
6
,你应该有6个LED点亮!sleep
在其他文件的顶部添加导入:
from time import sleep
Python
Copy
requests
和LED
代码进行while
循环,使其持续运行并不断更新LED:
while True:
r = requests.get(url)
j = r.json()
n = j['number']
for i, led in enumerate(leds):
if n > i:
led.on()
else:
led.off()
sleep(60) # update every minute
Python
Copy
确保最后添加睡眠,所以它在API调用之间等待60秒钟,以便每分钟检查一次结果。
尝试用木头或纸板制作自己的指示器:
最后,学习从API调用中获取宇航员名字。
j['people']
从字典检查:
>>> type(j['people'])<class 'list'>>>> j['people'][{'craft': 'ISS', 'name': 'Mikhail Kornienko'}, {'craft': 'ISS', 'name': 'Scott Kelly'}, {'craft': 'ISS', 'name': 'Oleg Kononenko'}, {'craft': 'ISS', 'name': 'Kimiya Yui'}, {'craft': 'ISS', 'name': 'Kjell Lindgren'}, {'craft': 'ISS', 'name': 'Sergey Volkov'}]
Python
Copy
j['people']
是一个列表。现在进一步检查清单:
>>> len(j['people'])6>>> type(j['people'][0])<class 'dict'>>>> j['people'][0]{'craft': 'ISS', 'name': 'Mikhail Kornienko'}
Python
Copy
>>> type(j['people'][0]['craft'])<class 'str'>>>> j['people'][0]['craft']'ISS',>>> type(j['people'][0]['name'])<class 'str'>>>> j['people'][0]['name']'Mikhail Kornienko'>>> j['people'][1]['name']'Scott Kelly'
Python
Copy
>>> for astronaut in j['people']:
print(astronaut['name'])Mikhail Kornienko
Scott Kelly
Oleg Kononenko
Kimiya Yui
Kjell Lindgren
Sergey Volkov
Python
Copy
n
:
n = j['number']astronauts = j['people']
Python
Copy
[led.off() for led in leds]
Python
Copy
if n > i
声明内,之后led.on()
,添加两行打印宇航员姓名,然后睡眠1秒,以便在每个光线之间暂停:
if n > i:
led.on()
print(astronauts[i]['name'])
sleep(1)
Python
Copy
现在,您已经创建了一个带LED指示灯的People in Space Indicator,尝试扩展您的项目:
requests
另一个API来查找有关每个宇航员的信息