Top
PHP & MySQLVideoanleitungen

Python-API-Lernprogramm – Eine Einführung in die Verwendung von APIs

Anwendungsprogrammschnittstellen oder APIs werden häufig verwendet, um Daten von entfernten Websites abzurufen. Websites wie Reddit, Twitter und Facebook bieten alle bestimmte Daten über ihre APIs. Um eine API zu verwenden, stellen Sie eine Anfrage an einen Remote-Webserver und rufen die benötigten Daten ab.

Warum aber eine API anstelle eines statischen Datasets verwenden, das Sie herunterladen können? APIs sind in folgenden Fällen nützlich:

  • Die Daten ändern sich schnell. Ein Beispiel hierfür sind Aktienkursdaten. Es macht keinen Sinn, einen Datensatz neu zu generieren und ihn jede Minute herunterzuladen – das wird eine Menge Bandbreite benötigen und ziemlich langsam sein.
  • Sie möchten ein kleines Stück eines viel größeren Datensatzes. Reddit Kommentare sind ein Beispiel. Was ist, wenn Sie nur Ihre eigenen Kommentare zu Reddit machen möchten? Es macht wenig Sinn, die gesamte Reddit-Datenbank herunterzuladen und dann nur Ihre eigenen Kommentare zu filtern.
  • Es gibt wiederholte Berechnungen. Spotify verfügt über eine API, die Ihnen das Genre eines Musikstücks mitteilen kann. Sie könnten theoretisch Ihren eigenen Klassifikator erstellen und ihn zum Kategorisieren von Musik verwenden, aber Sie werden nie so viele Daten haben wie Spotify.

In Fällen wie den obigen ist eine API die richtige Lösung. In diesem Blogpost werden wir eine einfache API abfragen, um Daten über die Internationale Raumstation (ISS) abzurufen. Die Verwendung einer API erspart uns Zeit und Mühe, die gesamte Berechnung selbst durchzuführen.

Die Internationale Raumstation.

API-Anfragen

APIs werden auf Webservern gehostet. Wenn Sie www.google.com in die Adresszeile Ihres Browsers eingeben, fragt Ihr Computer den www.google.com-Server nach einer Webseite, die er dann an Ihren Browser zurücksendet.

APIs funktionieren auf die gleiche Weise, außer dass Ihr Browser nach einer Webseite fragt und Ihr Programm nach Daten fragt. Diese Daten werden normalerweise im JSON-Format zurückgegeben (lesen Sie hierzu unser Tutorial zum Arbeiten mit JSON-Daten).

Um die Daten zu erhalten, stellen wir eine Anfrage an einen Webserver. Der Server antwortet dann mit unseren Daten. In Python verwenden wir dazu die Anforderungsbibliothek. In diesem Python-API-Tutorial verwenden wir Python 3.4 für alle unsere Beispiele.

Art der Anfragen

Es gibt viele verschiedene Arten von Anfragen. Die am häufigsten verwendete, eine GET-Anfrage, wird zum Abrufen von Daten verwendet.

Wir können eine einfache GET-Anfrage verwenden, um Informationen von der OpenNotify-API abzurufen.

OpenNotify hat mehrere API-Endpunkte. Ein Endpunkt ist eine Serverroute, die zum Abrufen verschiedener Daten von der API verwendet wird. Beispielsweise kann der Endpunkt / comments in der Reddit-API Informationen zu Kommentaren abrufen, während der Endpunkt / users Daten zu Benutzern abrufen kann. Um auf sie zuzugreifen, fügen Sie den Endpunkt der Basis-URL der API hinzu.

Der erste Endpunkt, den wir in OpenNotify betrachten, ist der iss-now.json-Endpunkt. Dieser Endpunkt erhält den aktuellen Längen- und Breitengrad der Internationalen Raumstation. Wie Sie sehen, eignet sich das Abrufen dieser Daten nicht für ein Dataset, da es einige Berechnungen auf dem Server erfordert und sich schnell ändert.

Sie können hier eine Liste aller Endpunkte auf OpenNotify anzeigen.

Die Basis-URL für die OpenNotify-API lautet http://api.open-notify.org. Daher fügen wir dies am Anfang aller unserer Endpunkte hinzu.

# Make a get request to get the latest position of the international space station from the opennotify api.

response = requests.get(“http://api.open-notify.org/iss-now.json”)

# Print the status code of the response.

print(response.status_code)

200

Statuscodes

Die Anfrage, die soeben gestellt wurde, hatte einen Statuscode von 200. Statuscodes werden mit jeder Anfrage zurückgegeben, die an einen Webserver gestellt wird. Statuscodes zeigen Informationen darüber an, was mit einer Anfrage passiert ist. Hier sind einige Codes, die für GET-Anfragen relevant sind:

  • 200 – alles lief gut und das Ergebnis wurde zurückgegeben (falls vorhanden)
  • 301 – Der Server leitet Sie zu einem anderen Endpunkt weiter. Dies kann passieren, wenn ein Unternehmen zwischen Domänennamen wechselt oder ein Endpunktname geändert wird.
  • 401 – Der Server denkt, dass Sie nicht authentifiziert sind. Dies passiert, wenn Sie nicht die richtigen Zugangsdaten für den Zugriff auf eine API senden (wir werden in einem späteren Post über die Authentifizierung sprechen).
  • 400 – Der Server ist der Meinung, dass Sie eine falsche Anfrage gestellt haben. Dies kann passieren, wenn Sie unter anderem nicht die richtigen Daten senden.
  • 403 – Die Ressource, auf die Sie zugreifen möchten, ist verboten – Sie haben nicht die erforderlichen Berechtigungen, um sie zu sehen.
  • 404 – Die Ressource, auf die Sie zugreifen wollten, wurde nicht auf dem Server gefunden.

Wir werden nun eine GET-Anfrage an den API http://api.open-notify.org/iss-pass, ein Endpunkt, der nicht existiert, machen.

response = requests.get(“http://api.open-notify.org/iss-pass”)

print(response.status_code)

404

Den richtigen Endpunkt treffen

iss-pass war kein gültiger Endpunkt, daher haben wir als Antwort einen 404-Statuscode erhalten. Wir haben am Ende vergessen, .json hinzuzufügen, wie die API-Dokumentation sagt.

Wir werden nun eine GET-Anfrage an http://api.open-notify.org/iss-pass.json stellen.

response = requests.get(“http://api.open-notify.org/iss-pass.json”)

print(response.status_code)

400

Abfrageparameter

Sie werden sehen, dass wir im letzten Beispiel einen 400-Statuscode erhalten haben, der auf eine ungültige Anforderung hinweist. Wenn Sie sich die Dokumentation für die OpenNotify-API ansehen, sehen wir, dass der ISS-Pass-Endpunkt zwei Parameter benötigt.

Der ISS-Pass-Endpunkt kehrt zurück, wenn die ISS als nächstes einen bestimmten Ort auf der Erde passiert. Um dies zu berechnen, müssen wir die Koordinaten des Ortes an die API übergeben. Wir tun dies, indem wir zwei Parameter übergeben – Längen- und Breitengrad.

Wir können dies tun, indem wir ein optionales Schlüsselwortargument, params, zu unserer Anfrage hinzufügen. In diesem Fall müssen zwei Parameter übergeben werden:

  • lat – Die Breite des gewünschten Ortes.
  • lon – Die Länge des Ortes, den wir wollen.

Wir können ein Wörterbuch mit diesen Parametern erstellen und sie dann in die Funktion requests.get übergeben.

Wir können das Gleiche auch direkt tun, indem wir die Abfrageparameter wie folgt in die URL einfügen: http://api.open-notify.org/iss-pass.json?lat=40.71&lon=-74.

Es ist fast immer vorzuziehen, die Parameter als Dictionary einzurichten, da Requests sich um einige Dinge kümmern, die auftauchen, wie zum Beispiel das korrekte Formatieren der Abfrageparameter.

Wir werden eine Anfrage mit den Koordinaten von New York City machen und sehen, welche Antwort wir bekommen.

# Set up the parameters we want to pass to the API.

# This is the latitude and longitude of New York City.

parameters = {“lat”: 40.71, “lon”: 74}

 

# Make a get request with the parameters.

response = requests.get(“http://api.open-notify.org/iss-pass.json”, params=parameters)

 

# Print the content of the response (the data the server returned) print(response.content)

# This gets the same data as the command above

response = requests.get(“http://api.open-notify.org/iss-pass.json?lat=40.71&lon=-74”)

print(response.content)

b'{\n  "message": "success", \n  "request": {\n    "altitude": 100, \n    "datetime": 1441417753, \n    "latitude": 40.71, \n    "longitude": -74.0, \n    "passes": 5\n  }, \n  "response": [\n    {\n      "duration": 330, \n      "risetime": 1441445639\n    }, \n    {\n      "duration": 629, \n      "risetime": 1441451226\n    }, \n    {\n      "duration": 606, \n      "risetime": 1441457027\n    }, \n    {\n      "duration": 542, \n      "risetime": 1441462894\n    }, \n    {\n      "duration": 565, \n      "risetime": 1441468731\n    }\n  ]\n}'

b'{\n  "message": "success", \n  "request": {\n    "altitude": 100, \n    "datetime": 1441417753, \n    "latitude": 40.71, \n    "longitude": -74.0, \n    "passes": 5\n  }, \n  "response": [\n    {\n      "duration": 329, \n      "risetime": 1441445639\n    }, \n    {\n      "duration": 629, \n      "risetime": 1441451226\n    }, \n    {\n      "duration": 606, \n      "risetime": 1441457027\n    }, \n    {\n      "duration": 542, \n      "risetime": 1441462894\n    }, \n    {\n      "duration": 565, \n      "risetime": 1441468731\n    }\n  ]\n}'

Die ISS über New York.

 

Mit JSON-Daten arbeiten

Sie haben vielleicht bemerkt, dass der Inhalt der Antwort früher eine Zeichenkette war (obwohl es als ein Byte-Objekt gezeigt wurde, können wir den Inhalt leicht in eine Zeichenkette unter Verwendung von response.content.decode (“utf-8”) konvertieren).

Strings sind die Art und Weise, wie wir Informationen an APIs weitergeben, aber es ist schwierig, die Informationen zu erhalten, die wir von ihnen möchten. Wie können wir die Zeichenfolge, die wir in Python erhalten und damit arbeiten, dekodieren? Wie ermitteln wir die Höhe der ISS aus der String-Antwort?

Zum Glück gibt es ein Format namens JavaScript Object Notation (JSON). JSON ist eine Möglichkeit, Datenstrukturen wie Listen und Wörterbücher in Zeichenfolgen zu codieren, die sicherstellen, dass sie von Maschinen leicht lesbar sind. JSON ist das primäre Format, in dem Daten an APIs übergeben werden. Die meisten API-Server senden ihre Antworten im JSON-Format.

Python unterstützt JSON mit dem json-Paket. Das JSON-Paket ist Teil der Standardbibliothek, daher müssen wir nichts installieren, um es zu verwenden. Wir können Listen und Wörterbücher in JSON konvertieren und Strings in Listen und Wörterbücher konvertieren. Bei unseren ISS-Passdaten handelt es sich um ein Wörterbuch, das im JSON-Format in eine Zeichenfolge codiert ist.

Die json-Bibliothek hat zwei Hauptmethoden:

  • Dumps – Nimmt ein Python-Objekt auf und konvertiert es in eine Zeichenfolge.
  • Lasten – Nimmt eine JSON-Zeichenfolge und konvertiert sie in ein Python-Objekt.

# Make a list of fast food chains.

best_food_chains = [“Taco Bell”, “Shake Shack”, “Chipotle”]

# This is a list.

print(type(best_food_chains))

# Import the json library

import json

# Use json.dumps to

convert best_food_chains to a string. best_food_chains_string = json.dumps(best_food_chains)

# We’ve successfully converted our list to a string.

print(type(best_food_chains_string))

# Convert best_food_chains_string back into a list

print(type(json.loads(best_food_chains_string)))

# Make a dictionary

fast_food_franchise = { “Subway”: 24722, “McDonalds”: 14098, “Starbucks”: 10821, “Pizza Hut”: 7600 }

# We can also dump a dictionary to a string and load it.

fast_food_franchise_string = json.dumps(fast_food_franchise) print(type(fast_food_franchise_string))

<class 'list'>
<class 'str'>
<class 'list'>
<class 'str'>

JSON von einer API-Anfrage erhalten

Sie können den Inhalt einer Antwort als Python-Objekt abrufen, indem Sie die Methode .json () für die Antwort verwenden.

# Make the same request we did earlier, but with the coordinates of San Francisco instead.

parameters = {“lat”: 37.78, “lon”: 122.41}

response = requests.get(“http://api.open-notify.org/iss-pass.json”, params=parameters)

# Get the response

data as a python object. Verify that it’s a dictionary. data = response.json()

print(type(data))

print(data)

<class 'dict'>
{'response': [{'risetime': 1441456672, 'duration': 369}, {'risetime': 1441462284, 'duration': 626}, {'risetime': 1441468104, 'duration': 581}, {'risetime': 1441474000, 'duration': 482}, {'risetime': 1441479853, 'duration': 509}], 'message': 'success', 'request': {'latitude': 37.78, 'passes': 5, 'longitude': -122.41, 'altitude': 100, 'datetime': 1441417753}}

Inhaltstyp

Der Server sendet nicht nur einen Statuscode und die Daten, wenn er eine Antwort generiert. Es sendet auch Metadaten mit Informationen darüber, wie die Daten generiert wurden und wie sie dekodiert werden. Dies wird in den Antwortheadern gespeichert. In Python können wir mit der Header-Eigenschaft eines Antwortobjekts darauf zugreifen.

Die Header werden als Wörterbuch angezeigt. Innerhalb der Header ist Content-Type der wichtigste Schlüssel für jetzt. Es zeigt uns das Format der Antwort und wie man sie entschlüsselt. Für die OpenNotify-API ist das Format JSON, weshalb wir es früher mit dem json-Paket dekodieren konnten.

# Headers is a dictionary

print(response.headers)

# Get the content-type from the dictionary.

print(response.headers[“content-type”])

{'server': 'gunicorn/19.3.0', 'content-length': '520', 'content-type': 'application/json', 'date': 'Sat, 05 Sep 2015 01:49:13 GMT', 'connection': 'keep-alive', 'via': '1.1 vegur'}

Die Anzahl der Personen im Raum finden

OpenNotify hat einen weiteren API-Endpunkt, astros.json. Es zeigt an, wie viele Personen sich gerade im Raum befinden. Das Format der Antworten finden Sie hier.

# Get the response from the API endpoint.

response = requests.get(“http://api.open-notify.org/astros.json”)

data = response.json()

 

# 9 people are currently in space.

print(data[“number”])

print(data)

9

{'number': 9, 'people': [{'name': 'Gennady Padalka', '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', 'craft': 'ISS'}, {'name': 'Andreas Mogensen', 'craft': 'ISS'}, {'name': 'Aidyn Aimbetov', 'craft': 'ISS'}], 'message': 'success'}

Python-API-Tutorial: Nächste Schritte

Nachdem Sie nun unser Python-API-Lernprogramm abgeschlossen haben, sollten Sie nun in der Lage sein, auf eine einfache API zuzugreifen und Anfragen zu erhalten. Es gibt noch ein paar andere Arten von Anfragen, über die Sie in unseren dataquest-APIs und im Scraping-Kurs mehr erfahren können, sowie über die API-Authentifizierung.

Andere empfohlene nächste Schritte sind das Lesen der Anforderungsdokumentation und das Arbeiten mit der Reddit-API. Es gibt ein Paket namens PRAW, das die Arbeit mit der Reddit-API in Python erleichtert, aber es wird empfohlen, zunächst nur Anfragen zu verwenden, um zu erfahren, wie alles funktioniert.