Eine URL in Python zu kürzen ist ein einziger HTTP-POST. Sie senden Ihren langen Link mit der requests-Bibliothek an die API eines Shorteners, übergeben Ihren API-Schlüssel als Bearer-Token und lesen den Kurzlink aus der JSON-Antwort aus. Das Ganze passt in etwa fünf Zeilen, und der Rest dieses Leitfadens beschreibt, was Sie ergänzen, sobald Sie es im Ernstfall einsetzen: Fehlerbehandlung, Idempotenz, Bulk und Async.
Dies ist die Entwickler-Version der allgemeinen Anleitung zum Kürzen einer URL - jene behandelt den Dashboard- und Browser-Ablauf, dies hier ist Code, den Sie in ein Skript einfügen können. Die Endpunkte und Feldnamen unten verwenden die Elido-API, aber die Grundform (eine Ziel-URL per POST senden, eine kurze URL zurückbekommen) ist bei den meisten modernen Shortenern gleich, sodass sich die Muster übertragen lassen.
Beginnen Sie mit dem Überblick über die kostenlose URL-Shortener-API, falls Sie noch keinen Dienst gewählt haben - dort werden die Form der Anfrage, das Auth-Modell und die Grenzen der kostenlosen Stufe erläutert, von denen dieser Artikel ausgeht.
Der schnellste Weg: ein einziger POST mit requests
Installieren Sie requests, legen Sie Ihren API-Schlüssel in einer Umgebungsvariable ab und senden Sie die Ziel-URL per POST an den Links-Endpunkt:
import os
import requests
resp = requests.post(
"https://api.elido.app/v1/links",
headers={"Authorization": f"Bearer {os.environ['ELIDO_API_KEY']}"},
json={"destination_url": "https://example.com/a-very-long-path?with=params"},
timeout=10,
)
resp.raise_for_status()
print(resp.json()["short_url"]) # -> https://s.elido.me/ab12cd
Drei Dinge machen daraus produktionsreifen Code statt eines Spielzeugs. Der API-Schlüssel kommt aus der Umgebung, niemals als Literal im Quellcode. timeout ist gesetzt, sodass eine hängende Verbindung schnell fehlschlägt, statt endlos zu blockieren. Und raise_for_status() verwandelt einen 4xx- oder 5xx-Fehler in eine Exception, die Sie abfangen können, statt einen fehlgeschlagenen Aufruf wie einen Erfolg aussehen zu lassen.
Die Antwort ist JSON. Lesen Sie short_url für den fertigen Link aus; die meisten Shortener geben zudem eine id zurück, die Sie speichern, falls Sie den Link später bearbeiten oder ablaufen lassen möchten.
Fehler und Rate-Limits richtig behandeln
Der Idealfall sind fünf Zeilen. Ein Skript, das unbeaufsichtigt läuft, muss auch die unschönen Fälle überstehen: einen vorübergehenden 5xx, einen 429, wenn Sie zu schnell unterwegs sind, einen kurzen Netzwerkaussetzer. Umschließen Sie den Aufruf so, dass er bei den Fehlern erneut versucht, bei denen sich das lohnt, und bei denen aufgibt, die ohnehin nie gelingen.
import os
import time
import requests
def shorten(destination: str, *, retries: int = 3) -> str:
headers = {"Authorization": f"Bearer {os.environ['ELIDO_API_KEY']}"}
for attempt in range(retries):
resp = requests.post(
"https://api.elido.app/v1/links",
headers=headers,
json={"destination_url": destination},
timeout=10,
)
if resp.status_code == 429:
time.sleep(int(resp.headers.get("Retry-After", 2)))
continue
if resp.status_code >= 500:
time.sleep(2 ** attempt) # exponential backoff
continue
resp.raise_for_status() # 4xx other than 429 -> raise
return resp.json()["short_url"]
raise RuntimeError(f"shorten failed after {retries} attempts")
Ein 401 oder 403 behebt sich niemals von selbst durch erneutes Versuchen, deshalb fallen diese durch zu raise_for_status() und stoppen das Skript. Ein 429 respektiert den Retry-After-Header, den die API sendet. Ein 5xx bremst exponentiell ab. Der Deep-Dive zu Rate-Limits und Idempotenz erklärt, warum blindes erneutes Versuchen aus einem Ausfall zwei macht.
Einen Idempotency-Key senden, damit Retries nicht duplizieren
Hier ist der subtile Fehler in der obigen Retry-Schleife. Gelingt ein POST auf dem Server, geht die Antwort aber auf dem Rückweg verloren, sieht Ihr Code ein Timeout, versucht es erneut und erzeugt einen zweiten Kurzlink für dieselbe URL. Ein Idempotency-Key behebt das: Senden Sie mit jeder logischen Anfrage einen stabilen, eindeutigen Schlüssel, und die API gibt bei einer Wiederholung den ursprünglichen Link zurück, statt einen neuen zu prägen.
import uuid
key = str(uuid.uuid4()) # one key per URL you want shortened once
resp = requests.post(
"https://api.elido.app/v1/links",
headers={
"Authorization": f"Bearer {os.environ['ELIDO_API_KEY']}",
"Idempotency-Key": key,
},
json={"destination_url": "https://example.com/launch"},
timeout=10,
)
Erzeugen Sie den Schlüssel einmal pro URL und verwenden Sie ihn bei allen Retries derselben URL wieder - nicht pro Versuch. Speichern Sie ihn zusammen mit der URL, falls der Batch selbst erneut ausgeführt werden könnte. Das ist die mit Abstand wichtigste Gewohnheit, wenn Sie vom Kürzen eines einzelnen Links zum Kürzen einer Liste übergehen, und genau deshalb ist sie fest in API und SDKs eingebaut.
URLs in großen Mengen kürzen
Mit einer sicheren shorten()-Funktion in der Hand ist ein Batch nur eine Schleife - aber eine Schleife, die das Rate-Limit respektiert und die Zuordnung zwischen Eingabe und Ausgabe nicht verliert:
urls = [
"https://example.com/spring-sale",
"https://example.com/newsletter",
"https://example.com/docs/getting-started",
]
results = {}
for url in urls:
try:
results[url] = shorten(url)
except Exception as err: # log and keep going; one bad URL should not sink the batch
results[url] = f"ERROR: {err}"
for original, short in results.items():
print(f"{short}\t{original}")
Das Ergebnis in einem dict zu halten, das nach der ursprünglichen URL geschlüsselt ist, sorgt dafür, dass ein teilweiser Fehlschlag sichtbar und erneut ausführbar ist, statt eine stille Lücke zu sein. Für ein paar Hundert Links ist diese sequenzielle Version völlig ausreichend. Bei Tausenden summiert sich die Round-Trip-Latenz, und genau da verdient sich Async seinen Platz.
Async im großen Maßstab mit httpx
Ist der Batch groß, liegt der Engpass im Warten auf das Netzwerk, nicht in Python. Ein asynchroner Client wie httpx sendet viele Anfragen gleichzeitig und hält dabei eine Obergrenze ein, wie viele davon gerade unterwegs sind, sodass Sie die Verbindung ausschöpfen, ohne das Rate-Limit auszulösen.
import asyncio
import os
import httpx
async def shorten_all(urls: list[str], concurrency: int = 10) -> dict[str, str]:
headers = {"Authorization": f"Bearer {os.environ['ELIDO_API_KEY']}"}
limit = asyncio.Semaphore(concurrency)
out: dict[str, str] = {}
async with httpx.AsyncClient(timeout=10) as client:
async def one(url: str) -> None:
async with limit:
r = await client.post(
"https://api.elido.app/v1/links",
headers=headers,
json={"destination_url": url},
)
out[url] = r.json()["short_url"]
await asyncio.gather(*(one(u) for u in urls))
return out
# asyncio.run(shorten_all(my_urls))
Semaphore(10) ist der ganze Trick: Es begrenzt gleichzeitige Anfragen auf zehn, sodass Sie schnell vorankommen, ohne die API in 429-Fehler zu hämmern. Passen Sie den Wert an das dokumentierte Limit Ihres Plans an. Für die vollständige Form der Anfrage, die Feldnamen und die aktuellen Limits ist die API-Dokumentation die Referenz, und Lösungen für Entwickler bietet die SDKs, falls Sie den Client lieber nicht selbst bauen möchten.
Welchen Ansatz Sie wählen sollten
Wählen Sie das Werkzeug passend zur Größe der Aufgabe. Ein Link in einem Skript: der fünfzeilige requests-Aufruf. Ein verlässlicher, zeitgesteuerter Job: die Version mit Retry und Idempotenz. Ein einmaliger Batch von ein paar Hundert: die sequenzielle Schleife. Zehntausende unter Zeitdruck: httpx mit einem semaphore.
Für welchen Sie sich auch entscheiden: Bewahren Sie den Schlüssel in der Umgebung auf, setzen Sie ein Timeout, und senden Sie einen Idempotency-Key bei allem, was erneut versucht werden könnte. Diese drei Gewohnheiten sind der Unterschied zwischen einem Snippet, das nur vorführt, und einem Skript, das Sie laufen lassen können.
Die Grundlagenserie lesen
Dieser Beitrag gehört zum Engineering-Cluster. Der Ausgangspunkt ist der Leitfaden zur kostenlosen URL-Shortener-API für die Form der Endpunkte und die Authentifizierung, danach der Beitrag zu Rate-Limits und Idempotenz für gutes Verhalten unter Last. Die lebende Referenz ist die API-Dokumentation.
Verwandte Beiträge im Blog
Häufig gestellte Fragen
Wie kürze ich eine URL in Python?
Senden Sie mit der requests-Bibliothek einen HTTP-POST an die API eines URL-Shorteners, übergeben Sie Ihre lange URL im JSON-Body und Ihren API-Schlüssel als Bearer-Token, und lesen Sie den Kurzlink anschließend aus der JSON-Antwort aus. Das sind etwa fünf Zeilen: die Header aufbauen, die Ziel-URL an den Links-Endpunkt posten und response.json()['short_url'] ausgeben.
Kann ich eine URL in Python ohne externe Bibliothek kürzen?
Ja. Das urllib.request-Modul der Standardbibliothek kann JSON per POST senden, ohne dass irgendetwas installiert werden muss, was in einer abgeriegelten Umgebung praktisch ist. Es ist umständlicher als requests - Sie kodieren den Body selbst, setzen die Header manuell und lesen die Antwort aus - aber es braucht kein pip install.
Wie kürze ich in Python viele URLs auf einmal?
Iterieren Sie über die Liste und senden Sie für jede einen POST, aber schicken Sie pro URL einen Idempotency-Key, damit ein Retry niemals ein Duplikat erzeugt, und respektieren Sie das Rate-Limit der API, indem Sie bei HTTP 429 abbremsen. Bei großen Batches kürzt ein asynchroner Client wie httpx mit einem begrenzten semaphore Tausende URLs gleichzeitig, statt eine nach der anderen.
Warum liefert meine Python-Anfrage an den URL-Shortener einen 401 zurück?
Ein 401 bedeutet, dass der API-Schlüssel im Authorization-Header fehlt oder falsch ist. Prüfen Sie, dass Sie genau 'Authorization: Bearer YOUR_API_KEY' senden, dass der Schlüssel nicht widerrufen wurde, und dass Sie ihn aus einer Umgebungsvariable geladen haben, statt einen abgelaufenen einzufügen. Ein 403 bedeutet dagegen, dass der Schlüssel gültig ist, aber für diese Aktion nicht die nötige Berechtigung (Scope) hat.
Elido testen
URL einfügen, kurzer Link in Sekunden
Kein Konto nötig. Link bleibt 30 Tage aktiv. Konto erstellen, um ihn dauerhaft zu behalten.
Kostenlos, keine Anmeldung erforderlich · 2 pro Tag