如何使用 API:使用 NASA 的开放 API 获取每日图像
应用程序编程接口(API)是一组用于访问Web应用程序的指令。今天,我们将使用Python和NASA的开放API来创建一个程序,该程序可以获取每日天文图像。
本文由 Pratik Shukla 撰写,是其天文游戏系列文章的一部分。
谁不喜欢那些迷人的太空图片呢!
美国国家航空航天局(NASA)通过每日天文图片服务提供令人惊叹的天文图像。在本教程中,我们将使用NASA API和nasa.py库来获取这些图像。
应用程序编程接口 (API) 是一组用于访问 Web 应用程序的指令和标准。API 是一种非常有用的工具,它允许我们公开共享信息。学习如何使用 API 的最佳方法是自己编写程序。
今天,我们将学习如何下载和显示每日天文图像。首先,我们将获取今天的图像。然后,我们将对代码进行一些修改,以便自动获取任意日期的图像。
今天我们将讨论以下内容:
使用 NASA 的 API 获取当日天文图片
在以下程序中,我们将使用NASA的开放API下载今天的每日天文图片(APOD)。该程序只会下载图像文件。如果今天没有可用的图像文件,它将打印一条消息:“图像不可用”。
如果图像文件可用,它将被下载到本地系统。然后,我们的代码将从本地系统获取图像并将其与任何附加信息(例如标题、URL)一起显示出来。
接下来,我们的代码会询问用户是否想收听图像的语音解说。如果用户选择收听语音解说,我们将使用 Google 文本转语音 (GTTS) 库将文本解说转换为音频文件并播放。
注意:要访问 NASA 提供的服务,我们需要一个已注册的 API 密钥。要获取 API 密钥,只需在 NASA API 网站上填写一份表格
demo_key即可。我们也可以使用.我们可以通过注册的 API 每小时发出 1000 个请求,而通过其他方式
demo_key,我们每天只能发出 50 个请求。注册成功后,您将在提供的邮箱地址收到一个 API 密钥。我们将在本教程的后续步骤中使用此密钥。
Python实现(5个步骤)
步骤 1:导入所需库
#Import required libraries:
import nasapy
import os
from datetime import datetime
import urllib.request
from IPython.display import Image,display,Audio
from gtts import gTTS
nasapy我们将使用 nasapy 库来访问 NASA API 提供的信息。os要将图像存储在特定目录中,我们使用 os 库。datetime我们在向 NASA API 发送请求以获取信息时会使用日期。为了获取特定格式的日期,我们将使用 datetime 库。urllib我们从 NASA API 获取的图像将以 URL 的形式呈现,因此我们使用 urllib 来获取它。Ipython我们需要使用 Ipython 库在 Jupyter Notebook 中显示图像。我们还将使用音频模块播放图像的语音解说。gtts我们使用 Google 文本转语音库将图像的文字说明转换为音频文件。
步骤 2. 创建 NASA 类的对象
接下来,我们将创建一个名为 `<object>` 的对象nasa。我们将使用nasapy库和我们注册的 API 密钥。我们将使用此对象调用类的一个方法Nasa来获取天文图像信息。
#Initialize Nasa class by creating an object:
k = "523p5hPYHGzafYGLCkqa54kKMTV2vbP0XcPxkcLm"
nasa = nasapy.Nasa(key = k)
步骤 3. 获取所需格式的日期
要获取特定日期的图像,我们需要传入特定格式的日期。日期格式要求YYYY-MM-DD使用datetime.today()函数实现。因此,我们需要使用该strftime(%Y-%m-%d)函数将此元组转换为字符串。
#Get today's date in YYYY-MM-DD format:
d = datetime.today().strftime('%Y-%m-%d')
步骤 4:从 NASA 的 API 获取信息
现在我们已经获得了格式正确的日期,可以请求获取今天的天文图像了。这里我们使用相应的picture_of_the_day()方法来获取图像数据。
#Get the image data:
apod = nasa.picture_of_the_day(date=d, hd=True)
我们的 apod 变量是一个包含各种键和值的字典。让我们来看看这个变量的键:
datetitlecopyrightexplanationurlhdurlmedia_typeservice_version
步骤 5. 显示图像和其他信息
#POINT A:
#Check the media type available:
if(apod["media_type"] == "image"):
#POINT B:
#Displaying hd images only:
if("hdurl" in apod.keys()):
#POINT C:
#Saving name for image:
title = d + "_" + apod["title"].replace(" ","_").replace(":","_") + ".jpg"
#POINT D:
#Path of the directory:
image_dir = "./Astro_Images"
#Checking if the directory already exists?
dir_res = os.path.exists(image_dir)
#If it doesn't exist then make a new directory:
if (dir_res==False):
os.makedirs(image_dir)
#If it exist then print a statement:
else:
print("Directory already exists!\n")
#POINT E:
#Retrieving the image:
urllib.request.urlretrieve(url = apod["hdurl"] , filename = os.path.join(image_dir,title))
#POINT F:
#Displaying information related to image:
if("date" in apod.keys()):
print("Date image released: ",apod["date"])
print("\n")
if("copyright" in apod.keys()):
print("This image is owned by: ",apod["copyright"])
print("\n")
if("title" in apod.keys()):
print("Title of the image: ",apod["title"])
print("\n")
if("explanation" in apod.keys()):
print("Description for the image: ",apod["explanation"])
print("\n")
if("hdurl" in apod.keys()):
print("URL for this image: ",apod["hdurl"])
print("\n")
#POINT G:
#Displaying main image:
display(Image(os.path.join(image_dir,title)))
#Point H:
#Text to Speech Conversion:
#Take input from user:
print("\n")
choice = input("Press * to hear the audio explanation : ")
if(choice=="*"):
#Text to be converted:
mytext = apod["explanation"]
#mytext="Good Evening Pratik."
#Creating an object:
myobj = gTTS(text=mytext, lang="en", slow=False)
#Generating audio file name:
audio_title = d + "_" + apod["title"] + ".mp3"
#Save the converted file:
myobj.save(os.path.join(image_dir,audio_title))
#Name of sound file:
sound_file = os.path.join(image_dir,audio_title)
# Playing the converted file
display(Audio(sound_file, autoplay=True))
#POINT I:
#If media type is not image:
else:
print("Sorry, Image not available!")
现在我们将逐段理解代码。
显示图片:
- 首先,我们只会展示图片。
- 其次,我们只对高清图像感兴趣。因此,如果图像是标清的,我们就不会进入循环。
- 现在,我们需要遵循一定的命名结构来保存图像。这里,我们将使用图像日期、图像标题和图像扩展名作为文件名。
- 我们还用下划线代替冒号和空格。
创建目录:
- 现在我们需要一个特定的目录来存储图片。我们使用 os 库创建一个目录。为了检查目录是否存在,我们使用
.exist()一个函数。如果目录不存在,则使用.makedirs()另一个函数创建它。 - 现在我们使用从 apod 变量中获取的 URL 来获取图像。获取图像的过程是使用该
urllib.request.urlretrieve()函数完成的。 - 我们还使用
os.path.join()指定标题名称将图像存储在新创建的目录中。 - 我们过去
apod[“hdurl”]常常下载图片。
显示其他信息:
- 现在我们已经将图片下载到指定目录,接下来要显示与该图片相关的其他信息。我们会检查指定的键值是否存在。如果存在,则显示其值。
Image()然后我们使用Ipython 库的函数显示主图像。
音频讲解:
- 现在图片和其他信息已经显示完毕,我们会询问用户是否想听图片的解释。如果用户按下按钮
*,我们会使用 Google 的文本转语音 (Text to Speechgtts) 库将文本转换为音频文件。 - 我们创建一个对象,它接收待转换的文本、语速和语言作为输入。然后,我们将这些信息存储在带有特定
.mp3扩展名的特定目录中。 - 然后我们使用该
Audio()函数在 jupyter notebook 中播放音频文件。 - 如果媒体类型不是图像,我们会打印一条简短的消息,说明“图像不可用”。
请运行以下 Google Collaboratory 文件以查看正确的输出结果。您可以在Google Collaboratory上在线下载并运行此代码文件。
根据日期值获取天文图像
但如果用户想要获取特定日期的图片呢?很简单!我们不用今天的日期,而是从用户那里获取指定格式的日期,并将其作为参数传递。这就是代码中唯一的区别。请查看下面的完整代码。
#Import required libraries:
import nasapy
import os
from datetime import datetime
import urllib.request
from IPython.display import Image,display,Audio
from gtts import gTTS
#Initialize Nasa class by creating an object:
nasa = nasapy.Nasa(key="523p5hPYHGzafYGLCkqa54kKMTV2vbP0XcPxkcLm")
#Get today's date in YYYY-MM-DD format:
d = input("Enter date in YYYY-MM-DD format : ")
#Get the image data:
apod = nasa.picture_of_the_day(date=d, hd=True)
#POINT A:
#Check the media type available:
if(apod["media_type"] == "image"):
#POINT B:
#Displaying hd images only:
if("hdurl" in apod.keys()):
#POINT C:
#Saving name for image:
title = d + "_" + apod["title"].replace(" ","_").replace(":","_") + ".jpg"
#POINT D:
#Path of the directory:
image_dir = "Astro_Images"
#Checking if the directory already exists?
dir_res = os.path.exists(image_dir)
#If it doesn't exist then make a new directory:
if (dir_res==False):
os.makedirs(image_dir)
#If it exist then print a statement:
else:
print("Directory already exists!\n")
#POINT E:
#Retrieving the image:
urllib.request.urlretrieve(url = apod["hdurl"] , filename = os.path.join(image_dir,title))
#POINT F:
#Displaying information related to image:
if("date" in apod.keys()):
print("Date image released: ",apod["date"])
print("\n")
if("copyright" in apod.keys()):
print("This image is owned by: ",apod["copyright"])
print("\n")
if("title" in apod.keys()):
print("Title of the image: ",apod["title"])
print("\n")
if("explanation" in apod.keys()):
print("Description for the image: ",apod["explanation"])
print("\n")
if("hdurl" in apod.keys()):
print("URL for this image: ",apod["hdurl"])
print("\n")
#POINT G:
#Displaying main image:
display(Image(os.path.join(image_dir,title)))
#Point H:
#Text to Speech Conversion:
#Take input from user:
print("\n")
choice = input("Press * to hear the audio explanation : ")
if(choice=="*"):
#Text to be converted:
mytext = apod["explanation"]
#mytext="Good Evening Pratik."
#Creating an object:
myobj = gTTS(text=mytext, lang="en", slow=False)
#Generating audio file name:
audio_title = d + "_" + apod["title"] + ".mp3"
#Save the converted file:
myobj.save(os.path.join(image_dir,audio_title))
#Name of sound file:
sound_file = os.path.join(image_dir,audio_title)
# Playing the converted file
display(Audio(sound_file, autoplay=True))
#POINT I:
#If media type is not image:
else:
print("Sorry, Image not available!")
请运行以下 Google Collaboratory 文件以查看正确的输出结果。您可以在Google Collaboratory上在线下载并运行此代码文件。
下载一系列日期的天文图像
既然我们已经知道如何下载并显示特定日期的图片,现在是时候更进一步了。我们将下载一系列日期的图片,并从中随机选择一张显示出来。下面我们来看看如何实现这一点。
Python实现(9步)
步骤 1:导入所需库
这些库与我们之前使用的库相同。
These are the same libraries we used previously.
#Import required libraries:
import nasapy
import os
import pandas as pd
import urllib.request
from IPython.display import Image,display
步骤 2:创建 NASA 类的对象
接下来我们将创建一个名为 `<object>` 的对象nasa。我们将使用 nasapy 库和我们注册的 API 密钥。我们将使用此对象调用 Nasa 类的一个方法来获取天文图像的信息。
#Initialize Nasa class by creating an object:
k = "523p5hPYHGzafYGLCkqa54kKMTV2vbP0XcPxkcLm"
nasa = nasapy.Nasa(key = k)
步骤 3:获取日期列表
我们需要下载多个日期对应的多张图片。因此,我们将使用pandas 库date_range()的函数。该函数会返回所需格式的日期列表。其中,period 值决定了列表的范围。
我们将下载 5 张图片,但您可以通过调整句点和结束值来下载任意数量的图片。
#Get a list of dates:
dates = pd.date_range(end = '2020-08-15', periods=5)
第四步:获取数据
之前我们只有一张图片。但这次我们要下载多张图片。为此,我们创建一个空列表,用字典的形式存储所有图片的对应值。
首先,我们将获取日期值并将其存储在 apod 变量中。然后,我们将以字典形式获取所需信息并将其添加到列表中。
#Empty list to store dictionary keys and values:
data = []
#Getting all the data:
for d in dates:
apod = nasa.picture_of_the_day(d, hd=True)
if apod['media_type'] == 'image':
if 'hdurl' in apod.keys():
data.append({'date':apod['date'], 'title': apod['title'],'hdurl': apod['hdurl']})
步骤五:设置图像存储位置
现在我们将创建一个目录来存储图片,就像之前一样。
#Path of the directory:
image_dir = "AAA_Images_1"
#Checking if the directory already exists?
dir_res = os.path.exists(image_dir)
#If it doesn't exist then make a new directory:
if (dir_res==False):
os.makedirs(image_dir)
#If it exist then print a statement:
else:
print("Directory already exists!\n")
步骤六:下载图片
现在我们已经获取了图像和目录的所有信息,接下来我们将下载图像。我们使用for loop循环遍历列表中的所有数据。
#Retrieving the image:
for img in data:
#Creating title for image:
title = img["date"]+"_"+img["title"].replace(" ","_").replace(":","_")+".jpg"
#Downloading the image:
urllib.request.urlretrieve(img['hdurl'],
os.path.join(image_dir,title))
步骤 7:获取图像列表
现在我们已经下载了所有图片,是时候显示它们了。目录中会有很多图片,所以我们可以使用以下代码获取图片列表。
#Get a list of images:
astro_images = os.listdir(image_dir)
步骤 8:显示图像
现在我们可以轻松地使用 `display` 函数显示图像Image()。我们将使用 ` os.path.join()display` 函数查找图像位置。这里我们将显示可用图像列表中的第 0 张图片。
#Displaying an image:
Image(os.path.join(image_dir, astro_images[0]))
步骤 9:显示列表中的随机图像
我们可以使用 Python 的 random 库从可用图像列表中获取随机图像。
#Get random image:
import random
Image(os.path.join(image_dir, astro_images[random.randint(0,len(astro_images)-1)]))
把所有东西整合起来
第一步:
#Import required libraries:
import nasapy
import os
import pandas as pd
import urllib.request
from IPython.display import Image,display
#Initialize Nasa class by creating an object:
k = "523p5hPYHGzafYGLCkqa54kKMTV2vbP0XcPxkcLm"
nasa = nasapy.Nasa(key = k)
#Get a list of dates:
dates = pd.date_range(end = '2020-08-15', periods=5)
#Empty list to store dictionary keys and values:
data = []
#Getting all the data:
for d in dates:
apod = nasa.picture_of_the_day(d, hd=True)
if apod['media_type'] == 'image':
if 'hdurl' in apod.keys():
data.append({'date':apod['date'], 'title': apod['title'],'hdurl': apod['hdurl']})
#Path of the directory:
image_dir = "AAA_Images_1"
#Checking if the directory already exists?
dir_res = os.path.exists(image_dir)
#If it doesn't exist then make a new directory:
if (dir_res==False):
os.makedirs(image_dir)
#If it exist then print a statement:
else:
print("Directory already exists!\n")
#Retrieving the image:
for img in data:
#Creating title for image:
title = img["date"]+"_"+img["title"].replace(" ","_").replace(":","_")+".jpg"
#Downloading the image:
urllib.request.urlretrieve(img['hdurl'], os.path.join(image_dir,title))
#Get list of images:
astro_images = os.listdir(image_dir)
第二步:
#Displaying an image:
Image(os.path.join(image_dir, astro_images[0]))
步骤 3:
#Get random image:
import random
Image(os.path.join(image_dir, astro_images[random.randint(0,len(astro_images)-1)]))
请运行以下 Google Collaboratory 文件以查看正确的输出结果。您可以在Google Collaboratory上在线下载并运行此代码文件。
总结
恭喜你完成了这项使用 NASA API 和 Python 的趣味活动。希望这项活动让你学到了一些 Python 的新知识,并激发你继续学习的兴趣。
在本教程的下一部分,我们将学习如何通过电子邮件发送下载的图片。
要下载本教程中使用的所有 Jupyter Notebook,请点击此处。如果您对本文有任何疑问、问题或想法,请随时通过shuklapratik22@gmail.com与我联系。
如果您想继续学习 API 并提升技能,不妨了解一下 Educative 的课程“ Java REST 和 SOAP API 测试自动化”。您将学习如何执行 REST 和 SOAP API 测试自动化,以及如何从零开始编写 API 和集成测试。
学习愉快!

