Vor ein paar Monaten zeigte mir einer unserer Entwickler ein Python-Skript, das er an einem Wochenende geschrieben hatte. Es sollte für ein Marktforschungsprojekt Inspirationsbilder von Pinterest ziehen. Er startete es – und das Ergebnis war … 16 Pins. Aus einem Board mit über 2.000. Er starrte auf den Bildschirm, dann auf mich und sagte: „Ich glaube, Pinterest macht sich über mich lustig.“
Damit ist er nicht allein. Genau das ist aus meiner Sicht die häufigste Frustration bei Entwicklern, die versuchen, Pinterest mit Python zu scrapen. Man startet requests und BeautifulSoup, ruft eine Pinterest-URL auf und bekommt entweder nur eine Handvoll Einträge oder eine leere HTML-Hülle zurück. Der Grund? Pinterest ist eine vollständig per JavaScript gerenderte Single-Page-App – deine statische HTTP-Anfrage sieht den echten Inhalt nie. In diesem Guide zeige ich dir, warum das so ist, welche Ansätze wirklich funktionieren (Playwright, internes API-Intercepting und No-Code-Tools wie ), und ich gebe dir Schritt-für-Schritt-Code zum Scrapen von Pins, Boards, Nutzerprofilen, Infinite Scroll und Bildern in voller Auflösung. Egal, ob du einen produktionsreifen Scraper bauen oder einfach schnell Daten einsammeln willst – hier wirst du fündig.
Was bedeutet Pinterest Scraping?
Pinterest Scraping bezeichnet das programmatische Extrahieren von Daten aus Pinterest – also etwa Pin-Bildern, Titeln, Beschreibungen, Board-Namen, Follower-Zahlen und URLs. Statt Pins manuell einzeln zu öffnen und zu speichern, nutzt du Code (oder ein Tool), um strukturierte Daten aus Suchergebnissen, Boards oder Profilen im großen Stil zu erfassen.
Mit auf der Plattform und Ende 2025 ist Pinterest eine der reichhaltigsten visuellen Datenquellen im Web. Für Unternehmen sind diese Daten pures Gold – egal, ob du Produkttrends beobachtest, Inhalte von Wettbewerbern vergleichst oder Influencer-Listen für die Ansprache aufbaust.
Warum Pinterest mit Python scrapen?
Pinterest ist längst nicht mehr nur eine Pinnwand für Hochzeitsplaner. Es ist eine ernstzunehmende Plattform für Business Intelligence – haben schon einmal etwas aufgrund von Brand-Pins gekauft, und . Das heißt: Nutzer kommen mit einer klaren Absicht, aber ohne Markenbindung. Das ist eine enorme Chance für Reichweite und Entdeckung – und erklärt, warum so viele Teams strukturierte Pinterest-Daten brauchen.
So sieht das nach Teams aufgeteilt aus:
| Team | Benötigte Daten | Geschäftlicher Nutzen |
|---|---|---|
| E-Commerce Operations | Produktbilder, Preise, Trend-Ästhetiken | Wettbewerbsfähige Preisgestaltung, trendbasierte Lagerplanung |
| Marketing | Board-Performance, Pin-Engagement, Inhalte von Wettbewerbern | Content-Strategie, Kampagnen-Benchmarking |
| Sales / Lead Gen | Creator-Profile, Follower-Zahlen, Kontaktdaten | Influencer-Outreach, Partner-Targeting |
| Immobilien | Home-Staging-Pins, Einrichtungstrends, Raumaufteilungen | Listing-Fotografie, Staging-Empfehlungen |
| Content Creator | Trendthemen, beliebte Formate, saisonale Motive | Redaktionsplanung, Recherche zu visuellem Stil |
Und hier der Haken: Die offizielle API von Pinterest ist stark eingeschränkt. Du brauchst ein Business-Konto, eine Freigabe (inklusive Videodemo deiner App) und bekommst nur Zugriff auf Daten deines eigenen Kontos. Wenn du öffentliche Boards, Suchergebnisse oder Wettbewerber-Profile abrufen willst, ist Scraping die praktikable Alternative. Deshalb setzen so viele Teams auf Python – oder auf No-Code-Tools wie Thunderbit, wenn sie Ergebnisse ohne Setup wollen.
Warum BeautifulSoup auf Pinterest allein scheitert – und was wirklich funktioniert
Wenn du schon versucht hast, Pinterest mit requests + BeautifulSoup zu scrapen und nur 16 Einträge oder eine leere Seite bekommen hast, bildest du dir das nicht ein. Pinterest basiert auf React und rendert seinen gesamten Inhalt per JavaScript. Wenn du eine Pinterest-URL mit einer normalen HTTP-Anfrage abrufst, liefert der Server nur ein minimales HTML-Gerüst – ein paar <link>- und <script>-Tags und einen leeren <div>, in den React die App einhängt. Alle Pin-Karten, Bilder, Titel und Rasterelemente werden erst nach der JavaScript-Ausführung im Browser eingefügt.
Kein JavaScript = keine Pins.
Was funktioniert also? So schlagen sich die wichtigsten Ansätze im Vergleich:
| Ansatz | Unterstützt JS? | Vollständige Daten? | Komplexität | Am besten geeignet für |
|---|---|---|---|---|
requests + BeautifulSoup | Nein | ~0–16 Einträge | Gering | Nicht für Pinterest geeignet |
| Selenium / Playwright | Ja | Ja, mit Scroll-Logik | Mittel | Volle Kontrolle, Python-Pipelines |
| Internes Pinterest-API-Intercepting | Ja | Ja, paginiertes JSON | Hoch | Maximale Datenmenge, kein Browser nötig |
| Drittanbieter-Scraper-API | Ja | Unterschiedlich | Gering | Skalierung ohne eigene Infrastruktur |
| No-Code-Tool (Thunderbit) | Ja | KI-strukturiert | Sehr gering | Nicht-technische Nutzer, schnelle Ergebnisse |
Für dieses Tutorial empfehle ich Playwright als Python-Ansatz. Es rendert JavaScript, unterstützt Scroll-Simulation, wird aktiv gepflegt (, mit bei Stellenanzeigen) und ist in Benchmarks . Wenn du den No-Code-Weg bevorzugst, zeige ich dir den ebenfalls.
Pinterest Official API vs. Python Scraping vs. No-Code: Welcher Weg passt?
Bevor du mit dem Coden beginnst, lohnt sich die Frage: Musst du das überhaupt selbst bauen? Hier ist ein Entscheidungsrahmen:
| Kriterium | Pinterest API | Python Scraping | Thunderbit (No-Code) |
|---|---|---|---|
| Freigabe erforderlich | Business-Konto + Videodemo | Keine | Keine |
| Zugriff auf öffentliche Pins/Boards | Eingeschränkt (nur eigene Daten) | Vollständig | Vollständig |
| Download von Bildern in voller Auflösung | Unterschiedlich | Ja, per URL-Anpassung | Ja, via Bildextraktion |
| Unterstützt Infinite Scroll | Nicht zutreffend | Ja, mit Code | Automatisch |
| Wartungsaufwand | Gering | Hoch (Selektoren brechen) | Keiner (KI passt sich an) |
| Export nach Sheets/Airtable | Manuell | Per Custom Code | Integriert |
| Setup-Zeit | Stunden bis Tage | 30–60 Min. | 2 Minuten |
Wenn du Marketer, E-Commerce-Operator oder einfach jemand bist, der Pinterest-Daten ohne Python-Skripte direkt in eine Tabelle bringen möchte, ist der Schnellweg. Du öffnest einfach eine Pinterest-Seite, klickst auf „AI Suggest Fields“, drückst „Scrape“ und exportierst direkt nach Google Sheets, Excel, Airtable oder Notion. Mit der Subpage-Scraping-Funktion kannst du sogar einzelne Pin-Links automatisch aufrufen und Daten anreichern. Ich habe Teammitglieder ohne eine Zeile Code dabei gesehen, wie sie in unter drei Minuten 500+ Pins in ein Google Sheet gezogen haben.
Wer volle Kontrolle will, Scraping in eine Python-Pipeline integrieren möchte oder einfach Freude daran hat, Dinge selbst zu bauen, liest jetzt weiter.
Deine Python-Umgebung für Pinterest Scraping einrichten
- Schwierigkeitsgrad: Mittel
- Zeitaufwand: ca. 30–60 Minuten (inklusive Programmierung und Tests)
- Du brauchst: Python 3.9+, Chrome-Browser (zum Testen), Terminal-/Kommandozeilen-Zugriff
Playwright und Abhängigkeiten installieren
Lege zunächst einen Projektordner an und richte eine virtuelle Umgebung ein:
1mkdir pinterest-scraper
2cd pinterest-scraper
3python -m venv venv
4source venv/bin/activate # Unter Windows: venv\Scripts\activate
Installiere Playwright und lade das Chromium-Browser-বinary herunter:
1pip install playwright
2playwright install chromium
Für den Export von Daten verwendest du außerdem die eingebauten Python-Module json, os und csv. Dafür sind keine weiteren Installationen nötig.
Projektordner-Struktur
Ich empfehle, von Anfang an sauber zu organisieren:
1pinterest-scraper/
2├── scraper.py
3├── config.py
4├── output/
5│ ├── pins.json
6│ └── pins.csv
7└── images/
8 ├── board-name-1/
9 └── board-name-2/
In config.py legst du deinen User-Agent fest. Pinterest blockiert Standard-Signaturen von Headless-Browsern, also nimm einen realistischen Wert:
1USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36"
Schritt 1: Die Pinterest-Such-URL bauen
Erstelle die Such-URL, indem du deine Anfrage in die Vorlage einsetzt:
1query = "mid century modern furniture"
2url = f"https://www.pinterest.com/search/pins/?q={query.replace(' ', '%20')}&rs=typed"
Du kannst das für jeden Suchbegriff parametrieren. Der Parameter rs=typed signalisiert Pinterest, dass die Suche getippt wurde und nicht vorgeschlagen war, was die Relevanz der Ergebnisse manchmal beeinflusst.
Schritt 2: Einen Headless-Browser starten und die Seite laden
Hier ist das zentrale Playwright-Setup. Achte auf den benutzerdefinierten User-Agent – ohne ihn blockiert dich Pinterest wahrscheinlich oder zeigt eine Login-Sperre.
1import asyncio
2from playwright.async_api import async_playwright
3from config import USER_AGENT
4async def scrape_search(query, max_pins=100):
5 url = f"https://www.pinterest.com/search/pins/?q={query.replace(' ', '%20')}&rs=typed"
6 async with async_playwright() as p:
7 browser = await p.chromium.launch(headless=True)
8 page = await browser.new_page(
9 user_agent=USER_AGENT,
10 viewport={"width": 1920, "height": 1080}
11 )
12 await page.goto(url)
13 await asyncio.sleep(3) # Warten, bis JavaScript die ersten Pins rendert
Nach diesem Schritt sollte die erste Gruppe von Pins geladen sein – typischerweise 25 bis 50.
Schritt 3: Pin-Daten aus der Seite extrahieren
Pinterest verpackt jeden Pin in einem div mit data-test-id='pinWrapper'. Darin findest du einen Link (<a>) mit der Pin-URL und dem Titel (über aria-label) sowie ein <img> mit der Thumbnail-URL.
1 results = []
2 pins = await page.query_selector_all("div[data-test-id='pinWrapper']")
3 for pin in pins:
4 link = await pin.query_selector("a")
5 if not link:
6 continue
7 title = await link.get_attribute("aria-label") or ""
8 href = await link.get_attribute("href") or ""
9 img = await link.query_selector("img")
10 src = await img.get_attribute("src") if img else ""
11 results.append({
12 "title": title,
13 "url": f"https://www.pinterest.com{href}" if href.startswith("/") else href,
14 "image_url": src
15 })
An diesem Punkt enthält results die Pins, die im initialen Viewport sichtbar sind. Für mehr musst du scrollen – und genau das ist der wichtigste Teil.
Schritt 4: Ergebnisse als JSON oder CSV speichern
Nach der Extraktion schreibst du die Daten in Dateien, damit du sie weiterverwenden kannst:
1import json
2import csv
3def save_json(data, filepath="output/pins.json"):
4 with open(filepath, "w", encoding="utf-8") as f:
5 json.dump(data, f, ensure_ascii=False, indent=2)
6def save_csv(data, filepath="output/pins.csv"):
7 if not data:
8 return
9 with open(filepath, "w", newline="", encoding="utf-8-sig") as f:
10 writer = csv.DictWriter(f, fieldnames=data[0].keys())
11 writer.writeheader()
12 writer.writerows(data)
Wenn du die CSV später in Excel öffnen möchtest, nutze utf-8-sig als Encoding – so vermeidest du beschädigte Sonderzeichen.
Ganze Pinterest-Boards und Nutzerprofile scrapen
Hier fehlt in vielen bestehenden Tutorials ein wichtiger Teil. Ich habe kein einziges Konkurrenz-Tutorial gefunden, das Board- oder Profil-Scraping wirklich tief behandelt – dabei gehört genau das zu den am häufigsten gewünschten Funktionen in Foren. Nutzer möchten alle Pins eines Boards herunterladen, Bilder in Board-Ordnern organisieren und Profil-Daten wie Follower-Zahlen und Board-Listen auslesen.
Alle Pins von einer Board-URL scrapen
Board-URLs folgen dem Muster https://www.pinterest.com/{username}/{board-name}/. Die DOM-Struktur ähnelt den Suchergebnissen – Pins werden in div[data-test-id='pinWrapper'] verpackt – aber du musst scrollen, um alle zu laden.
1async def scrape_board(board_url, max_pins=500):
2 async with async_playwright() as p:
3 browser = await p.chromium.launch(headless=True)
4 page = await browser.new_page(user_agent=USER_AGENT, viewport={"width": 1920, "height": 1080})
5 await page.goto(board_url)
6 await asyncio.sleep(3)
7 seen_ids = set()
8 all_pins = []
9 for scroll_round in range(100): # Sicherheitslimit
10 pins = await page.query_selector_all("div[data-test-id='pinWrapper']")
11 new_count = 0
12 for pin in pins:
13 link = await pin.query_selector("a")
14 if not link:
15 continue
16 href = await link.get_attribute("href") or ""
17 if href in seen_ids:
18 continue
19 seen_ids.add(href)
20 new_count += 1
21 title = await link.get_attribute("aria-label") or ""
22 img = await link.query_selector("img")
23 src = await img.get_attribute("src") if img else ""
24 all_pins.append({
25 "title": title,
26 "url": f"https://www.pinterest.com{href}" if href.startswith("/") else href,
27 "image_url": src
28 })
29 print(f"Scroll {scroll_round + 1}: {len(all_pins)} eindeutige Pins gesammelt")
30 if new_count == 0 or len(all_pins) >= max_pins:
31 break
32 prev_height = await page.evaluate("document.body.scrollHeight")
33 await page.evaluate("window.scrollTo(0, document.body.scrollHeight)")
34 await asyncio.sleep(2.5)
35 curr_height = await page.evaluate("document.body.scrollHeight")
36 if curr_height == prev_height:
37 break # Kein weiterer Inhalt
38 await browser.close()
39 return all_pins
Worauf du achten solltest: Auf Board-Seiten gibt es manchmal einen Bereich „More Ideas“, der gespeicherte Pins von algorithmischen Empfehlungen trennt. Wenn du nur die tatsächlich gespeicherten Pins des Nutzers willst, stoppe das Scrollen, sobald diese Trennlinie erscheint.
Ein Nutzerprofil scrapen: Boards, Follower-Zahl und Pins
Profil-URLs sehen so aus: https://www.pinterest.com/{username}/. Auf einer Profilseite kannst du Folgendes extrahieren:
- Follower-/Following-Zahlen: Suche nach
div[data-test-id='follower-count'] - Board-Liste: Jedes Board ist eine Kachel, die auf
/{username}/{board-name}/verlinkt - Gesamtzahl der Pins: Wird manchmal im Profil-Header angezeigt
1async def scrape_profile(username):
2 url = f"https://www.pinterest.com/{username}/"
3 async with async_playwright() as p:
4 browser = await p.chromium.launch(headless=True)
5 page = await browser.new_page(user_agent=USER_AGENT, viewport={"width": 1920, "height": 1080})
6 await page.goto(url)
7 await asyncio.sleep(3)
8 # Follower-Zahl extrahieren
9 follower_el = await page.query_selector("div[data-test-id='follower-count']")
10 followers = await follower_el.inner_text() if follower_el else "N/A"
11 # Board-Links extrahieren
12 board_links = await page.query_selector_all("a[href*='/" + username + "/']")
13 boards = []
14 for bl in board_links:
15 href = await bl.get_attribute("href") or ""
16 name = await bl.get_attribute("aria-label") or href.split("/")[-2]
17 if href.count("/") >= 3 and href != f"/{username}/":
18 boards.append({"name": name, "url": f"https://www.pinterest.com{href}"})
19 await browser.close()
20 return {"username": username, "followers": followers, "boards": boards}
Wenn du alle Pins über sämtliche Boards eines Profils scrapen willst, iteriere einfach durch die Board-Liste und rufe für jedes Board scrape_board() auf. Die heruntergeladenen Bilder kannst du dann automatisch in separate Board-Ordner sortieren.
Einen produktionsreifen Infinite-Scroll-Handler bauen
Das ist der Abschnitt, der einen Bastel-Scraper von einem echten Tool unterscheidet. Das größte Problem – und ich habe es in mindestens einem Dutzend Foren-Threads gesehen – ist, dass Scraper nur 16–25 Einträge zurückgeben, weil sie nicht weit genug scrollen oder mit einer festen Scroll-Anzahl wie for i in range(5): scroll() einfach hoffen, dass es reicht.
Dieser Ansatz ist unzuverlässig. Pinterest lädt neue Inhalte in Paketen von ungefähr 25 Pins nach, ausgelöst durch Scroll-Events. Wenn du fünfmal scrollst, bekommst du vielleicht 125 Pins – oder nur 75, wenn das Netzwerk langsam ist, oder 150, wenn die Pakete kleiner waren. Du brauchst also ein intelligenteres Muster.
Das Scrollen-bis-keine-neuen-Inhalte-mehr-kommen-Muster
Hier ist eine robuste Scroll-Funktion, die eindeutige Pin-IDs verfolgt, ein konfigurierbares Timeout nutzt, Retry-Logik enthält und den Fortschritt ausgibt:
1import time
2import random
3async def scroll_and_collect(page, max_pins=1000, max_scrolls=200, scroll_pause=2.5):
4 seen_ids = set()
5 all_pins = []
6 no_new_count = 0
7 for i in range(max_scrolls):
8 pins = await page.query_selector_all("div[data-test-id='pinWrapper']")
9 new_this_round = 0
10 for pin in pins:
11 link = await pin.query_selector("a")
12 if not link:
13 continue
14 href = await link.get_attribute("href") or ""
15 if href in seen_ids:
16 continue
17 seen_ids.add(href)
18 new_this_round += 1
19 title = await link.get_attribute("aria-label") or ""
20 img = await link.query_selector("img")
21 src = await img.get_attribute("src") if img else ""
22 all_pins.append({
23 "title": title,
24 "url": f"https://www.pinterest.com{href}" if href.startswith("/") else href,
25 "image_url": src
26 })
27 print(f" Scroll {i+1}: {new_this_round} neue Pins | {len(all_pins)} Pins insgesamt")
28 if len(all_pins) >= max_pins:
29 print(f" Max-Pins-Grenze ({max_pins}) erreicht. Abbruch.")
30 break
31 if new_this_round == 0:
32 no_new_count += 1
33 if no_new_count >= 3:
34 print(" Nach 3 aufeinanderfolgenden Scrolls keine neuen Pins. Inhalt offenbar erschöpft.")
35 break
36 else:
37 no_new_count = 0
38 prev_height = await page.evaluate("document.body.scrollHeight")
39 await page.evaluate("window.scrollTo(0, document.body.scrollHeight)")
40 await asyncio.sleep(scroll_pause + random.uniform(0.5, 1.5))
41 curr_height = await page.evaluate("document.body.scrollHeight")
42 if curr_height == prev_height and new_this_round == 0:
43 print(" Seitenhöhe unverändert und keine neuen Pins. Feed vermutlich am Ende.")
44 break
45 return all_pins
Warum dieses Design funktioniert:
- Deduplizierung über href: Die URL jedes Pins ist eindeutig, daher nutzen wir sie als ID. So wird derselbe Pin beim erneuten Rendern des DOM nicht doppelt gezählt.
- Drei-Versuche-Regel: Wenn drei Scrolls hintereinander null neue Pins liefern, stoppen wir. Das fängt den Fall ab, dass die Seite zwar noch lädt, aber kein neuer Inhalt vorhanden ist.
- Zufälliges Jitter bei Pausen: Eine zufällige Pause von 0,5–1,5 Sekunden zwischen den Scrolls lässt das Verhalten menschlicher wirken und senkt das Risiko, Anti-Bot-Mechanismen auszulösen.
- Max-Scrolls als Sicherheitsgrenze: Verhindert Endlosschleifen, falls etwas schiefgeht.
Randfälle behandeln
- „More Ideas“-Unterbrechung: Auf Board-Seiten fügt Pinterest manchmal einen Bereich „More Ideas“ ein. Wenn du nur die eigentlichen Pins des Boards willst, kannst du auf dieses Element prüfen und das Scrollen beenden, sobald es erscheint.
- Rate-Limiting bei langen Sessions: Wenn du dich durch ein Board mit Tausenden Pins scrollst, kann Pinterest Anfragen drosseln. Wenn Scrolls gelegentlich keine neuen Pins liefern (aber nicht drei in Folge), erhöhe die Scroll-Pause auf 5+ Sekunden.
Pinterest-Bilder in voller Auflösung abrufen, nicht nur Thumbnails
Das bringt viele Leute zur Verzweiflung. Du scrapst eine Menge Pins, lädst die Bilder herunter – und alle sind winzige 236px-Thumbnails. In Foren wird das oft als „trash quality, viel zu klein“ beschrieben. Die Lösung liegt im Verständnis der Pinterest-Bild-URL-Struktur.
Die Pinterest-Bildpfade verstehen
Alle Pinterest-Bilder werden von https://i.pinimg.com/{size}/{hash}.jpg ausgeliefert. Der {size}-Teil bestimmt die Auflösung:
| Größenpfad | Abmessungen | Verwendung |
|---|---|---|
/236x/ | 236 px breit | Standard-Rasteransicht (Standardausgabe) |
/474x/ | 474 px breit | Mittlere Auflösung |
/736x/ | 736 px breit | Pin-Detail-/vergrößerte Ansicht |
/originals/ | Ursprüngliche Upload-Größe | Volle Auflösung |
Hilfsfunktion: Jede Pinterest-Bild-URL auf volle Auflösung anheben
Hier ist eine Funktion, die jede Pinterest-Bild-URL auf die bestmögliche Qualität umschreibt, inklusive Fallback-Logik:
1import requests as req
2def upgrade_image_url(url, preferred_size="originals"):
3 """Schreibt eine Pinterest-Bild-URL auf die höchstmögliche Auflösung um."""
4 sizes = ["originals", "736x", "474x", "236x"]
5 if preferred_size not in sizes:
6 preferred_size = "originals"
7 for size in sizes[sizes.index(preferred_size):]:
8 upgraded = url
9 for s in sizes:
10 upgraded = upgraded.replace(f"/{s}/", f"/{size}/")
11 try:
12 resp = req.head(upgraded, timeout=5, allow_redirects=True)
13 if resp.status_code == 200:
14 return upgraded
15 except Exception:
16 continue
17 return url # Gibt die Original-URL zurück, wenn alles fehlschlägt
Wichtiger Hinweis (Stand 2025): Der Pfad /originals/ liefert immer häufiger HTTP-403-Fehler. Ein bestätigt dieses Verhalten Mitte 2025. Die verlässliche Obergrenze ist /736x/. Meine Funktion versucht zuerst /originals/ und fällt dann automatisch auf /736x/ zurück.
Bilder in organisierte Ordner herunterladen
1import os
2import time
3def download_images(pins, folder="images/default", delay=1.5):
4 os.makedirs(folder, exist_ok=True)
5 for i, pin in enumerate(pins):
6 img_url = upgrade_image_url(pin.get("image_url", ""), preferred_size="736x")
7 if not img_url:
8 continue
9 filename = f"pin_{i+1}.jpg"
10 filepath = os.path.join(folder, filename)
11 try:
12 resp = req.get(img_url, timeout=15)
13 if resp.status_code == 200:
14 with open(filepath, "wb") as f:
15 f.write(resp.content)
16 print(f" {filename} heruntergeladen ({len(resp.content) // 1024} KB)")
17 else:
18 print(f" Fehler bei {filename}: HTTP {resp.status_code}")
19 except Exception as e:
20 print(f" Fehler beim Download von {filename}: {e}")
21 time.sleep(delay + random.uniform(0.3, 0.8))
Füge zwischen den Downloads eine Verzögerung zur Begrenzung der Anfragerate ein. Ich verwende 1,5–2,3 Sekunden mit etwas Zufall. Ohne das wird Pinterest deine IP nach einigen hundert Anfragen blockieren.
Deine gescrapten Pinterest-Daten exportieren
Export nach CSV oder JSON
Die Grundlagen haben wir oben schon behandelt. Für größere Datensätze (10.000+ Pins) solltest du JSON Lines in Betracht ziehen – ein JSON-Objekt pro Zeile –, da sich das leichter streamen und verarbeiten lässt:
1def save_jsonl(data, filepath="output/pins.jsonl"):
2 with open(filepath, "w", encoding="utf-8") as f:
3 for item in data:
4 f.write(json.dumps(item, ensure_ascii=False) + "\n")
Export nach Google Sheets, Airtable oder Notion
Wenn du Daten direkt aus Python nach Google Sheets schicken willst, brauchst du die Bibliothek gspread und einen Google-Cloud-Service-Account. Für Airtable nimmst du pyairtable. Für Notion gibt es notion-client. Jede dieser Optionen erfordert API-Key-Setup und macht deine Pipeline deutlich komplexer.
Oder – und hier bin ich vielleicht voreingenommen, aber es ist wirklich der schnellste Weg – du nutzt , um Pinterest zu scrapen und direkt per Klick nach Google Sheets, Excel, Airtable oder Notion zu exportieren. Keine API-Keys, keine Service-Accounts, kein zusätzlicher Code. Die erledigt den Export nativ.
Tipps, um beim Pinterest-Scraping nicht geblockt zu werden
Das Anti-Bot-System von Pinterest wird von ScrapeOps mit bewertet – also nicht trivial, aber auch nicht das schwerste Ziel. Es nutzt Browser-Fingerprinting, Verhaltensanalyse und IP-basiertes Rate-Limiting. Was funktioniert:
- User-Agents rotieren: Verwende einen Pool echter Chrome-User-Agent-Strings und wähle pro Sitzung zufällig einen aus.
- Zufällige Pausen einbauen: 2–5 Sekunden zwischen Scrolls und Requests, mit Jitter. Ohne Proxies solltest du auf 10–15 Sekunden erhöhen.
- Realistisches Viewport-Format: Setze
viewport={"width": 1920, "height": 1080}– keine kleinen oder ungewöhnlichen Dimensionen. - Bei Skalierung Proxies nutzen: Wenn du Tausende Pins scrapen willst, rotiere Residential Proxies. Ohne sie musst du nach einigen hundert Requests mit IP-Blocks rechnen.
robots.txtrespektieren: Dierobots.txtvon Pinterest blockiert die meisten automatisierten Crawler und enthält . Behalte das im Hinblick auf Compliance im Kopf.- Scraping im eingeloggten Zustand vermeiden: Bleib bei öffentlich sichtbaren Inhalten und scrape ausgeloggt. Scraping hinter einem Login erhöht rechtliche und technische Risiken.
Thunderbit behandelt Anti-Bot- und CAPTCHA-Herausforderungen automatisch über seine KI-Engine – also eine Sache weniger, um die du dich kümmern musst, wenn du den No-Code-Weg gehst.
Rechtliche und ethische Aspekte beim Pinterest-Scraping
Ich halte mich hier kurz, weil das nicht der Schwerpunkt des Artikels ist – aber es ist wichtig.
Die Nutzungsbedingungen von Pinterest (Abschnitt 2a) besagen, dass du zustimmst, Daten oder Inhalte von Pinterest nicht „auf nicht autorisierte Weise zu scrapen, zu sammeln, zu durchsuchen, zu kopieren oder anderweitig darauf zuzugreifen, etwa durch automatisierte Mittel (ohne unsere ausdrückliche vorherige Genehmigung).“ Dennoch haben Gerichte in der Regel entschieden, dass das Scrapen öffentlich zugänglicher Daten den Computer Fraud and Abuse Act nicht verletzt – siehe sowie Meta v. Bright Data (Januar 2024), wo das Gericht entschied, dass das Scrapen öffentlich sichtbarer Daten im ausgeloggten Zustand legal ist.
Ein paar Grundregeln:
- Scrape nur öffentlich sichtbare Inhalte und bleib ausgeloggt
- Nutze gescrapte Daten nicht für Spam oder zur Imitation anderer Nutzer
- Achte beim Umgang mit Bildern auf Urheberrechte – extrahiere möglichst Metadaten und verbreite urheberrechtlich geschützte Bilder nicht kommerziell ohne Erlaubnis
- Wenn du gescrapte Daten kommerziell nutzen willst, sprich mit einer Rechtsberatung
Für einen tieferen Blick auf die Rechtslage siehe unseren .
Fazit: Was du gelernt hast und wie es weitergeht
Du weißt jetzt, warum statisches Scraping auf Pinterest scheitert (es ist eine React-SPA – kein JavaScript, keine Daten), wie du mit Playwright Suchergebnisse, Boards und Nutzerprofile scrapen kannst, wie du einen produktionsreifen Infinite-Scroll-Handler baust, der nicht nach 16 Pins aufgibt, und wie du Bilder in voller Auflösung statt winziger Thumbnails erhältst.
Die Kurzfassung der wichtigsten Punkte:
requests+ BeautifulSoup funktionieren auf Pinterest nicht. Verlier damit keine Zeit.- Playwright ist das beste Python-Tool für diesen Job – schnell, gut gepflegt und mit nativem JS-Rendering.
- Infinite Scroll braucht eine Schleife mit Deduplizierung, nicht nur eine feste Anzahl an Scrolls.
- Bilder in voller Auflösung erfordern eine Anpassung des URL-Pfads – nutze
/736x/(da/originals/oft 403 zurückgibt). - Board- und Profil-Scraping wird in vielen Tutorials kaum behandelt, ist aber mit den richtigen Selektoren gut machbar.
- Für Nicht-Programmierer oder Teams, die Geschwindigkeit wollen, lässt dich Pinterest in 2 Klicks scrapen und nach Google Sheets, Excel, Airtable oder Notion exportieren – ganz ohne Python. Teste es kostenlos über die .
Wenn du eine Python-Pipeline baust, gibt dir der Code in diesem Guide eine solide Grundlage. Wenn du nur die Daten brauchst, ist Thunderbit die Abkürzung. So oder so bleibst du nicht mehr bei 16 Pins und ratlos vor dem Bildschirm sitzen.
Mehr zu Scraping und Datenextraktion findest du in unseren Guides zu , und . Du kannst auch einen Blick auf werfen oder Tutorials auf dem ansehen.
FAQs
1. Kann man Pinterest mit BeautifulSoup scrapen?
Nicht wirklich effektiv allein. Pinterest rendert alle Inhalte per JavaScript, daher sieht requests + BeautifulSoup nur eine leere HTML-Hülle. Du brauchst zunächst einen Headless-Browser wie Playwright oder Selenium, um die Seite zu rendern, oder du nutzt ein No-Code-Tool wie Thunderbit, das das JavaScript-Rendering automatisch übernimmt.
2. Wie viele Pins kann man in einer Sitzung von Pinterest scrapen?
Das hängt von deiner Scroll-Logik und der Anti-Bot-Behandlung ab. Mit dem produktionsreifen Infinite-Scroll-Handler aus diesem Guide (Deduplizierung, Timeout, Retry-Logik) kannst du zuverlässig Hunderte bis Tausende Pins pro Board oder Suchanfrage erfassen. Bei sehr großen Boards solltest du mit mehreren Minuten Scroll- und Sammelzeit rechnen.
3. Warum sind meine gescrapten Pinterest-Bilder so klein?
Standardmäßig liefert Pinterest im Raster /236x/-Thumbnails aus. Für höhere Auflösung musst du den Bild-URL-Pfad auf /736x/ oder /originals/ umschreiben. Beachte aber, dass /originals/ seit 2025 zunehmend 403-Fehler zurückgibt, weshalb /736x/ die verlässliche Obergrenze ist.
4. Ist das Scrapen von Pinterest legal?
Das Scrapen öffentlich zugänglicher Daten wird durch neuere Gerichtsentscheidungen im Allgemeinen akzeptiert (z. B. hiQ v. LinkedIn, Meta v. Bright Data), aber die Nutzungsbedingungen von Pinterest verbieten nicht autorisierten automatisierten Zugriff. Bleib bei öffentlichen Inhalten, nutze gescrapte Daten nicht für Spam, respektiere Urheberrechte und hole dir für kommerzielle Fälle juristischen Rat.
5. Was ist die beste No-Code-Alternative zum Scrapen von Pinterest?
kann Pinterest-Daten – Titel, Bilder, URLs, Beschreibungen – in 2 Klicks extrahieren und direkt nach Google Sheets, Excel, Airtable oder Notion exportieren. Er übernimmt JavaScript-Rendering, Infinite Scroll und Anti-Bot-Herausforderungen automatisch, sodass du keinen Code schreiben oder warten musst.
Mehr erfahren