So führen Sie HTTP -Anfragen mit Python - Teil 1 der Standardbibliothek durch

So führen Sie HTTP -Anfragen mit Python - Teil 1 der Standardbibliothek durch

HTTP ist das vom World Wide Web verwendete Protokoll. Deshalb ist es wichtig, programmgesteuert mit ihm zu interagieren: Eine Webseite abzukratzen, mit einer Service -APIs zu kommunizieren oder sogar einfach eine Datei herunterzuladen, sind alle Aufgaben, die auf dieser Interaktion basieren. Python macht solche Vorgänge sehr einfach: Einige nützliche Funktionen sind bereits in der Standardbibliothek bereitgestellt und für komplexere Aufgaben sind es möglich (und sogar empfohlen), das externe zu verwenden Anfragen Modul. In diesem ersten Artikel der Serie konzentrieren wir uns auf die integrierten Module. Wir werden Python3 verwenden und hauptsächlich in der Python Interactive Shell arbeiten.

In diesem Tutorial lernen Sie:

  • So führen Sie HTTP -Anfragen mit Python3 und der Urllib durch.Bibliothek anfordern
  • So arbeiten Sie mit Serverantworten
  • So herunterladen Sie eine Datei mit dem Urlopen oder den Urlieve -Funktionen


HTTP -Anfrage bei Python - Pt. I: Die Standardbibliothek

Softwareanforderungen und Konventionen verwendet

Softwareanforderungen und Linux -Befehlszeilenkonventionen
Kategorie Anforderungen, Konventionen oder Softwareversion verwendet
System OS-unabhängig
Software Python3
Andere
  • Kenntnis der grundlegenden Konzepte der objektorientierten Programmierung und der Python -Programmiersprache
  • Grundkenntnisse über das HTTP -Protokoll und HTTP -Verben
Konventionen # - erfordert, dass gegebene Linux -Befehle mit Root -Berechtigungen entweder direkt als Stammbenutzer oder mit Verwendung von ausgeführt werden können sudo Befehl
$ - Erfordert, dass die angegebenen Linux-Befehle als regelmäßiger nicht privilegierter Benutzer ausgeführt werden können

Anfragen mit der Standardbibliothek durchführen

Beginnen wir mit einem sehr einfachen ERHALTEN Anfrage. Das GET -HTTP -Verb wird verwendet, um Daten aus einer Ressource abzurufen. Bei der Ausführung solcher Art von Anforderungen ist es möglich, einige Parameter in den Formularvariablen anzugeben: diese Variablen, die als Schlüsselwertpaare ausgedrückt werden, Formular a Abfragezeichenfolge welches an die „angehängt“ ist URL der Ressource. Eine Anfrage sollte immer sein idempotent (Dies bedeutet, dass das Ergebnis der Anfrage unabhängig von der Häufigkeit sein sollte, mit der sie ausgeführt wird) und niemals verwendet werden sollte, um einen Zustand zu ändern. Get Anfragen mit Python durchführen ist wirklich einfach. Für dieses Tutorial nutzen wir den offenen NASA -API -Anruf, mit dem wir das sogenannte „Bild des Tages“ abrufen können:



>>> von urllib.anfordern urlopen importieren >>> mit urlopen ("https: // api.NASA.Gov/Planetary/APOD?api_key = Demo_key ") als Antwort: ... Antwort_Content = Antwort.lesen() 
Kopieren

Das erste, was wir taten, war, die zu importieren urlopen Funktion von der Urlib.Anfrage Bibliothek: Diese Funktion gibt eine zurück http.Klient.Httpresponse Objekt, das einige sehr nützliche Methoden hat. Wir haben die Funktion in a verwendet mit Aussage, weil die Httpresponse Objekt unterstützt die Kontextmanagement Protokoll: Die Ressourcen werden sofort geschlossen, nachdem die Anweisung „mit“ ausgeführt wurde, auch wenn eine Ausnahme wird erhöht.

Der lesen Die Methode, die wir im obigen Beispiel verwendet haben Bytes und nimmt optional ein Argument an, das die Anzahl der zu lesensenden Bytes darstellt (wir werden später sehen, wie wichtig dies in einigen Fällen wichtig ist, insbesondere beim Herunterladen großer Dateien). Wenn dieses Argument weggelassen wird, wird der Körper der Antwort in seiner Gesamtheit gelesen.

Zu diesem Zeitpunkt haben wir den Körper der Reaktion als Bytesobjekt, referenziert von der Antwort_Content Variable. Wir möchten es vielleicht in etwas anderes verwandeln. Um es zum Beispiel in eine Zeichenfolge zu verwandeln, verwenden wir die dekodieren Methode, die den Codierungstyp als Argument bereitstellt, typischerweise:

>>> response_content.decode ('utf-8')

Im obigen Beispiel haben wir die verwendet UTF-8 Codierung. Der API -Aufruf, den wir im Beispiel verwendet haben, gibt jedoch eine Antwort in zurück in JSON Das Format wollen es daher mit Hilfe der verarbeiten JSON Modul:

>>> importieren json json_response = json.lädt (response_content) 
Kopieren

Der JSON.Ladungen Methode deserialisiert a Saite, A Bytes oder ein Bytearray Instanz, die ein JSON -Dokument in ein Python -Objekt enthält. Das Ergebnis der Aufruf der Funktion ist in diesem Fall ein Wörterbuch:

>>> aus pprint import pprint >>> pprint (json_response) 'Date': '2019-04-14', 'Erklärung': 'Lehre zurück und schau zwei schwarze Löcher an. Inspiriert von der ersten direkten Erkennung von Gravitationswellen im Jahr 2015 spielt dieses Simulationsvideo in Zeitlupe, würde jedoch ungefähr ein Drittel eines zweiten in Echtzeit dauern. Setzen. Ihre extremen Schwerkraftlinsen das Licht hinter ihnen '' in Einstein -Ringe, wenn sie sich näher schieben und schließlich in einen verschmolzen. Die ansonsten unsichtbaren Gravitationswellen, die als massive Objekte erzeugt werden. Die GW150914 genannt '' '' '' '' '' '' Save '' Stimmen mit der Fusion von 36 und 31 Solarmasse schwarze '' Löcher in einer Entfernung von 1 übereinstimmen die Gravitationswellen.3 Milliarden Lichtjahre. Das endgültige "Single Black Loch" hat 63 -mal die Sonne, wobei die verbleibenden 3 Sonnenmassen in "Gravitationswellen in Energie umgewandelt werden. Seitdem haben die Ligo- und Jungfrau-Gravitationswellenobservatorien mehrere weitere "Erkennungen des Zusammenführens massiver Systeme.',' media_type ':' Video ',' service_version ':' v1 ',' title ':' simulation: zwei schwarze löcher merge ',' url ':' https: // www.Youtube.com/bett/i_88s8dwbcu?rel = 0 ' 
Kopieren

Als Alternative konnten wir auch die verwenden JSON_LOAD Funktion (Beachten Sie die fehlende nachverfolgende „S“). Die Funktion akzeptiert a Dateiähnlich Objekt als Argument: Dies bedeutet, dass wir es direkt auf dem verwenden können Httpresponse Objekt:

>>> mit urlopen ("https: // api.NASA.Gov/Planetary/APOD?api_key = Demo_key ") als Antwort: ... JSON_Response = JSON.Last (Antwort) 
Kopieren

Lesen Sie die Antwortschicht

Eine andere sehr nützliche Methode, die auf der verwendet werden kann Httpresponse Objekt ist Getheader. Diese Methode gibt die zurück Header der Antwort als eine Reihe von Tupeln. Jedes Tupel enthält einen Header -Parameter und seinen entsprechenden Wert:



>>> pprint (Antwort.Getheaders ()) [('Server', 'OpenResty'), ('Date', 'Sun, 14. April 2019 10:08:48 GMT'), ('Inhaltstyp', 'Application/JSON'), (( 'Inhaltslänge', '1370'), ('Verbindung', 'Close'), ('vary', 'Accord-Coding'), ('x-ratelimit-limit', '40'), ('x -Ratelimit-Remaining ',' 37 '), (' via ',' 1.1 Vegur, http/1.1 api-umbrella (apachetrafficserver [CMSSF]) '), (' Alter ',' 1 '), (' X-Cache ',' Miss '), (' Access-Control-Origin ','*') , ('Strict-Transport-Security', 'max-Alter = 31536000; Vorspannung')] 

Sie können unter den anderen bemerken, die Inhaltstyp Parameter, der, wie wir oben sagten, ist Anwendung/JSON. Wenn wir nur einen bestimmten Parameter abrufen möchten, können wir die verwenden Getheader Methode stattdessen den Namen des Parameters als Argument übergeben:

>>> Antwort.Getheader ('Inhaltstyp') 'Anwendung/JSON' ' 
Kopieren

Den Status der Antwort erhalten

Den Statuscode erhalten und Grund Phrase vom Server zurückgegeben, nachdem eine HTTP -Anforderung auch sehr einfach ist: Wir müssen nur auf die zugreifen Status Und Grund Eigenschaften der Httpresponse Objekt:

>>> Antwort.Status 200 >>> Antwort.Grund "OK" 
Kopieren

Einschließlich Variablen in die GET -Anfrage einschließlich

Die URL der oben gesendeten Anfrage enthielt nur eine Variable: API-Schlüssel, und sein Wert war "Demo_key". Wenn wir mehrere Variablen übergeben möchten, können wir sie und ihre zugehörigen Werte als Schlüsselwertepaare eines Python-Wörterbuchs (oder als Abfolge von Tuproplements mit zwei Elementen) an die URL an die URL anbringen. Dieses Wörterbuch wird an die übergeben Urlib.analysieren.Urlencode Methode, die die erstellt und zurückgibt Abfragezeichenfolge. Mit dem oben verwendeten API -Aufruf können wir eine optionale "Datum" -Variable angeben, um das mit einem bestimmten Tag verknüpfte Bild abzurufen. So könnten wir vorgehen:

>>> von urllib.analysieren urlencode >>> query_params =  ..."api_key": "Demo_key", ..."Date": "2019-04-11" >>> query_string = urlencode (query_params) >>> query_string 'api_key = Demo_key & Date = 2019-04-11' 
Kopieren

Zuerst haben wir jede Variable und ihren entsprechenden Wert als Schlüsselwertpaare eines Wörterbuchs definiert, als dass wir das Wörterbuch als Argument an die bestanden haben Urlencode Funktion, die eine formatierte Abfragezeichenfolge zurückgab. Wenn wir nun die Anfrage senden, müssen wir sie nur an die URL anbringen:

>>> url = "?".Join (["https: // api.NASA.gov/Planetary/apod ", query_string])

Wenn wir die Anfrage mit der URL oben senden, erhalten wir eine andere Antwort und ein anderes Bild:

'Date': '2019-04-11', 'Erklärung': 'Wie sieht ein schwarzes Loch aus? Um herauszufinden, dass Radio -Teleskope aus der Erde die Beobachtungen von "schwarzen Löchern mit den größten bekannten Ereignishorizonten am" Himmel "koordinierten. Allein sind schwarze Löcher nur schwarz, aber diese Monster -Attraktoren sind bekanntermaßen von glühendem Gas umgeben. Das "erste Bild wurde gestern veröffentlicht und löste den Bereich" um das Schwarze Loch in der Mitte von Galaxy M87 auf einer Skala "unter deren Ereignishorizont erwartet erwartet. Im Bild ist die "dunkle Zentralregion nicht der Ereignishorizont, sondern der Schatten des Schwarzen Loch. Die Größe und die "Form des Schattens werden durch helles Gas in der Nähe des" Ereignishorizonts, durch starke Gravitationslinsenablenkungen "und durch den Spin des Schwarzen Lochs bestimmt. Bei der Auflösung des "Schattens dieses Black Hole" unterstützte das Ereignis -Horizon -Teleskop (EHT) die Beweise, dass Einsteins Schwerkraft auch in extremen Regionen arbeitet, und "klare Beweise dafür, dass M87 ein zentrales Spinning Black" Loch mit etwa 6 Milliarden Sonnenmassen hat. Die EHT ist nicht durchgeführt -"Zukünftige Beobachtungen werden auf eine noch höhere Auflösung, eine bessere Verfolgung der Variabilität und die Erforschung der" unmittelbaren Umgebung des Schwarzen Lochs in der Mitte unserer milchigen Way -Galaxie ausgerichtet sein ".',' hdurl ':' https: // apod.NASA.GOV/APOD/Image/1904/M87BH_EHT_2629.JPG ',' media_type ':' Bild ',' service_version ':' v1 ',' title ':' Erster Horizon-Scale-Bild eines schwarzen Lochs ',' url ':' https: // apod.NASA.GOV/APOD/Image/1904/M87BH_EHT_960.JPG ' 


Falls Sie es nicht bemerkt haben, verweist die zurückgegebene Bild -URL auf das kürzlich vorgestellte erste Bild eines schwarzen Lochs:



Das Bild, das durch den API -Anruf zurückgegeben wurde - das erste Bild eines schwarzen Lochs

Senden einer Postanfrage

Das Senden einer Postanforderung mit den Variablen, die in der Anforderungsbehörde in der Standardbibliothek "enthalten" sind, erfordert zusätzliche Schritte. Zunächst konstruieren wir wie zuvor die Postdaten in Form eines Wörterbuchs:

>>> Data =  ... "variable1": "value1", ... "variable2": "value2" ... 
Kopieren

Nachdem wir unser Wörterbuch konstruiert haben, wollen wir das verwenden Urlencode Funktion wie zuvor und codieren zusätzlich die resultierende Zeichenfolge in ASCII:

>>> post_data = urlencode (Daten).codieren ('ascii')

Schließlich können wir unsere Anfrage senden und die Daten als zweites Argument der übergeben urlopen Funktion. In diesem Fall werden wir verwenden https: // httpbin.org/post als Ziel -URL (httpbin.org ist ein Anfrage- und Antwortdienst):

>>> mit urlopen ("https: // httpbin.org/post ", post_data) als Antwort: ... JSON_Response = JSON.Load (Antwort) >>> pprint (json_response) 'args': , 'data': ", 'files': , 'Form': 'variable1': 'value1', 'variable2': ' Value2 ',' Header ': ' Akzeptieren von Kodierung ':' Identität ',' Inhaltslänge ':' 33 ',' Content-Type ':' Application/X-Www-Form-Urlencoded ',' Host '' : 'httpbin.org ',' user-Agent ':' Python-urllib/3.7 ',' Json ': Keine,' Ursprung ':' xx.xx.xx.xx, xx.xx.xx.xx ',' url ':' https: // httpbin.org/post ' 
Kopieren

Die Anfrage war erfolgreich, und der Server gab eine JSON -Antwort zurück, die Informationen zu der Anfrage enthält, die wir gestellt haben. Wie Sie sehen können, werden die Variablen, die wir im Körper der Anfrage bestanden haben 'form' Schlüssel im Reaktionskörper. Lesen Sie den Wert der Header Schlüssel, wir können auch sehen, dass der Inhaltstyp der Anfrage war Anwendung/x-www-form-urlencoded und der Benutzeragent 'Python-urllib/3.7 '.

Senden von JSON -Daten in der Anfrage

Was ist, wenn wir eine JSON -Darstellung von Daten mit unserer Anfrage senden möchten?? Zuerst definieren wir die Struktur der Daten, als sie in JSON umwandeln:

>>> Person =  ... "FirstName": "Luke", ... "LastName": "Skywalker", ... "Titel": "Jedi Knight" ...  
Kopieren

Wir möchten auch ein Wörterbuch verwenden, um benutzerdefinierte Header zu definieren. In diesem Fall möchten wir beispielsweise angeben, dass unser Anforderungsinhalt ist Anwendung/JSON:

>>> Custom_Headers =  ... "Inhaltstyp": "Anwendung/JSON" ... 
Kopieren

Anstatt die Anfrage direkt zu senden, erstellen wir schließlich eine Anfrage Objekt und wir bestehen in der Reihenfolge: Die Ziel -URL, die Anforderungsdaten und die Anforderungsüberschriften als Argumente seines Konstruktors:

>>> von urllib.Anfrage importieren >>> req = Anfrage ( ... "https: // httpbin.org/post ", ... JSON.Dumps (Person).codieren ('ascii'), ... Custom_Headers ...) 
Kopieren

Eine wichtige Sache zu bemerken ist, dass wir die benutzt haben JSON.Dumps Funktionsübergabe Das Wörterbuch, das die Daten enthält, die wir als Argument in die Anfrage aufgenommen werden möchten: Diese Funktion wird verwendet serialisieren ein Objekt in eine JSON -formatierte Zeichenfolge, die wir mit dem codierten kodieren Methode.



Zu diesem Zeitpunkt können wir unsere senden Anfrage, Bestehen Sie es als erstes Argument der urlopen Funktion:

>>> mit urlopen (req) als Antwort: ... JSON_Response = JSON.Last (Antwort) 
Kopieren

Lassen Sie uns den Inhalt der Antwort überprüfen:

'args': , 'Daten': '"FirstName": "Luke", "LastName": "Skywalker", "Titel": "Jedi" Knight "', 'Dateien': , '' Form ': ,' Header ': ' Akzeptieren von Kodierung ':' Identität ',' Inhaltslänge ':' 70 ',' Content-Type ':' Application/JSON ',' Host ':' httpbin.org ',' user-Agent ':' Python-urllib/3.7 ',' json ': ' FirstName ':' Luke ',' LastName ':' Skywalker ',' Titel ':' Jedi Knight ',' Origin ':' xx.xx.xx.xx, xx.xx.xx.xx ',' url ':' https: // httpbin.org/post ' 

Diesmal können wir sehen, dass das mit dem "Form" -Staste im Reaktionskörper verbundene Wörterbuch leer ist und der mit "JSON" -Stast. Wie Sie beobachten können.

Senden einer Anfrage mit einem anderen HTTP -Verb als erhalten oder posten

Bei der Interaktion mit APIs müssen wir möglicherweise verwenden Http Verben anders als nur bekommen oder posten. Um diese Aufgabe zu erfüllen, müssen wir den letzten Parameter der Anfrage Klassenkonstruktor und geben Sie das Verb an, das wir verwenden möchten. Das Standardverb wird erhalten, wenn die Daten Parameter ist Keiner, Ansonsten wird der Beitrag verwendet. Angenommen, wir wollen eine senden SETZEN Anfrage:

>>> Req = Anfrage ( ... "https: // httpbin.org/put ", ... JSON.Dumps (Person).codieren ('ascii'), ... Custom_Headers, ... Methode = 'put' ...) 
Kopieren

Herunterladen einer Datei

Ein weiterer sehr häufiger Vorgang, den wir möglicherweise ausführen möchten, ist das Herunterladen einer Datei aus dem Web herunterzuladen. Mit der Standardbibliothek gibt es zwei Möglichkeiten, dies zu tun: Verwenden der Verwendung der urlopen Funktion, das Lesen der Antwort in Teilen (insbesondere wenn die zum Download der Datei groß ist) und schreibt sie „manuell“ in eine lokale Datei oder verwendet die URLRETRIEVE Funktion, die, wie in der offiziellen Dokumentation angegeben, als Teil einer alten Schnittstelle angesehen wird und in Zukunft veraltet werden könnte. Lassen Sie uns ein Beispiel für beide Strategien sehen.

Herunterladen einer Datei mit urlopen

Sagen Sie, wir möchten den Tarball mit der neuesten Version des Linux -Kernel -Quellcode herunterladen. Mit der ersten Methode, die wir oben erwähnt haben, schreiben wir:

>>> neuest_kernel_tarball = "https: // cdn.Kernel.org/pub/linux/kernel/v5.X/Linux-5.0.7.Teer.XZ ">>> mit urlopen (letztleitend_kernel_tarball) als Antwort: ... mit Open ('letztes Kernel.Teer.xz ',' wb ') als Tarball: ... während wahr: ... Chunk = Antwort.Read (16384) ... Wenn Chunk: ... Tarball.Schreiben Sie (Chunk) ... anders: ... brechen 
Kopieren

Im obigen Beispiel haben wir zuerst beide verwendet urlopen Funktion und die offen Eine im Inneren mit Aussagen und damit die Verwendung des Kontext-Management-Protokolls, um sicherzustellen. In einem während Schleife bei jeder Iteration die Chunk Variable referenziert die aus der Antwort gelesenen Bytes (16384 in diesem Fall - 16 Kibibyten). Wenn Chunk ist nicht leer, wir schreiben den Inhalt an das Dateiobjekt („Tarball“). Wenn es leer ist, bedeutet dies, dass wir den gesamten Inhalt des Reaktionskörpers konsumiert haben. Deshalb brechen wir die Schleife.

Eine prägnantere Lösung beinhaltet die Verwendung der schließen Bibliothek und die CopyFileObj Funktion, die Daten von einem Datei-ähnlichen Objekt (in diesem Fall "Antwort") zu einem anderen Datei-ähnlichen Objekt (in diesem Fall "Tarball" kopiert) kopiert. Die Puffergröße kann unter Verwendung des dritten Arguments der Funktion angegeben werden, das standardmäßig auf 16384 Bytes eingestellt ist):

>>> import Shutil ... mit urlopen (neuest_kernel_tarball) als Antwort: ... mit Open ('letztes Kernel.Teer.xz ',' wb ') als Tarball: ... schließen.CopyFileObj (Antwort, Tarball) 
Kopieren

Herunterladen einer Datei mit der Funktion der UrlRetruve herunterladen

Die alternative und noch prägnantere Methode zum Herunterladen einer Datei mithilfe der Standardbibliothek wird durch die Verwendung des Urlib.Anfrage.URLRETRIEVE Funktion. Die Funktion nimmt vier Argumente auf, aber nur die ersten beiden Interessen haben uns jetzt: Die erste ist obligatorisch und ist die URL der Ressource zum Herunterladen; Der zweite ist der Name, mit dem die Ressource lokal gespeichert wird. Wenn es nicht gegeben ist, wird die Ressource als temporäre Datei in gespeichert /tmp. Der Code wird:

>>> von urllib.anfordern urlretrieve import >>> urlretrieve ("https: // cdn.Kernel.org/pub/linux/kernel/v5.X/Linux-5.0.7.Teer.XZ ") ('neuestes Kernel.Teer.XZ ', ) 
Kopieren

Sehr einfach, nicht wahr?? Die Funktion gibt ein Tupel zurück, das den zum Speichern der Datei verwendeten Namen enthält (dies ist nützlich, wenn die Ressource als temporäre Datei gespeichert wird und der Name zufällig generiert ist) und die HttpMessage Objekt, das die Header der HTTP -Antwort hält.

Schlussfolgerungen

In diesem ersten Teil der Artikelreihe, die Python- und HTTP -Anfragen gewidmet sind. Wenn Sie Zweifel haben oder die Dinge ausführlicher erkunden möchten, konsultieren Sie bitte die offizielle offizielle Urllib.Dokumentation anfordern. Der nächste Teil der Serie konzentriert sich auf die Python HTTP -Anforderungsbibliothek.

Verwandte Linux -Tutorials:

  • Eine Einführung in Linux -Automatisierung, Tools und Techniken
  • Mastering -Bash -Skriptschleifen beherrschen
  • Verschachtelte Schleifen in Bash -Skripten
  • Mint 20: Besser als Ubuntu und Microsoft Windows?
  • Dinge zu installieren auf Ubuntu 20.04
  • Wie man mit der Woocommerce -REST -API mit Python arbeitet
  • So starten Sie externe Prozesse mit Python und dem…
  • Umgang mit Benutzereingaben in Bash -Skripten
  • So laden, entladen und schwarze Liste Linux -Kernel -Module
  • Hung Linux System? Wie man zur Befehlszeile entkommt und…