Netzwerkanfragen mit der Standardbibliothek

PythonBeginner
Jetzt üben

Einführung

In der Arbeit im IT-Betrieb gehört es zu den häufigen Aufgaben, die Verfügbarkeit von Webdiensten zu prüfen. Drittanbieterbibliotheken wie requests sind zwar weit verbreitet, in eingeschränkten Umgebungen dürfen Sie sich jedoch manchmal nur auf Pythons Standardbibliothek verlassen.

In diesem Lab verwenden Sie Pythons Standardbibliotheksmodul urllib, um einen einfachen Verfügbarkeitsprüfer zu erstellen. Das zeigt, dass sich nützliche Werkzeuge für den Betrieb oft ohne zusätzliche Abhängigkeiten entwickeln lassen.

Nach diesem Lab können Sie:

  • das Modul urllib.request importieren;
  • eine Funktion zum Prüfen einer URL definieren;
  • HTTP-Statuscodes abrufen, zum Beispiel 200 OK;
  • Ausnahmen wie Serverfehler oder nicht erreichbare Hosts behandeln;
  • verständliche Statusmeldungen ausgeben.

Module importieren

In diesem Schritt erstellen Sie zunächst ein Python-Skript und importieren das benötigte Modul. Das Modul urllib.request ist Pythons integriertes Werkzeug zum Öffnen von URLs. Sie können es sich wie einen Webbrowser, etwa Chrome oder Firefox, vorstellen, den Sie statt mit der Maus per Code steuern. Ihr Skript kann damit Daten aus dem Internet abrufen.

Das ist im Betrieb nützlich, weil viele Systeme HTTP-basierte APIs oder Health-Endpunkte bereitstellen. Auch wenn Teams später Drittanbieterbibliotheken einsetzen, hilft das Verständnis der Standardbibliothekswerkzeuge dabei, das zugrunde liegende Anfrage-Antwort-Modell klarer zu erkennen.

Stellen Sie zunächst sicher, dass Sie sich im richtigen Verzeichnis befinden. Öffnen Sie Ihr Terminal und wechseln Sie in den Projektordner:

cd ~/project

Erstellen Sie nun mit dem Texteditor nano (oder einem Editor Ihrer Wahl) eine neue Python-Datei namens connectivity_check.py:

nano connectivity_check.py

In Python müssen Sie eine Bibliothek importieren, bevor Sie sie verwenden können. Fügen Sie die folgenden Zeilen am Anfang der Datei ein. Sie importieren urllib.request für die Anfrage und urllib.error für die mögliche Fehlerbehandlung in den späteren Schritten.

import urllib.request
import urllib.error

Drücken Sie Ctrl+O und anschließend Enter, um die Datei zu speichern. Drücken Sie danach Ctrl+X, um nano zu beenden.

Mit dem Befehl cat können Sie den Dateiinhalt überprüfen:

cat connectivity_check.py

Funktion definieren

Nachdem die Imports vorbereitet sind, strukturieren Sie nun den Code. Es ist eine bewährte Vorgehensweise, die Logik in Funktionen zu kapseln. Dadurch wird der Code wiederverwendbar und lässt sich leichter testen.

Funktionen sind besonders für Betriebsskripte nützlich, weil dieselbe Aktion oft für viele Ziele ausgeführt werden muss. Wenn Sie die Netzwerkprüfung in eine Funktion verpacken, können Sie sie für verschiedene URLs aufrufen, statt den Code zu duplizieren.

In diesem Schritt definieren Sie eine Funktion namens check_url, die eine URL-Zeichenkette als Argument entgegennimmt.

Öffnen Sie die Datei connectivity_check.py erneut:

nano connectivity_check.py

Fügen Sie die folgende Funktionsdefinition unterhalb der Import-Anweisungen ein. Zunächst fügen Sie nur die Anweisung pass ein. Sie dient in Python als Platzhalter und bedeutet „nichts tun“. Die eigentliche Logik ergänzen Sie in den nächsten Schritten.

import urllib.request
import urllib.error

def check_url(url):
    print(f"Checking connectivity for: {url}")
    ## Logic will go here
    pass

Speichern Sie die Datei und beenden Sie den Editor (Ctrl+O, Enter, Ctrl+X).

Damit ist das Grundgerüst vorbereitet. Die Funktion check_url erhält einen Parameter namens url. Dieser enthält später die Adresse der Website, die Sie testen möchten, zum Beispiel "https://www.google.com".

Anfrage senden

In diesem Schritt implementieren Sie die zentrale Logik, um eine Anfrage zu senden und den HTTP-Statuscode abzurufen. Der HTTP-Statuscode 200 bedeutet normalerweise „OK“ oder Erfolg.

Auf hoher Ebene ist eine HTTP-Anfrage ein Dialog zwischen Client und Server. Ihr Skript ist der Client. Es sendet eine Anfrage an eine URL, wartet auf die Antwort des Servers und prüft anschließend Metadaten wie den Statuscode, bevor es entscheidet, wie es weitergeht.

Sie verwenden urllib.request.urlopen(), um die URL zu öffnen. Diese Funktion gibt ein Antwortobjekt zurück. Mit dessen Methode .getcode() rufen Sie den Statuscode ab.

Öffnen Sie connectivity_check.py:

nano connectivity_check.py

Ändern Sie Ihre Funktion check_url so, dass sie wie folgt aussieht. Beachten Sie, dass Sie ein Timeout von 5 Sekunden hinzufügen. Dadurch hängt das Skript nicht unbegrenzt, falls der Server nicht antwortet.

import urllib.request
import urllib.error

def check_url(url):
    print(f"Checking connectivity for: {url}")

    ## Open the URL with a 5-second timeout
    response = urllib.request.urlopen(url, timeout=5)

    ## Get the status code
    status_code = response.getcode()

    print(f"Status Code: {status_code}")

Hinweis: In diesem Stadium stürzt das Skript ab, wenn die URL ungültig ist oder der Server nicht erreichbar ist, weil noch keine Fehlerbehandlung vorhanden ist. Das beheben Sie im nächsten Schritt.

Speichern Sie die Datei und beenden Sie den Editor.

Fehler behandeln

Netzwerkprogrammierung ist unvorhersehbar. Server fallen aus, DNS-Abfragen schlagen fehl und Internetverbindungen brechen ab. Wenn urlopen fehlschlägt, löst die Funktion eine Ausnahme aus. Damit das Skript robust arbeitet, müssen Sie diese Ausnahmen mit einem try...except-Block behandeln.

Die Unterscheidung zwischen verschiedenen Fehlerarten ist in der Überwachung realer Systeme wichtig. Wenn ein Server 500 zurückgibt, haben Sie den Server erreicht und er meldet ein internes Problem. Ein URLError bedeutet häufig, dass die Anfrage einen nutzbaren HTTP-Endpunkt überhaupt nicht erreicht hat. Gute Betriebsabläufe behandeln diese Fälle als unterschiedliche Vorfallklassen.

Wir behandeln zwei konkrete Fehlertypen:

  • urllib.error.HTTPError: Der Server hat geantwortet, aber mit einem Fehlercode, zum Beispiel 404 Not Found oder 500 Server Error.
  • urllib.error.URLError: Der Server konnte überhaupt nicht erreicht werden, zum Beispiel wegen fehlendem Internetzugang oder einer falschen Domain.

Sie können sich den try...except-Block als Sicherheitsnetz vorstellen. Wenn etwas schiefgeht, etwa die Internetverbindung ausfällt, stürzt der Code nicht ab. Stattdessen wechselt Python in den passenden except-Block. Dort können Sie den Fehler abfangen und eine hilfreiche Meldung ausgeben.

Öffnen Sie connectivity_check.py:

nano connectivity_check.py

Ändern Sie die Funktion so, dass die Anfrage innerhalb eines try-Blocks ausgeführt wird:

import urllib.request
import urllib.error

def check_url(url):
    print(f"Checking connectivity for: {url}")

    try:
        ## Attempt to open the URL
        response = urllib.request.urlopen(url, timeout=5)
        status_code = response.getcode()
        print(f"Success! Status Code: {status_code}")

    except urllib.error.HTTPError as e:
        ## Server responded with an error (e.g., 404, 500)
        print(f"HTTP Error: {e.code}")

    except urllib.error.URLError as e:
        ## Failed to reach the server
        print(f"URL Error: {e.reason}")

Der Code versucht, die Zeilen im try-Block auszuführen. Wenn ein Fehler auftritt, beendet Python die Ausführung des try-Blocks und springt zum passenden except-Block.

Speichern Sie die Datei und beenden Sie den Editor.

Skript testen

Im letzten Schritt ergänzen Sie einen Hauptblock, der Ihre Funktion aufruft. Dadurch können Sie das Skript direkt im Terminal ausführen.

Das Muster if __name__ == "__main__": ist eine Python-Konvention. Es trennt wiederverwendbare Funktionen von dem Code, der bei einer direkten Ausführung starten soll. Diese kleine Designentscheidung erleichtert die spätere Wiederverwendung: Ein anderes Skript kann check_url importieren, ohne automatisch die Testaufrufe auszuführen.

Sie testen das Skript mit einer bekanntermaßen funktionierenden URL, etwa https://www.example.com. Zusätzlich können Sie eine nicht existierende URL ausprobieren, um die Fehlerbehandlung zu beobachten.

Öffnen Sie connectivity_check.py:

nano connectivity_check.py

Fügen Sie den folgenden Code am Ende der Datei ein:

if __name__ == "__main__":
    ## Test with a valid URL
    target_url = "https://www.example.com"
    check_url(target_url)

    print("-" * 20)

    ## Test with an invalid URL to see error handling
    invalid_url = "https://www.this-domain-does-not-exist-12345.com"
    check_url(invalid_url)

Der Block if __name__ == "__main__": stellt sicher, dass dieser Code nur ausgeführt wird, wenn Sie das Skript direkt starten. Beim Import als Modul in einem anderen Skript wird er nicht ausgeführt.

Speichern Sie die Datei und beenden Sie den Editor.

Führen Sie nun das Skript aus, um die Ergebnisse anzuzeigen:

python3 connectivity_check.py

Sie sollten eine Ausgabe ähnlich der folgenden sehen:

Checking connectivity for: https://www.example.com
Success! Status Code: 200
--------------------
Checking connectivity for: https://www.this-domain-does-not-exist-12345.com
URL Error: [Errno -2] Name or service not known

(Hinweis: Die genaue Fehlermeldung für die ungültige URL kann je nach Netzwerkumgebung leicht abweichen.)

Zusammenfassung

In diesem Lab haben Sie erfolgreich einen Netzwerkverfügbarkeitsprüfer mit Pythons Standardbibliothek erstellt. Sie haben gelernt:

  • Module zu importieren: Sie haben urllib.request und urllib.error verwendet.
  • HTTP-Anfragen zu senden: Sie haben urlopen verwendet, um eine Verbindung zu einem Webserver herzustellen.
  • Antworten zu verarbeiten: Sie haben HTTP-Statuscodes abgerufen, um die Verfügbarkeit eines Dienstes zu prüfen.
  • Fehler zu behandeln: Sie haben try...except-Blöcke für HTTPError und URLError implementiert. Dadurch ist Ihr Skript gegenüber Netzwerkfehlern robust.

Diese Fähigkeit ist grundlegend für die Erstellung von Überwachungsskripten, Health-Checks und einfachen Web-Scrapern in Umgebungen, in denen Sie keine externen Abhängigkeiten installieren können.