发布于 2026-01-06 0 阅读
0

如何使用 API:使用 NASA 的开放 API 获取每日图像

如何使用 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
Enter fullscreen mode Exit fullscreen mode
  • 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)
Enter fullscreen mode Exit fullscreen mode

步骤 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')
Enter fullscreen mode Exit fullscreen mode

步骤 4:从 NASA 的 API 获取信息

现在我们已经获得了格式正确的日期,可以请求获取今天的天文图像了。这里我们使用相应的picture_of_the_day()方法来获取图像数据。

#Get the image data:

apod = nasa.picture_of_the_day(date=d, hd=True)
Enter fullscreen mode Exit fullscreen mode

我们的 apod 变量是一个包含各种键和值的字典。让我们来看看这个变量的键:

  • date
  • title
  • copyright
  • explanation
  • url
  • hdurl
  • media_type
  • service_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!")
Enter fullscreen mode Exit fullscreen mode

现在我们将逐段理解代码。

显示图片:

  • 首先,我们只会展示图片。
  • 其次,我们只对高清图像感兴趣。因此,如果图像是标清的,我们就不会进入循环。
  • 现在,我们需要遵循一定的命名结构来保存图像。这里,我们将使用图像日期、图像标题和图像扩展名作为文件名。
  • 我们还用下划线代替冒号和空格。

创建目录:

  • 现在我们需要一个特定的目录来存储图片。我们使用 os 库创建一个目录。为了检查目录是否存在,我们使用.exist()一个函数。如果目录不存在,则使用.makedirs()另一个函数创建它。
  • 现在我们使用从 apod 变量中获取的 URL 来获取图像。获取图像的过程是使用该urllib.request.urlretrieve()函数完成的。
  • 我们还使用os.path.join()指定标题名称将图像存储在新创建的目录中。
  • 我们过去apod[“hdurl”]常常下载图片。

显示其他信息:

  • 现在我们已经将图片下载到指定目录,接下来要显示与该图片相关的其他信息。我们会检查指定的键值是否存在。如果存在,则显示其值。
  • Image()然后我们使用Ipython 库的函数显示主图像。

音频讲解:

  • 现在图片和其他信息已经显示完毕,我们会询问用户是否想听图片的解释。如果用户按下按钮*,我们会使用 Google 的文本转语音 (Text to Speech gtts) 库将文本转换为音频文件。
  • 我们创建一个对象,它接收待转换的文本、语速和语言作为输入。然后,我们将这些信息存储在带有特定.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!")
Enter fullscreen mode Exit fullscreen mode

请运行以下 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
Enter fullscreen mode Exit fullscreen mode

步骤 2:创建 NASA 类的对象

接下来我们将创建一个名为 `<object>` 的对象nasa。我们将使用 nasapy 库和我们注册的 API 密钥。我们将使用此对象调用 Nasa 类的一个方法来获取天文图像的信息。

#Initialize Nasa class by creating an object:

k = "523p5hPYHGzafYGLCkqa54kKMTV2vbP0XcPxkcLm"
nasa = nasapy.Nasa(key = k)
Enter fullscreen mode Exit fullscreen mode

步骤 3:获取日期列表

我们需要下载多个日期对应的多张图片。因此,我们将使用pandas 库date_range()的函数。该函数会返回所需格式的日期列表。其中,period 值决定了列表的范围。

我们将下载 5 张图片,但您可以通过调整句点和结束值来下载任意数量的图片。

#Get a list of dates:
dates = pd.date_range(end = '2020-08-15', periods=5)
Enter fullscreen mode Exit fullscreen mode

第四步:获取数据

之前我们只有一张图片。但这次我们要下载多张图片。为此,我们创建一个空列表,用字典的形式存储所有图片的对应值。

首先,我们将获取日期值并将其存储在 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']})
Enter fullscreen mode Exit fullscreen mode

步骤五:设置图像存储位置

现在我们将创建一个目录来存储图片,就像之前一样。

#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")  
Enter fullscreen mode Exit fullscreen mode

步骤六:下载图片

现在我们已经获取了图像和目录的所有信息,接下来我们将下载图像。我们使用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))
Enter fullscreen mode Exit fullscreen mode

步骤 7:获取图像列表

现在我们已经下载了所有图片,是时候显示它们了。目录中会有很多图片,所以我们可以使用以下代码获取图片列表。

#Get a list of images:
astro_images = os.listdir(image_dir)
Enter fullscreen mode Exit fullscreen mode

步骤 8:显示图像

现在我们可以轻松地使用 `display` 函数显示图像Image()。我们将使用 ` os.path.join()display` 函数查找图像位置。这里我们将显示可用图像列表中的第 0 张图片。

#Displaying an image:
Image(os.path.join(image_dir, astro_images[0]))
Enter fullscreen mode Exit fullscreen mode

步骤 9:显示列表中的随机图像

我们可以使用 Python 的 random 库从可用图像列表中获取随机图像。

#Get random image:
import random
Image(os.path.join(image_dir, astro_images[random.randint(0,len(astro_images)-1)]))
Enter fullscreen mode Exit fullscreen mode

把所有东西整合起来

第一步:

#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)
Enter fullscreen mode Exit fullscreen mode

第二步:

#Displaying an image:
Image(os.path.join(image_dir, astro_images[0]))
Enter fullscreen mode Exit fullscreen mode

步骤 3:

#Get random image:
import random
Image(os.path.join(image_dir, astro_images[random.randint(0,len(astro_images)-1)]))
Enter fullscreen mode Exit fullscreen mode

替代文字

请运行以下 Google Collaboratory 文件以查看正确的输出结果。您可以在Google Collaboratory上在线下载并运行此代码文件。

总结

恭喜你完成了这项使用 NASA API 和 Python 的趣味活动。希望这项活动让你学到了一些 Python 的新知识,并激发你继续学习的兴趣。

在本教程的下一部分,我们将学习如何通过电子邮件发送下载的图片。

要下载本教程中使用的所有 Jupyter Notebook,请点击此处。如果您对本文有任何疑问、问题或想法,请随时通过shuklapratik22@gmail.com与我联系。

如果您想继续学习 API 并提升技能,不妨了解一下 Educative 的课程“ Java REST 和 SOAP API 测试自动化”。您将学习如何执行 REST 和 SOAP API 测试自动化,以及如何从零开始编写 API 和集成测试。

学习愉快!

继续阅读有关 Python 和 API 的内容。

文章来源:https://dev.to/educative/how-to-use-an-api-fetch-daily-images-with-nasa-s-open-api-nki