5 min Lesezeit 10. Okt. 2026

Python HTTP requests senden: GET, POST & mehr mit requests

So sendest du mit der Python-Bibliothek requests GET- und POST-Anfragen an APIs – mit Beispielen für Azubis, Studenten und Berufseinsteiger.

Marcel Schmidtpeter Von Marcel Schmidtpeter 10. Okt. 2026
Python HTTP requests senden: GET, POST & mehr mit requests

Du sollst in deinem Azubi-Projekt die aktuelle Temperatur vom Wetterdienst abholen, oder dein Professor erwartet eine Hausarbeit, die Daten von einer öffentlichen API auswertet? Dann kommst du nicht darum herum: Python HTTP requests senden - also HTTP-Anfragen direkt aus deinem Programm heraus. Genau das lernst du hier, mit der `requests`-Bibliothek, dem Standardwerkzeug dafür.

Am Ende kannst du GET- und POST-Anfragen senden, Antworten auswerten und typische Fehler abfangen. Ich verwende durchgehend die kostenlose Test-API JSONPlaceholder - da kannst du alles gefahrlos nachbauen.

Was brauchst du für Python HTTP requests?

Du brauchst Python 3 (ab Version 3.8 empfohlen), einen Editor wie VS Code und Grundkenntnisse in Funktionen und Dictionaries. Wenn du bei Dictionaries noch unsicher bist, wirf vorher einen Blick in unseren Artikel zum Python Dictionary.

HTTP (Hypertext Transfer Protocol) ist das Protokoll, mit dem Browser und Server im Web kommunizieren. Jedes Mal, wenn du eine Seite aufrufst, sendet dein Browser eine HTTP-Anfrage. Mit Python machst du genau das Gleiche - nur programmatisch.

Was ist die requests-Bibliothek?

`requests` ist eine externe Python-Bibliothek zum Senden von HTTP-Anfragen. Sie ist die verbreitetste Lösung dafür, weil sie die komplizierte Standardbibliothek `urllib` hinter einer einfachen API versteckt.

Merke: Für HTTP-Anfragen in Python nutzt du in der Praxis fast immer `requests` - nicht die eingebaute `urllib`-Bibliothek. Der Komfort-Unterschied ist enorm.

Die offizielle Dokumentation findest du unter requests.readthedocs.io.

Schritt 1: Wie installierst du requests?

`requests` ist nicht in Python enthalten. Du installierst es mit pip, dem Paketmanager von Python:

bash
pip install requests

Warum eine virtuelle Umgebung? Weil du Projektabhängigkeiten sauber getrennt halten willst. Wie das funktioniert, erklären wir im Artikel zu pip und virtualenv.

Schritt 2: Wie sendest du einen GET-Request?

Ein GET-Request holt Daten von einem Server - wie ein Browser, der eine Webseite lädt. Das ist die häufigste HTTP-Methode.

python
import requests

response = requests.get("https://jsonplaceholder.typicode.com/posts/1")
print(response.status_code)  # 200
print(response.text)  # Rohdaten als String

Das zurückgegebene Objekt ist ein Response-Objekt. Es enthält alles, was der Server geantwortet hat.

Schritt 3: Wie wertest du die Antwort aus?

Die Antwort steckt komplett im Response-Objekt. Die drei wichtigsten Eigenschaften:

Eigenschaft

Bedeutung

Beispiel

`status_code`

HTTP-Statuscode als Zahl

`200` = Erfolg

`text`

Antwort als String

HTML oder roher Text

`json()`

Antwort als Python-Datenstruktur

Dictionary oder Liste

Der Statuscode sagt dir, ob die Anfrage erfolgreich war. `200` bedeutet OK, `404` bedeutet "nicht gefunden", `500` ein Serverfehler. Eine vollständige Liste findest du bei MDN Web Docs.

Faustregel: `2xx` = Erfolg, `4xx` = Fehler auf deiner Seite, `5xx` = Fehler beim Server.

Da APIs fast immer JSON (JavaScript Object Notation, ein Textformat für strukturierte Daten) zurückliefern, brauchst du meist `response.json()`:

python
import requests

response = requests.get("https://jsonplaceholder.typicode.com/posts/1")
daten = response.json()
print(daten["title"])  # Titel des Posts ausgeben

Mehr zum Arbeiten mit JSON-Daten findest du in unserem Artikel zum JSON-Modul.

Schritt 4: Wie übergibst du Query-Parameter?

Query-Parameter sind Filter, die du an eine URL anhängst - etwa `?userId=1`. Stell dir das wie einen Bestellzettel vor: Du sagst dem Server genau, was du willst. `requests` baut die URL automatisch zusammen:

python
import requests

response = requests.get(
    "https://jsonplaceholder.typicode.com/posts", params={"userId": 1}
)
print(response.url)
# https://jsonplaceholder.typicode.com/posts?userId=1

posts = response.json()
print(f"Anzahl Posts: {len(posts)}")

Warum `params` nutzen statt die URL von Hand zusammensetzen? Weil `requests` Sonderzeichen automatisch korrekt kodiert (URL-Encoding). Das vermeidet eine klassische Fehlerquelle.

Schritt 5: Wie sendest du einen POST-Request?

Ein POST-Request sendet Daten an den Server - etwa um einen neuen Eintrag zu erstellen. Das ist der Unterschied: GET holt, POST schickt.

python
import requests

neuer_post = {
    "title": "Mein erster POST-Request",
    "body": "Hallo von Python aus",
    "userId": 1,
}

response = requests.post(
    "https://jsonplaceholder.typicode.com/posts", json=neuer_post
)
print(response.status_code)  # 201 = Created
print(response.json()["id"])  # 101 (neue ID vom Server)

Der Parameter `json=neuer_post` wandelt dein Dictionary automatisch in JSON um und setzt den passenden Header. Alternativ gibt es `data=` für Formulardaten - für den Anfang brauchst du aber fast immer `json=`.

Alle HTTP-Methoden im Überblick

Methode

Zweck

requests-Funktion

GET

Daten abrufen

`requests.get(url)`

POST

Daten erstellen/senden

`requests.post(url, json=daten)`

PUT

Daten vollständig ersetzen

`requests.put(url, json=daten)`

PATCH

Daten teilweise ändern

`requests.patch(url, json=daten)`

DELETE

Daten löschen

`requests.delete(url)`

PUT, PATCH und DELETE funktionieren nach demselben Muster wie POST - nur mit anderer Methode.

Schritt 6: Wie funktionieren Timeout und Fehlerbehandlung?

Jeder produktive Request braucht zwei Dinge: einen Timeout und Fehlerbehandlung. Ohne Timeout kann dein Programm bei einem trägen Server ewig hängen - genau hier machen viele Einsteiger den Fehler. Immer einen Timeout mitgeben, das gilt für jede ernsthafte Anwendung, nicht nur für Übungen.

python
import requests

try:
    response = requests.get(
        "https://jsonplaceholder.typicode.com/posts/1",
        timeout=5,  # maximal 5 Sekunden warten
    )
    response.raise_for_status()  # wirft Exception bei 4xx/5xx
    print(response.json())
except requests.exceptions.Timeout:
    print("Server hat nicht rechtzeitig geantwortet.")
except requests.exceptions.HTTPError as fehler:
    print(f"HTTP-Fehler: {fehler}")
except requests.exceptions.RequestException as fehler:
    print(f"Allgemeiner Fehler: {fehler}")

Die Methode `raise_for_status()` wirft eine Exception (einen Fehler, den du abfangen kannst), wenn der Statuscode 4xx oder 5xx ist - also wenn etwas schiefging. Falls try/except noch neu für dich ist, lies unseren Artikel zum Exception Handling in Python.

Merke: Immer `timeout=` setzen und Exceptions behandeln. Ein Programm ohne Timeout und Fehlerbehandlung ist in der Praxis unbrauchbar.

Vollständiges Beispiel: API-Client mit GET und POST

Alle Schritte zusammen in einem lauffähigen Programm:

python
import requests

BASE_URL = "https://jsonplaceholder.typicode.com"


def hole_posts_von_user(user_id):
    """Holt alle Posts eines Users per GET-Request."""
    try:
        response = requests.get(
            f"{BASE_URL}/posts", params={"userId": user_id}, timeout=5
        )
        response.raise_for_status()
        return response.json()
    except requests.exceptions.RequestException as fehler:
        print(f"Fehler beim Laden: {fehler}")
        return []


def erstelle_post(titel, inhalt):
    """Erstellt einen neuen Post per POST-Request."""
    daten = {"title": titel, "body": inhalt, "userId": 1}
    try:
        response = requests.post(f"{BASE_URL}/posts", json=daten, timeout=5)
        response.raise_for_status()
        return response.json()
    except requests.exceptions.RequestException as fehler:
        print(f"Fehler beim Erstellen: {fehler}")
        return None


def main():
    # GET: Posts von User 1 laden
    posts = hole_posts_von_user(1)
    print(f"{len(posts)} Posts gefunden")
    for post in posts[:3]:
        print(f"- {post['title']}")

    # POST: Neuen Post erstellen
    neuer = erstelle_post("Mein Titel", "Mein Inhalt")
    if neuer:
        print(f"Neuer Post erstellt mit ID {neuer['id']}")


if __name__ == "__main__":
    main()

Häufige Probleme & Lösungen

Diese drei Meldungen sehen Einsteiger besonders oft. Hier kommen Ursache und Lösung für jede davon.

Problem 1: ModuleNotFoundError: No module named 'requests'

Die Bibliothek ist nicht installiert - oder nicht in der Umgebung, die dein Skript nutzt. Prüfe mit `pip list`, ob requests erscheint. Falls du virtualenv nutzt: Ist die richtige Umgebung aktiviert? Lösung: `pip install requests` in der aktiven Umgebung ausführen.

Problem 2: json.decoder.JSONDecodeError

Du rufst `response.json()` auf, aber der Server hat kein JSON geliefert - etwa eine HTML-Fehlerseite. Prüfe vorher `response.status_code` und schau dir `response.text` an. Mit `raise_for_status()` vor dem JSON-Aufruf fängst du das Problem früher.

Problem 3: SSLError oder Zertifikatsfehler

Das passiert oft hinter Firmen-Proxys mit selbstsignierten Zertifikaten - in der Ausbildung wirst du das früher oder später erleben. Die saubere Lösung: das Zertifikat des Unternehmens als CA-Bundle einbinden, etwa über die Umgebungsvariable `REQUESTS_CA_BUNDLE` oder den Parameter `verify="pfad/zur/zertifikatsdatei.pem"`.

Nicht `verify=False` verwenden - das deaktiviert die Sicherheitsprüfung und ist ein echtes Risiko.

FAQ

Wie sende ich Headers mit einem Request in Python?

Über den `headers`-Parameter als Dictionary: `requests.get(url, headers={"Authorization": "Bearer TOKEN"})`. Das brauchst du bei APIs mit Authentifizierung (der Server prüft, ob du berechtigt bist) fast immer.

Was ist der Unterschied zwischen GET und POST?

GET holt Daten vom Server und verändert nichts. POST sendet Daten an den Server, um etwas zu erstellen oder zu verarbeiten. GET-Parameter stehen in der URL, POST-Daten im Request-Body.

Wie teste ich eine API ohne eigenes Programm?

Mit Tools wie curl oder Postman kannst du Requests manuell senden. Für automatisierte Tests in Python eignet sich pytest - dazu haben wir einen eigenen Artikel zu pytest Unit Tests.

Was bedeutet Statuscode 401 vs. 403?

`401 Unauthorized` bedeutet: Du bist nicht authentifiziert (z. B. kein oder ungültiger Token). `403 Forbidden` bedeutet: Du bist authentifiziert, aber darfst die Ressource nicht sehen.

Kann requests auch asynchron arbeiten?

Nein, `requests` arbeitet nur synchron - dein Programm wartet auf jede Antwort. Für viele parallele Requests nutzt du `httpx` oder `aiohttp` mit `async/await`.

Fazit

Python HTTP requests zu senden ist mit der `requests`-Bibliothek denkbar einfach: GET holt Daten, POST erstellt sie, PUT/PATCH/DELETE verändern sie. Die wichtigsten Regeln: `response.json()` für JSON-Antworten, `params` für Query-Parameter, `json=` für POST-Daten - und immer Timeout plus Fehlerbehandlung.

Damit kannst du jede REST-API anbinden, von der Wetter-API im Azubi-Projekt bis zur Datensammlung für die Bachelorarbeit. Der nächste logische Schritt: die geholten Daten in einer Datenbank speichern - dazu haben wir einen Artikel zu Python und sqlite3.

Wenn du bei HTTP, APIs oder generell beim Python-Lernen festhängst: Bei study-it.education bekommst du individuelle Nachhilfe von echten Profis - egal ob du Azubi, Student oder Quereinsteiger bist. Schau vorbei und lass uns gemeinsam an deinem Projekt arbeiten!


Passende Nachhilfe

1:1-Hilfe zu diesem Thema?

Erstgespräch · 0 € · 30 min

Brauchst du jemand, der das mit dir durchgeht?

Statt nochmal lesen: 30 min mit einem Senior-Dev.

Kostenloses Erstgespräch buchen →
Über den Autor
Marcel Schmidtpeter
Marcel Schmidtpeter

So sendest du mit der Python-Bibliothek requests GET- und POST-Anfragen an APIs – mit Beispielen für Azubis, Studenten und Berufseinsteiger.

marcel.schmidtpeter@study-it.education →
Weiterlesen

Mehr Lesestoff