cURL ist der schnellste Weg, eine Webseite vom Terminal aus abzurufen. Es spricht HTTP, HTTPS, FTP und mehr, ist auf nahezu jeder Maschine verfügbar und tut genau eine Sache gut: eine Anfrage senden und die rohe Antwort zurückgeben. Das macht cURL für Web Scraping zu einem naheliegenden ersten Werkzeug, egal ob man einen Endpunkt manuell prüft, eine Anfrage prototypisch erstellt, bevor man echten Code schreibt, oder einen Einzeiler in ein Shell-Skript einbindet.
Dieser Leitfaden ist eine praktische Befehlszeilen-Walkthrough. Sie werden eine Seite abrufen, auf Disk speichern, Weiterleitungen folgen, Header und einen User-Agent setzen, Cookies senden, Formular- und JSON-Daten per POST übertragen, über einen Proxy routen und den HTTP-Statuscode lesen. Danach betrachten wir, wo reines cURL an seine Grenzen stößt (JavaScript-gerenderte Seiten und Anti-Bot-Sperren) und wie man über die Crawlbase Crawling API und den Smart AI Proxy fertiges HTML erhält, ohne das Terminal zu verlassen.
Warum überhaupt cURL zum Scrapen?
Die meisten Scraping-Projekte landen in Python oder Node, warum also an der Befehlszeile starten? Weil cURL der kürzeste Weg von "Was gibt diese URL zurück?" zur Antwort ist. Es gibt nichts zu installieren, kein Skript zu schreiben, keine Abhängigkeiten zu verwalten. Man gibt einen Befehl ein und sieht die genauen Bytes, die der Server gesendet hat, Header inklusive. Wenn ein Scraper falsch läuft, ist die Reproduktion der Anfrage in cURL der schnellste Weg herauszufinden, ob das Problem im eigenen Code oder am Server liegt.
cURL ist außerdem komponierbar. Da es rohe Ausgabe nach stdout schreibt, kann man es direkt in einen Parser, ein grep oder eine Datei pipen und in wenigen Bash-Zeilen über eine URL-Liste schleifen. Für kleine Aufgaben reicht dieses Muster oft vollständig aus. Für größere ist cURL immer noch das Werkzeug, das man zum Debuggen der Anfrage greift, bevor man sie skaliert.
Eine Seite per GET-Anfrage abrufen
Das einfachste mögliche Scraping ist ein bloßes GET. Man zeigt cURL auf eine URL und es gibt den Antwort-Body im Terminal aus.
curl https://example.com
Standardmäßig sendet cURL eine GET-Anfrage, es muss also kein Flag hinzugefügt werden. Das HTML flutet das Terminal, was für einen kurzen Blick in Ordnung ist, aber für größere Mengen nicht geeignet. Die nächsten Schritte befassen sich damit, die Ausgabe zu kontrollieren: speichern, Rauschen reduzieren und die Metadaten rund um den Body lesen. Für einen tieferen Einblick auf der Anfrage-Seite, siehe wie man GET-Anfragen mit cURL sendet.
Die Antwort in einer Datei speichern
Zwei Flags erledigen das Speichern. Mit -o schreibt man in einen selbst gewählten Dateinamen, mit -O (großes O) behält man den Remote-Dateinamen aus der URL.
# Write the body to a named file curl -o page.html https://example.com # Keep the remote filename (saves as report.pdf) curl -O https://example.com/files/report.pdf
Das Speichern auf Disk ist die Grundlage jedes Batch-Scrapings: einmal abrufen, später parsen und den Server nicht erneut treffen, während man die Extraktionslogik verfeinert. Es hält außerdem eine rohe Kopie bereit, die man vergleichen kann, wenn sich das Markup einer Seite ändert.
Weiterleitungen mit -L folgen
Standardmäßig folgt cURL keinen Weiterleitungen. Gibt eine URL einen 301 oder 302 zurück, erhält man die Weiterleitungs-Antwort selbst, nicht die Seite, auf die sie zeigt. Das ist ein klassischer Grund, warum ein Scraping-Ergebnis leer ist. Das Flag -L weist cURL an, dem Location-Header bis zum endgültigen Ziel zu folgen.
curl -L https://example.com/old-path
Die meisten Produktionsseiten leiten HTTP auf HTTPS um, normalisieren abschließende Schrägstriche oder verschieben Seiten, daher ist -L ein Flag, das man fast immer setzen sollte. Wenn man stattdessen eine Weiterleitungskette untersuchen möchte, anstatt ihr blind zu folgen, lässt man -L weg und liest die Statuszeile und den Location-Header direkt.
Einen User-Agent und andere Header setzen
cURL kündigt sich mit einem User-Agent wie curl/8.4.0 an, den viele Seiten sofort als Nicht-Browser erkennen. Das Senden eines realistischen User-Agents ist der Header mit dem höchsten Einzelwert, den man setzen kann. Mit -H fügt man beliebige Header hinzu, oder man verwendet das dedizierte Flag -A für den User-Agent.
# Set a browser-like User-Agent with -A curl -A "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" https://example.com # Add multiple headers with repeated -H flags curl https://example.com \ -H "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)" \ -H "Accept-Language: en-US,en;q=0.9" \ -H "Referer: https://www.google.com/"
Realistische Header lassen die Anfrage wie einen Browser aussehen und nicht wie ein Skript. Ein sinnvolles Standard-Set besteht aus einem aktuellen User-Agent, einem Accept- und Accept-Language-Paar und manchmal einem Referer. Für das vollständige Bild, welche Header warum wichtig sind, siehe wie man HTTP-Header mit cURL sendet.
Cookies senden und speichern
Manche Seiten benötigen eine Session, bevor sie Inhalte zurückgeben: ein Zustimmungs-Cookie, eine Regionsauswahl oder einen eingeloggten Zustand. cURL behandelt Cookies mit zwei Flags. Mit -b sendet man Cookies, mit -c speichert man die vom Server gesetzten Cookies in einer Datei (ein Cookie-Jar), damit eine spätere Anfrage sie wiederverwenden kann.
# Send a cookie inline curl -b "consent=1; region=us" https://example.com # First request: save cookies the server sets into a jar curl -c cookies.txt https://example.com/start # Second request: replay the saved cookies curl -b cookies.txt https://example.com/dashboard
Das Speichern-und-Wiederholen-Muster ermöglicht einen zweistufigen Ablauf von der Befehlszeile aus: die Eingangsseite aufrufen, um Cookies zu sammeln, und diese dann in die eigentlich gewünschte Seite übertragen. Man kann -b und -c in einer einzigen Anfrage kombinieren, um den Jar gleichzeitig zu laden und zu aktualisieren, wenn sich eine Session weiterentwickelt.
Formular- und JSON-Daten per POST senden
Scraping ist nicht immer GET. Suchformulare, Filter und APIs erwarten oft einen POST. Das Flag -d sendet Daten und wechselt implizit die Methode auf POST. Standardmäßig sendet es form-kodierte Daten; man setzt Content-Type: application/json, um einen JSON-Body zu senden.
# Form-encoded POST (application/x-www-form-urlencoded) curl -d "query=laptops&page=2" https://example.com/search # JSON POST: set the method and content type explicitly curl -X POST https://example.com/api/search \ -H "Content-Type: application/json" \ -d '{"query": "laptops", "page": 2}'
Bei Formulardaten werden Felder mit & getrennt, genau wie es ein Browser tun würde. Bei JSON umschließt man den Body in einfachen Anführungszeichen, damit die Shell die doppelten Anführungszeichen unangetastet lässt, und sendet immer den passenden Content-Type, da der Server die Nutzdaten sonst ablehnen oder falsch lesen könnte. Eine JSON-API direkt auf diese Weise anzusprechen ist oft sauberer als gerendertes HTML zu scrapen, wenn der Endpunkt verfügbar ist.
cURL durch einen Proxy routen
Scraping von einer einzigen IP in großem Volumen führt dazu, dass diese IP rate-limitiert oder gesperrt wird. Das Routen über einen Proxy stellt eine andere Adresse vor die Anfrage. Das Flag -x setzt den Proxy, mit optionalen user:pass@-Anmeldeinformationen.
# Plain HTTP proxy curl -x http://proxy.example.com:8080 https://example.com # Authenticated proxy curl -x http://user:[email protected]:8080 https://example.com
Ein einzelner statischer Proxy verlagert das Problem nur auf eine neue IP. Was ein echtes Scraping am Laufen hält, ist die Rotation über viele Adressen hinweg, sodass keine einzelne ein Limit auslöst. Die vollständige Mechanik, cURL auf einen Proxy zu zeigen, einschließlich SOCKS und rotierender Endpunkte, wird in wie man cURL mit einem Proxy verwendet behandelt.
Leise, ausführlich und den Statuscode lesen
Für Scripting möchte man cURL normalerweise ruhig halten, außer wenn etwas kaputt geht, dann möchte man alles sehen. Das Flag -s schaltet den Fortschrittsbalken stumm; -v gibt die vollständige Anfrage und Antwort aus, Header und alles, was beim Debuggen einer Sperre unschätzbar wertvoll ist. Um nur den HTTP-Statuscode zu lesen, verwendet man eine Write-out-Vorlage.
# Silent: no progress meter, just the body curl -s https://example.com -o page.html # Verbose: see the full request/response exchange curl -v https://example.com # Print only the HTTP status code, discard the body curl -s -o /dev/null -w "%{http_code}\n" https://example.com
Dieser letzte Befehl ist ein Arbeitstier: er verwirft den Body, gibt nur den Statuscode aus und liefert ein sauberes Signal, auf das ein Skript verzweigen kann. Ein 200 bedeutet weiterfahren; ein 403 oder 429 bedeutet, man wird herausgefordert oder gedrosselt und sollte zurückrudern oder die Taktik wechseln. Statuscodes zu lesen ist der Weg, einen gesunden Lauf von einem gesperrten zu unterscheiden.
cURL in einen Parser pipen
cURL ruft ab; es parst nicht. Die Unix-Antwort besteht darin, seine Ausgabe in ein Werkzeug zu pipen, das das tut. Für einen schnellen Feldgriff pipt man in grep oder einen kleinen Python-Einzeiler; für echte HTML-Abfragen ist ein Werkzeug wie htmlq (CSS-Selektoren auf der Befehlszeile) kaum zu schlagen.
# Grab the <title> with grep curl -s https://example.com | grep -o '<title>[^<]*</title>' # Parse properly with htmlq (CSS selectors) curl -s https://example.com | htmlq 'h1' --text # Hand the HTML to Python for structured extraction curl -s https://example.com | python3 -c \ "import sys; from bs4 import BeautifulSoup; \ print(BeautifulSoup(sys.stdin.read(), 'html.parser').title.text)"
Regex mit grep ist für einen einmaligen Feldgriff in Ordnung, aber auf echtem Markup fragil; man greift zu einem HTML-bewussten Parser, sobald die Struktur verschachtelt wird. Das Python-Pipe skaliert natürlich zu einem vollständigen BeautifulSoup-Skript, wenn die Extraktion über einen einzigen Selektor hinauswächst.
Über eine URL-Liste in Bash schleifen
Eine URL ist ein Test; ein Scraping ist eine Liste. Eine kurze Bash-Schleife liest URLs aus einer Datei, ruft jede ab, prüft den Status und speichert die erfolgreichen. Eine Pause zwischen Anfragen verhindert, dass der Server hammered wird.
while read url; do slug=$(echo "$url" | md5sum | cut -c1-8) code=$(curl -s -L -o "out_$slug.html" -w "%{http_code}" "$url") echo "$code $url" sleep 2 done < urls.txt
Dieses Muster deckt überraschend viel ab: eine Datei mit URLs, je ein Abruf, Weiterleitungen werden gefolgt, der Status protokolliert, die Ausgabe unter einem stabilen Namen gespeichert und eine zweisekündige Pause zwischen den Zugriffen. Die sleep-Dauer auf die Toleranz des Ziels abstimmen, und man hat einen höflichen, neustartfähigen Crawler in sechs Zeilen.
Wo reines cURL an Grenzen stößt
cURL ist ein HTTP-Client, kein Browser. Dieser Unterschied ist die ganze Geschichte, wo es beim modernen Scraping aufhört zu funktionieren, und er zeigt sich auf zwei Arten.
Es kann kein JavaScript ausführen. cURL ruft das rohe HTML ab, das der Server sendet, und nichts weiter. Auf einer client-seitig gerenderten Seite (die meisten React-, Vue- und Angular-Apps) ist dieses initiale HTML eine fast leere Hülle; der eigentliche Inhalt wird von Skripten gezeichnet, die in einem Browser laufen. cURL führt sie nie aus, man bekommt also das Skelett und keine Daten. Kein Flag behebt das, weil es keine JavaScript-Engine gibt, die man einschalten könnte.
Es wird gesperrt. Selbst auf server-gerenderten Seiten lesen Anti-Bot-Systeme die Anfrage: eine Rechenzentrum-IP, ein fehlender oder Standard-User-Agent, kein browsertypischer Header-Satz und kein TLS-Fingerabdruck, der einem echten Browser entspricht. Reines cURL besteht die meisten dieser Prüfungen nicht und erhält einen 403, ein CAPTCHA oder eine stille Täuschungsseite. Mit Headern und einem Proxy kann man einiges abdecken, aber bei harten Zielen ist es ein verlorenes Wettrüsten. Das breitere Playbook findet sich in wie man Websites scrapt, ohne gesperrt zu werden.
Ein funktionierendes Scraping einer modernen Seite braucht zwei Dinge gleichzeitig: einen Browser, der die Seite tatsächlich rendert, und eine IP, die die Seite als echten Besucher erkennt. cURL bietet beides nicht. Man kann selbst einen Headless-Browser plus einen rotierenden Pool von Residential-Proxys aufbauen, aber diesen Stack gesund zu halten ist der Großteil der Arbeit. Der nächste Abschnitt fügt beides in einen einzigen cURL-Aufruf zusammen.
Fertiges HTML mit der Crawling API erhalten
Der sauberste Weg, cURL weiterhin zu verwenden und dabei Rendering und Sperren zu lösen, ist der Aufruf der Crawlbase Crawling API von der Befehlszeile aus. Man übergibt seinen Token und die Ziel-URL; die API ruft die Seite hinter einer vertrauenswürdigen Residential-IP ab und gibt das HTML zurück. Fügt man &javascript=true hinzu, rendert die API die Seite zuerst in einem echten Browser, sodass client-seitige Inhalte in der Antwort vorhanden sind.
# Static fetch through the Crawling API curl "https://api.crawlbase.com/?token=YOUR_TOKEN&url=https://example.com" # JavaScript-rendered fetch for client-side pages curl "https://api.crawlbase.com/?token=YOUR_JS_TOKEN&javascript=true&url=https://example.com"
Die zu scrapende URL kommt in den Parameter url und sollte URL-kodiert sein, wenn sie selbst einen Query-String enthält. Den normalen Token für statische Seiten und den JavaScript-Token mit javascript=true für gerenderte Seiten verwenden. Da die Antwort nur HTML auf stdout ist, gelten alle Piping- und Parsing-Tricks von vorhin weiterhin: in eine Datei umleiten, in htmlq pipen oder einem Python-Parser übergeben. Man behält den cURL-Workflow und lagert die Rendering- und IP-Probleme aus.
Reines cURL wird gesperrt und kann kein JavaScript ausführen. Die Crawling API nimmt Ihren Token und eine URL, ruft die Seite hinter einer rotierenden Residential-IP ab, rendert sie optional in einem echten Browser und gibt fertiges HTML nach stdout zurück, sodass es direkt in Ihre bestehenden cURL-Pipes und -Schleifen passt. Starten Sie auf dem kostenlosen Tarif und behalten Sie denselben Befehlszeilen-Workflow.
cURL durch den Smart AI Proxy routen
Wenn man lieber die eigene Anfrage-Logik beibehält und nur den Netzwerkpfad tauscht, gibt der Smart AI Proxy (auch AI Proxy genannt) rotierende Residential-IPs hinter einem einzigen Proxy-Endpunkt. Er ist ein Drop-in-Ersatz für das bereits bekannte Flag -x, sodass sich der bestehende cURL-Befehl kaum ändert.
curl -x http://YOUR_TOKEN:@smartproxy.crawlbase.com:8012 -k \ https://example.com
Hier ist der Token der Proxy-Benutzername (das Passwort bleibt leer), und jede Anfrage durch den Endpunkt wird automatisch über den Residential-Pool rotiert. Das Flag -k weist cURL an, die TLS-Interception des Proxys zu akzeptieren. Dies ist die richtige Wahl, wenn der Scraper bereits um cURL oder den Proxy-Support einer Bibliothek herum gebaut wurde und man nur die IP-Rotation benötigt, anstatt ein vollständiges serverseitiges Rendering. Für client-gerenderte Seiten bevorzugt man die Crawling API mit javascript=true.
Wichtigste Erkenntnisse
-
cURL ist das schnellste Abruf- und Debug-Werkzeug. Ein einfaches
curl URLgibt die Antwort aus;-o/-Ospeichern sie,-Lfolgt Weiterleitungen und-s/-vsteuern die Ausgabemenge. -
Header und Cookies lassen man wie einen Browser aussehen. Einen echten User-Agent mit
-Aoder-Hsetzen und-b/-cverwenden, um Cookies in einer Session zu senden und zu speichern. -
POST und Proxys decken den Rest der Grundlagen ab.
-dsendet Formular- oder JSON-Daten (mit dem richtigenContent-Type) und-xroutet durch einen Proxy. -
Pipen und schleifen zum Skalieren. cURL-Ausgabe in
grep,htmlqoder Python pipen und eine Bash-Schleife mit Statusprüfungen und Pacing über eine URL-Liste wickeln. -
Reines cURL kann kein JS rendern und wird gesperrt. Die Crawling API aufrufen (mit
javascript=truefür gerenderte Seiten) oder durch den Smart AI Proxy routen, um fertiges HTML zu erhalten und dabei den cURL-Workflow beizubehalten.
Häufig gestellte Fragen
Kann cURL für Web Scraping verwendet werden?
Ja. cURL sendet HTTP-Anfragen und gibt die rohe Antwort zurück, die man in einer Datei speichern oder in einen Parser wie grep, htmlq oder ein Python-Skript pipen kann. Es eignet sich hervorragend für statische, server-gerenderte Seiten und zum Debuggen von Anfragen. Seine Grenzen liegen darin, dass es kein JavaScript ausführen kann und von Anti-Bot-Systemen leicht gesperrt wird. Für client-gerenderte oder geschützte Seiten kombiniert man es daher mit einem Rendering- und Proxy-Dienst.
Warum gibt cURL eine leere oder unvollständige Seite zurück?
Meistens einer von zwei Gründen. Entweder ist die Seite client-seitig gerendert, sodass der eigentliche Inhalt von JavaScript gezeichnet wird, das cURL nie ausführt, und man nur die HTML-Hülle erhält, oder die Seite hat eine Nicht-Browser-Anfrage erkannt und eine Sperr- oder Täuschungsseite ausgeliefert. Den Statuscode mit -w "%{http_code}" prüfen: ein 200 ohne Daten deutet auf JavaScript-Rendering hin, ein 403 oder 429 auf eine Sperre.
Wie setzt man einen User-Agent in cURL?
Das Flag -A mit einem browsertypischen String verwenden, z.B. curl -A "Mozilla/5.0 (...)" https://example.com, oder es als Header mit -H "User-Agent: ..." setzen. Die Standard-Kennung curl/x.y.z ist ein sofortiges Zeichen, dass die Anfrage kein Browser ist, daher ist ein realistischer User-Agent der erste Header, den man korrigieren sollte, wenn eine Seite sperrt.
Wie sendet man POST-Daten mit cURL?
Mit -d, was die Daten sendet und die Methode automatisch auf POST umstellt. Standardmäßig sendet es form-kodierte Daten (-d "a=1&b=2"). Für JSON fügt man -H "Content-Type: application/json" hinzu und übergibt den Body als einfach-quoted JSON-String, damit die Shell die Anführungszeichen nicht verändert.
Wie verwendet man einen Proxy mit cURL?
Das Flag -x verwenden: curl -x http://host:port https://example.com, und user:pass@ vor dem Host für einen authentifizierten Proxy hinzufügen. Ein einzelner statischer Proxy ändert nur einmal die IP; um in großem Volumen zu scrapen, braucht man Rotation über viele IPs, was ein Dienst wie der Smart AI Proxy hinter einem einzigen Endpunkt bereitstellt.
Wie scrapt man JavaScript-lastige Seiten mit cURL?
Das ist mit cURL allein nicht möglich, da cURL keine JavaScript-Engine hat und nie die Skripte ausführt, die den Inhalt rendern. Die praktische Lösung ist der Aufruf eines Rendering-Dienstes über cURL: die URL mit javascript=true an die Crawling API senden, die die Seite in einem echten Browser rendert und dann das fertige HTML nach stdout zurückgibt, wo die üblichen cURL-Piping- und Parsing-Methoden weiterhin funktionieren.
Crawlen Sie jede Website im großen Maßstab, ohne gegen die Infrastruktur zu kämpfen.
Crawlbase übernimmt Proxys, Fingerprints und CAPTCHAs, damit Ihr Team Datenpipelines ausliefert, statt Crawl-Infrastruktur zu pflegen. 1.000 Anfragen kostenlos, keine Karte erforderlich.
