Instagram ist eine der datenreichsten öffentlichen Flächen im Web und gleichzeitig eine der schwierigsten, programmatisch auszulesen. Profile und Beiträge werden clientseitig mit JavaScript gerendert, die Plattform setzt automatisierten Traffic aggressiv heraus, und eine einfache HTTP-Anfrage an eine Profil-URL gibt in der Regel eine nahezu leere Hülle zurück. Dieser Leitfaden zeigt Ihnen, wie Sie Instagram-Daten mit Python scrapen auf eine Art, die tatsächlich funktioniert, und dabei streng bei dem bleibt, was öffentlich ist.
Um es von Anfang an klar zu sagen: Alles hier beschränkt sich auf öffentliche Daten von öffentlichen Konten. Das bedeutet öffentliche Profilfelder, öffentliche Beitragsbeschriftungen, öffentliche Like- und Kommentarzählerstände sowie öffentliche Beitrags-URLs. Es umfasst keine privaten Konten, login-gesperrte Inhalte, Direktnachrichten, Follower-Listen oder personenbezogene Daten einzelner Personen. Instagram und sein Mutterkonzern Meta schränken automatisierten Zugriff in ihren Bedingungen ein, also lesen Sie den Abschnitt zur Rechtslage gegen Ende, bevor Sie das auf irgendetwas Reales ansetzen. Für jede produktive oder kommerzielle Nutzung ist die offizielle Instagram Graph API das richtige Werkzeug, kein Scraper.
Was Sie erstellen werden
Ein kleines Python-Skript, das eine öffentliche Instagram-Profil-URL übernimmt, die vollständig gerenderte Seite über die Crawling API mit einem JavaScript-Token abruft und einige öffentliche Felder herausparst:
- Öffentlicher Benutzername das auf dem Profil angezeigte Konto-Handle.
- Öffentliche Beitragsbeschriftungen der sichtbare Text bei öffentlichen Beiträgen.
- Öffentliche Like- und Kommentarzählerstände die aggregierten Zahlen, die ein Beitrag anzeigt, nicht die dahinterstehenden Personen.
- Öffentliche Beitrags-URLs der Permalink zu jedem öffentlichen Beitrag.
Beachten Sie, was bewusst fehlt: keine Follower-Listen, keine Kommentator-Identitäten, keine privaten Kontoinhalte, keine Kontaktdaten. Das sind personenbezogene Daten von Einzelpersonen, und deren Erhebung ist hier bewusst ausgeschlossen.
Warum eine einfache Anfrage bei Instagram scheitert
Fordern Sie eine öffentliche Instagram-Profil-URL mit einem einfachen HTTP-Client an, erhalten Sie eine Antwort, die technisch erfolgreich und praktisch wertlos ist. Der Body ist eine JavaScript-Hülle: der eigentliche Inhalt erscheint erst, nachdem die Skripte der Seite im Browser ausgeführt wurden und Daten von internen Endpunkten abgerufen haben. Darüber hinaus markiert Instagram automatisierten Traffic schnell. Rechenzentrum-IP-Bereiche, fehlendes Browser-Verhalten und repetitive Anfragemuster werden herausgefordert oder rate-limitiert, noch lange bevor der interessante Inhalt geladen wird.
Ein funktionierender Instagram-Scraper braucht also zwei Dinge in derselben Anfrage: einen echten Browser, der die Seite rendert, und eine IP-Adresse, die die Plattform als normalen Besucher erkennt. Sie können das selbst mit einem Headless-Browser und einem Pool aus rotierenden Residential-Proxys aufbauen, aber diesen Stack gesund zu halten ist der größte Teil der Arbeit. Die Crawling API fasst beides in einem Aufruf zusammen. Sie senden ihr eine URL mit einem JavaScript-Token, sie rendert die Seite hinter einer vertrauenswürdigen Residential-IP und gibt fertiges HTML zurück, das Sie parsen können. Den tiefergehenden Hintergrund finden Sie in unserem Leitfaden zu wie man JavaScript-Websites crawlt.
Crawlbase bietet zwei Token-Typen. Das normale Token ruft statisches HTML ab; das JavaScript-Token (JS-Token) rendert die Seite zuerst in einem echten Browser. Instagram ist clientseitig gerendert, daher benötigen Sie hier das JS-Token. Das normale Token gibt dieselbe Hülle zurück wie eine einfache Anfrage, ohne etwas Nützliches zum Parsen.
Voraussetzungen
Einige Vorbereitungen zuerst. Keine dauert lange.
Python-Grundkenntnisse. Sie sollten in der Lage sein, ein Skript auszuführen und Pakete mit pip zu installieren. Falls Sie neu im HTML-Parsen sind, erklärt unser Primer zu BeautifulSoup in Python die Extraktionsseite.
Python 3.8 oder höher. Bestätigen Sie mit python --version. Falls nicht vorhanden, installieren Sie es von python.org.
Ein Crawlbase-Konto und ein JS-Token. Registrieren Sie sich, öffnen Sie Ihr Dashboard und kopieren Sie Ihr JavaScript-Token (JS-Token) von der Kontodokumentationsseite. Behandeln Sie es wie ein Passwort: Es authentifiziert Ihre Anfragen, halten Sie es daher aus der Versionskontrolle heraus.
Projekt einrichten
Erstellen Sie eine isolierte virtuelle Umgebung und installieren Sie dann die zwei Bibliotheken, die der Scraper benötigt.
python --version python -m venv instagram_env source instagram_env/bin/activate pip install crawlbase beautifulsoup4
Unter Windows aktivieren Sie mit instagram_env\Scripts\activate statt der source-Zeile. Zwei Abhängigkeiten erledigen die Arbeit: crawlbase ist der offizielle Client für die Crawling API, und beautifulsoup4 parst das zurückgegebene HTML, damit Sie einzelne Felder per Selektor herausziehen können.
Schritt 1: Das gerenderte Profil abrufen
Beginnen Sie damit, die fertige Seite zu laden. Importieren Sie CrawlingAPI, initialisieren Sie sie mit Ihrem JS-Token und fragen Sie eine öffentliche Profil-URL ab. Prüfen Sie den Status-Code vor dem Parsen, damit Fehler laut statt still bleiben.
from crawlbase import CrawlingAPI api = CrawlingAPI({"token": "YOUR_CRAWLBASE_JS_TOKEN"}) def crawl(page_url): options = {"ajax_wait": "true", "page_wait": 5000} response = api.get(page_url, options) if response["status_code"] == 200: return response["body"].decode("utf-8") print(f"Request failed: {response['status_code']}") return None if __name__ == "__main__": page_url = "https://www.instagram.com/nasa/" html = crawl(page_url) print(html[:500] if html else "No HTML returned")
Die zwei Wait-Optionen sind bei einem clientseitig gerenderten Ziel wichtig. ajax_wait weist die API an, auf das Laden asynchroner Inhalte zu warten, und page_wait hält nach dem Laden für eine feste Anzahl von Millisekunden an, damit spät gerenderte Elemente erscheinen, bevor die Seite erfasst wird. Fünf Sekunden sind ein vernünftiger Ausgangswert; erhöhen Sie ihn, wenn Felder leer zurückkommen. Das Beispiel verwendet ein öffentliches Organisationskonto (NASA) genau deshalb, weil es öffentlich und unpersönlich ist. Führen Sie das Skript aus und Sie sollten echtes Profil-Markup sehen, was bestätigt, dass das Rendering funktioniert, bevor Sie einen einzigen Selektor schreiben.
Instagram benötigt eine gerenderte Seite hinter einer vertrauenswürdigen IP, in einem einzigen Aufruf. Die Crawling API nimmt ein JS-Token, führt die Seite in einem echten Browser aus, rotiert serverseitig durch Residential-IPs und liefert fertiges HTML, sodass Sie keinen eigenen Headless-Fleet und keinen Proxy-Pool betreiben müssen. Testen Sie es zunächst mit einem öffentlichen Profil im kostenlosen Kontingent.
Schritt 2: Die öffentlichen Felder mit BeautifulSoup parsen
Mit gerendemtem HTML in der Hand laden Sie es in BeautifulSoup und ziehen die öffentlichen Felder heraus. Instagram gibt viele nützliche Metadaten in den <meta>-Tags der Seite und in einem eingebetteten JSON-LD-Block aus, was stabiler ist als das Verfolgen tief verschachtelter, häufig umbenannter CSS-Klassen. Benutzername und Profilbeschreibung befinden sich in Standard-Meta-Tags; die Beitrags-Permalinks befinden sich in Anker-hrefs, die dem /p/<shortcode>/-Muster folgen.
import re from bs4 import BeautifulSoup def meta(soup, prop): el = soup.find("meta", attrs={"property": prop}) return el["content"] if el and el.has_attr("content") else None def scrape_profile(html): soup = BeautifulSoup(html, "html.parser") username = meta(soup, "og:title") summary = meta(soup, "og:description") post_urls = [] for a in soup.select("a[href^='/p/']"): href = a["href"] url = f"https://www.instagram.com{href}" if url not in post_urls: post_urls.append(url) return { "username": username, "summary": summary, "post_urls": post_urls, }
Das og:description-Tag bei einem öffentlichen Profil enthält typischerweise die aggregierten öffentlichen Zählerstände (Follower, Gefolgte, Beiträge) als einzelnen Zusammenfassungsstring. Behandeln Sie diese nur als öffentliche Aggregate, nie als Einstieg zur Aufzählung der dahinterstehenden Personen. Die Beitrags-URLs werden aus Ankern gesammelt und dedupliziert, da derselbe Permalink im gerenderten DOM mehr als einmal erscheinen kann.
Instagram ändert sein Markup und seine Klassennamen ohne Vorankündigung, weshalb dieser Code auf Meta-Tags und die stabile /p/<shortcode>/-URL-Form setzt statt auf fragile verschachtelte Klassen. Wenn ein Feld als None zurückkommt, inspizieren Sie erneut die Live-Seite in den Entwicklertools Ihres Browsers und aktualisieren Sie den Selektor. Regelmäßige Wartung ist normal für jeden produktiven Scraper, kein Zeichen dafür, dass etwas kaputt ist.
Schritt 3: Öffentliche Felder von einem einzelnen Beitrag extrahieren
Eine öffentliche Beitragsseite enthält dieselbe Art von Meta- und JSON-LD-Daten. Daraus können Sie die öffentliche Beschriftung sowie die öffentlichen Like- und Kommentarzählerstände ziehen. Instagram bettet auf Beitragsseiten ein application/ld+json-Skript ein, das oft einen interactionStatistic-Block mit diesen aggregierten Zahlen sowie den Beschriftungstext enthält. Das Parsen des JSON-LD ist dauerhafter als das Scrapen von gerenderten Widgets.
import json from bs4 import BeautifulSoup def scrape_post(html): soup = BeautifulSoup(html, "html.parser") block = soup.find("script", attrs={"type": "application/ld+json"}) if not block: return {} data = json.loads(block.string) likes = comments = None for stat in data.get("interactionStatistic", []): kind = stat.get("interactionType", "") count = stat.get("userInteractionCount") if "LikeAction" in kind: likes = count elif "CommentAction" in kind: comments = count return { "caption": data.get("caption") or data.get("articleBody"), "like_count": likes, "comment_count": comments, }
Dies extrahiert nur aggregierte, nicht-personenbezogene Felder: den Beschriftungstext, die öffentliche Like-Anzahl und die öffentliche Kommentar-Anzahl. Einzelne Kommentare, Kommentator-Handles oder wer den Beitrag geliked hat, werden nicht gelesen. Diese Zurückhaltung ist beabsichtigt, und sie ist auch das, was die Arbeit verteidigbar hält. Like- und Kommentar-Zählerstände sind Zahlen; die dahinterstehenden Personen gehören Ihnen nicht.
Schritt 4: Alles zusammensetzen
Verbinden Sie nun Abruf und Parsen zu einem einzigen lauffähigen Skript, das ein öffentliches Profil liest und dann seine ersten öffentlichen Beiträge besucht.
import json import time from crawlbase import CrawlingAPI from bs4 import BeautifulSoup api = CrawlingAPI({"token": "YOUR_CRAWLBASE_JS_TOKEN"}) def crawl(page_url): options = {"ajax_wait": "true", "page_wait": 5000} response = api.get(page_url, options) if response["status_code"] == 200: return response["body"].decode("utf-8") print(f"Request failed: {response['status_code']}") return None def main(): profile_url = "https://www.instagram.com/nasa/" html = crawl(profile_url) if not html: return profile = scrape_profile(html) records = [] for post_url in profile["post_urls"][:5]: post_html = crawl(post_url) if post_html: record = scrape_post(post_html) record["url"] = post_url records.append(record) time.sleep(3) output = {"username": profile["username"], "posts": records} print(json.dumps(output, indent=2, ensure_ascii=False)) if __name__ == "__main__": main()
Das time.sleep(3) zwischen den Anfragen ist keine Dekoration. Die Dosierung ist der entscheidende Faktor dafür, ob ein Lauf gesund bleibt, und wir werden darauf zurückkommen. Der Slice [:5] hält die Demo klein; erhöhen Sie ihn nur, wenn Ihre Dosierung und Ihr Volumen verantwortungsvoll sind.
Wie die Ausgabe aussieht
Führen Sie das vollständige Skript aus und Sie erhalten einen sauberen Datensatz öffentlicher Felder, bereit zum Schreiben in JSON, CSV oder eine Datenbank.
{ "username": "NASA (@nasa)", "posts": [ { "caption": "A new view of a distant galaxy cluster.", "like_count": 412338, "comment_count": 1894, "url": "https://www.instagram.com/p/Cxample123/" } ] }
Ungeblockt bleiben
Selbst wenn das Rendering von der Crawling API übernommen wird, beobachtet Instagram den Traffic auf Scraper-typische Muster. Einige Gewohnheiten halten einen Lauf gesund, und sie gelten für jedes schwer verteidigte Ziel.
-
Anfragen dosieren. Seiten in einer engen Schleife zu hammern ist der schnellste Weg, gedrosselt zu werden. Fügen Sie echte Verzögerungen ein, wie das
time.sleepoben, und widerstehen Sie dem Drang, aggressiv zu parallelisieren. - Auf Rotation setzen. Ein Pool von Residential-IPs verteilt Anfragen auf viele echte Benutzeradressen, sodass keine einzelne ein Rate-Limit auslöst. Die Crawling API übernimmt das für Sie; wenn Sie Ihren eigenen Stack aufbauen, ist das der Teil, den Sie richtig machen müssen. Unser Leitfaden zu wie man rotierende Proxys einsetzt geht tiefer.
- Status-Codes beachten. Ein Lauf, der beginnt, Herausforderungen oder Fehler zurückzugeben, signalisiert Ihnen, dass die aktuelle Rate oder IP-Tier nicht mehr ausreicht. Schalten Sie zurück, statt härter zu drücken.
- Volumen niedrig halten und Ziele variieren. Öffentliche Datenforschung erfordert nicht das Crawlen des gesamten Verlaufs eines Kontos. Nehmen Sie eine Stichprobe von dem, was Sie brauchen, und hören Sie auf.
Das umfassendere Playbook finden Sie unter wie man CAPTCHAs beim Web-Scraping umgeht und in unserem tiefen Einblick in wie man JavaScript-Seiten mit Python scrapt. Wenn Sie Ihren eigenen Traffic lieber über einen rotierenden Pool leiten möchten statt die verwaltete API zu nutzen, gibt Ihnen der Smart AI Proxy dieselbe Residential-Rotation als Drop-in-Proxy-Endpunkt.
Ist es legal, Instagram zu scrapen?
Das ist der Abschnitt, den Sie lesen sollten, bevor Sie Produktionscode schreiben. Instagram gehört Meta, und Meta's Nutzungsbedingungen schränken automatisierten Zugriff und Datenerhebung stark ein. Automatisiertes Scraping kann gegen diese Bedingungen verstoßen, unabhängig davon, wie sorgfältig Ihr Tooling ist, und keiner der obigen Codes ändert das. Er lässt nur den technischen Teil funktionieren. Lesen Sie Meta's und Instagram's Nutzungsbedingungen sowie Instagram's robots.txt, und behandeln Sie beides als Grenze für das, was Sie erheben.
Die ehrlichen, restriktiven Regeln, an die Sie sich halten sollten. Sammeln Sie nur öffentliche Daten von öffentlichen Konten: öffentliche Profilfelder, öffentliche Beitragsbeschriftungen, öffentliche Like- und Kommentarzählerstände sowie öffentliche Beitrags-URLs, die jeder ohne Login sehen kann. Scrapen Sie niemals private Konten, login-gesperrte Inhalte, Direktnachrichten, Follower- oder Gefolgte-Listen, individuelle Kommentator- oder Liker-Identitäten oder personenbezogene Daten einzelner Personen. Umgehen Sie niemals Authentifizierung, lösen Sie eine Login-Herausforderung programmatisch oder nutzen Sie Anmeldedaten von jemandem, um Inhalte zu erreichen. Das sind klare Grenzen, und dieser Leitfaden bleibt aus gutem Grund auf der öffentlichen Seite all dieser Grenzen.
Für jede echte oder kommerzielle Nutzung ist das richtige Werkzeug die offizielle Instagram Graph API. Sie ist für sanktionierten Zugriff auf Konten gebaut, die Sie besitzen oder verwalten, bietet garantierte Struktur und hält Sie innerhalb von Meta's Bedingungen. Dieser Artikel ist eine technische Anleitung, die eng auf öffentliche Daten von öffentlichen Konten beschränkt ist. Er ist keine Befürwortung massenhafter Erhebung personenbezogener Daten und behandelt nichts hinter einem Login. Wenn Ihr Projekt mehr als eine kleine Stichprobe öffentlicher Felder benötigt, ist die Graph API oder eine formelle Datenvereinbarung der richtige Weg, kein raffinierterer Scraper.
Wichtigste Erkenntnisse
- Instagram ist clientseitig gerendert und bot-geschützt. Eine einfache Anfrage gibt eine leere Hülle zurück, also müssen Sie die Seite rendern, bevor Sie sie parsen.
-
Rendering und eine vertrauenswürdige IP gehören in einen Aufruf. Die Crawling API mit einem JS-Token erledigt beides;
ajax_waitundpage_waitsteuern, wie lange sie auf Inhalte wartet. -
Stabile Signale parsen. Meta-Tags, die
/p/<shortcode>/-URL-Form und JSON-LD sind dauerhafter als fragile verschachtelte Klassen. - Nur öffentliche Aggregate. Benutzernamen, Beschriftungen, Like- und Kommentarzählerstände und Beitrags-URLs ziehen; niemals Follower-Listen, Kommentator-Identitäten oder private Inhalte.
- Dosieren, rotieren und die Graph API bevorzugen. Volumen niedrig halten, auf Residential-Rotation setzen und für alles Echte oder Kommerzielle die offizielle Instagram Graph API nutzen.
Häufig gestellte Fragen
Warum gibt eine einfache Anfrage keine Daten von Instagram zurück?
Weil Instagram seinen Profil- und Beitragsinhalt clientseitig mit JavaScript rendert. Das anfängliche HTML ist eine Hülle, die sich erst füllt, nachdem die Skripte der Seite im Browser ausgeführt wurden, sodass eine rohe HTTP-Anfrage einen nahezu leeren Body zurückgibt. Um echte öffentliche Daten zu erhalten, muss die Seite zuerst gerendert werden, was das JS-Token der Crawling API für Sie übernimmt.
Brauche ich das normale Token oder das JS-Token für Instagram?
Das JS-Token. Das normale Token ruft statisches HTML ab, das bei Instagram dieselbe leere Hülle wie eine einfache Anfrage ist. Das JS-Token rendert die Seite in einem echten Browser, bevor das HTML zurückgegeben wird, sodass die öffentlichen Felder vorhanden sind, wenn BeautifulSoup sie parst.
Welche Instagram-Daten sind sicher zu scrapen?
Nur öffentliche Daten von öffentlichen Konten: den öffentlichen Benutzernamen, öffentliche Beitragsbeschriftungen, öffentliche Like- und Kommentarzählerstände als aggregierte Zahlen sowie öffentliche Beitrags-URLs. Private Konten, login-gesperrte Inhalte, Direktnachrichten, Follower- und Gefolgte-Listen sowie die Identitäten einzelner Kommentatoren oder Liker sind tabu. Das sind personenbezogene Daten, und deren Erhebung verstößt gegen Meta's Bedingungen und in vielen Ländern gegen Datenschutzrecht.
Sollte ich die offizielle Instagram Graph API oder die Seite scrapen?
Für jede echte, laufende oder kommerzielle Nutzung die offizielle Instagram Graph API verwenden. Sie ist der sanktionierte Weg, bietet garantierte Struktur und hält Sie innerhalb von Meta's Bedingungen. Das Scrapen einer kleinen Stichprobe öffentlicher Felder mit dem hier gezeigten Ansatz passt für leichtgewichtige öffentliche Datenforschung, bei der kein API-Zugang besteht, solange Sie die Bedingungen, robots.txt und Rate-Limits respektieren.
Wie vermeide ich Blocking beim Scrapen von Instagram?
Halten Sie Ihre pro-IP-Anfragerate niedrig, fügen Sie echte Verzögerungen zwischen Anfragen ein, variieren Sie Ihre Ziele statt den vollständigen Verlauf eines Kontos zu crawlen, und leiten Sie über rotierende Residential-IPs weiter, sodass keine einzelne Adresse ein Rate-Limit auslöst. Die Crawling API verwaltet Rotation und einen vertrauenswürdigen IP-Pool für Sie. Beobachten Sie die Status-Codes und schalten Sie zurück, sobald Sie Herausforderungen sehen.
Kann ich private Konten oder Follower-Listen scrapen?
Nein, und dieser Leitfaden zeigt bewusst nicht wie. Private Kontoinhalte befinden sich hinter Authentifizierung, und Follower-Listen und individuelle Benutzeridentitäten sind personenbezogene Daten. Login-gesperrte Inhalte zu scrapen, Follower aufzuzählen oder Authentifizierung zu umgehen, um irgendetwas davon zu erreichen, liegt außerhalb des Rahmens hier und verstößt gegen Meta's Bedingungen. Für sanktionierten Zugriff auf Konten, die Sie besitzen oder verwalten, ist die offizielle Instagram Graph API der richtige Weg.
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.
