!pip install requests
Angesichts der aktuellen Berichterstattung in der Presse über sogenannte “Killerobjekte” aus dem All, möchte ich ein Beispiel aus der numerischen Astronomie vorstellen, um einen besseren Überblick über Near-Earth Objects (NEOs) zu erhalten.
Die NASA stellt über eine öffentlich zugängliche Programmierschnittstelle API die Möglichkeit bereit, auf ihre aktuelle Datenbank zuzugreifen. Dieses Vorgehen fällt unter das Konzept der Open Data, was bedeutet, dass man nicht einmal ein Benutzerkonto benötigt, um diese wertvollen Daten einzusehen und zu nutzen.
Im Folgenden finden Sie einen entsprechenden Python-Quellcode, um auf diese API zuzugreifen. Dieser Code ermöglicht es uns, die von der NASA bereitgestellten Daten abzurufen und wir werden uns diese Daten anschließend genauer ansehen, um beispielsweise Informationen über die Bahnen, Größen und potenziellen Risiken von erdnahen Objekten zu gewinnen.
Die Bibliothek Requests ist ein hervorragendes Werkzeug, um auf sehr einfache Weise API-Aufrufe in Python auszuführen und die erhaltenen Ergebnisse anschließend als JSON-Objekt zu verarbeiten (zu parsen). Diese Bibliothek gehört jedoch nicht zum Standardumfang der Python-Installation und muss daher in der Regel separat installiert werden, beispielsweise über den Paketmanager pip
.
import time
import requests
from datetime import datetime, timedelta
Zuerst importieren wir die notwendigen Bibliotheken für Python, um einen API-Aufruf durchzuführen. In diesem Beispielcode verzichten wir bewusst auf die üblichen und wichtigen Überprüfungen der Rückgabewerte des API-Aufrufs. Dies tun wir, um den Code so einfach wie möglich zu halten und uns primär auf das Wesentliche zu konzentrieren: die erfolgreiche Abfrage der Daten von der NASA-API. In einer realen Anwendung wäre es natürlich unerlässlich, die Antwort des Servers auf Fehler oder unerwartete Ergebnisse zu überprüfen, um die Stabilität und Zuverlässigkeit des Programms zu gewährleisten.
= 7
days_to_fetch = datetime.today()
begin_obj = (datetime.today() + timedelta(days = days_to_fetch))
end_obj = begin_obj.strftime('%Y-%m-%d')
begin_str = end_obj.strftime('%Y-%m-%d') end_str
Die Variablen begin_str
und end_str
enthalten nun zwei Zeichenketten, die jeweils ein Datum im Format Jahr-Monat-Tag repräsentieren. begin_str
speichert dabei das aktuelle Datum, während end_str
das Datum in genau einer Woche enthält. Diese beiden Variablen werden verwendet, um den Zeitraum für die Abfrage von Daten über Near-Earth Objects (NEOs) an die NASA-API zu definieren. Indem wir einen Start- und Endzeitpunkt festlegen, können wir die Ergebnisse auf einen bestimmten Zeitraum eingrenzen, in diesem Fall auf die aktuelle Woche.
print(f"Vom {begin_str} bis zum {end_str}")
Vom 2025-04-09 bis zum 2025-04-16
= f"https://api.nasa.gov/neo/rest/v1/feed?start_date={begin_str}&end_date={end_str}&api_key=DEMO_KEY"
NASA_URL = requests.get(NASA_URL, timeout = 10)
request_raw = request_raw.json() json_data
Damit haben wir nun die Informationen über die nächsten 7 Tage als JSON-Objekt erhalten. Dieses Objekt enthält wahrscheinlich eine strukturierte Sammlung von Daten über alle erdnahen Objekte (NEOs), die in diesem Zeitraum erwartet werden oder deren Beobachtungen stattgefunden haben. Jetzt können wir uns den Inhalt dieses JSON-Objekts einmal genauer ansehen, um zu verstehen, welche spezifischen Informationen uns die NASA-API liefert. Dies könnte beispielsweise eine Liste von NEOs mit Details zu ihrer Größe, Geschwindigkeit, ihrer nächsten Erdannäherung und der Wahrscheinlichkeit eines Einschlags umfassen. Die genaue Struktur des JSON-Objekts zu untersuchen ist der nächste wichtige Schritt, um die relevanten Daten für unsere Analyse oder Übersicht zu extrahieren.
sorted(json_data.keys())
['element_count', 'links', 'near_earth_objects']
Wunderbar, die relevanten Informationen über die erdnahen Objekte (NEOs) finden wir unter dem Schlüssel near_earth_objects
innerhalb des JSON-Objekts. Dieser Schlüssel dient als zentraler Zugriffspunkt, um auf die eigentlichen Daten über die NEOs zuzugreifen. Es ist sehr wahrscheinlich, dass der Wert, der diesem Schlüssel zugeordnet ist, eine weitere Struktur enthält, beispielsweise ein Dictionary, in dem die einzelnen Tage innerhalb des von uns abgefragten Zeitraums als Schlüssel dienen und die Werte Listen von NEO-Objekten für den jeweiligen Tag darstellen. Um also die spezifischen Daten zu den NEOs zu erhalten, müssen wir in unserem Python-Code auf dieses Element mit dem Namen near_earth_objects
zugreifen.
sorted(json_data['near_earth_objects'].keys())
['2025-04-09',
'2025-04-10',
'2025-04-11',
'2025-04-12',
'2025-04-13',
'2025-04-14',
'2025-04-15',
'2025-04-16']
Dann schauen wir mal in das aktuelle Datum:
type(json_data['near_earth_objects'][begin_str])
list
sorted(json_data['near_earth_objects'][begin_str][0].keys())
['absolute_magnitude_h',
'close_approach_data',
'estimated_diameter',
'id',
'is_potentially_hazardous_asteroid',
'is_sentry_object',
'links',
'name',
'nasa_jpl_url',
'neo_reference_id']
Wunderbar hier haben wir alle Daten.
'near_earth_objects'][begin_str][0] json_data[
{'links': {'self': 'http://api.nasa.gov/neo/rest/v1/neo/3407680?api_key=DEMO_KEY'},
'id': '3407680',
'neo_reference_id': '3407680',
'name': '(2008 FW6)',
'nasa_jpl_url': 'https://ssd.jpl.nasa.gov/tools/sbdb_lookup.html#/?sstr=3407680',
'absolute_magnitude_h': 21.0,
'estimated_diameter': {'kilometers': {'estimated_diameter_min': 0.1677084622,
'estimated_diameter_max': 0.3750075218},
'meters': {'estimated_diameter_min': 167.7084621628,
'estimated_diameter_max': 375.0075217981},
'miles': {'estimated_diameter_min': 0.1042091748,
'estimated_diameter_max': 0.2330187988},
'feet': {'estimated_diameter_min': 550.2246310023,
'estimated_diameter_max': 1230.3396778159}},
'is_potentially_hazardous_asteroid': True,
'close_approach_data': [{'close_approach_date': '2025-04-09',
'close_approach_date_full': '2025-Apr-09 06:42',
'epoch_date_close_approach': 1744180920000,
'relative_velocity': {'kilometers_per_second': '26.7882567653',
'kilometers_per_hour': '96437.7243550494',
'miles_per_hour': '59922.6515582806'},
'miss_distance': {'astronomical': '0.4365028102',
'lunar': '169.7995931678',
'kilometers': '65299890.654934274',
'miles': '40575470.5434060212'},
'orbiting_body': 'Earth'}],
'is_sentry_object': False}
Als Nächstes wollen wir das Objekt identifizieren, das in den nächsten 7 Tagen die dichteste Annäherung an die Erde aufweist. Um dies zu bewerkstelligen, müssen wir die Daten, die wir unter dem Schlüssel near_earth_objects
gefunden haben, genauer untersuchen. Es ist wahrscheinlich, dass für jeden Tag innerhalb des von uns abgefragten Zeitraums eine Liste von NEOs vorhanden ist, und jedes dieser Objekte wiederum detaillierte Informationen über seine vorhergesagten oder beobachteten Annäherungen an die Erde enthält. Wir werden also diese Daten durchgehen und nach dem Eintrag suchen, der die geringste Distanz zur Erde innerhalb der nächsten sieben Tage angibt. Diese Distanz wird üblicherweise in astronomischen Einheiten (AU) oder in Monddistanzen angegeben.
= float('inf')
distance = None
neo
for days in range(days_to_fetch):
= (datetime.today() + timedelta(days = days))
work_date = work_date.strftime('%Y-%m-%d')
work_date_str
if work_date_str in json_data['near_earth_objects']:
for i in json_data['near_earth_objects'][work_date_str]:
= float(i['close_approach_data'][0]['miss_distance']['kilometers'])
miss = i['is_potentially_hazardous_asteroid']
hazardous
if hazardous and miss < distance:
= miss
distance = i neo
Was wollen wir genau von diesem Objekt wissen? Name, URL, Groesse , Datum, Abstand mit dem das Objekt an uns vorbeifliegt
= neo['name']
name = neo['nasa_jpl_url']
url = neo['estimated_diameter']['meters']['estimated_diameter_min']
size_min = neo['estimated_diameter']['meters']['estimated_diameter_max']
size_max = size_min + ((size_max - size_min) / 2)
size_avr = neo['close_approach_data'][0]['close_approach_date_full']
approach_date = float(neo['close_approach_data'][0]['miss_distance']['kilometers'])
distance
print(f"{name} \nGroesse von: {size_avr:.2f} Metern \nDatum: {approach_date} \nDistance: {distance:.2f} Kilometer")
(2025 FP10)
Groesse von: 696.21 Metern
Datum: 2025-Apr-12 03:55
Distance: 4168566.74 Kilometer
Und hier sind die genauen Daten vom JPL fuer 2025 FP10
Zurück nach oben