Du startest dein Python-Skript, um für ein Marktforschungsprojekt Inspirationsbilder von Pinterest zu ziehen – und am Ende stehen 16 Pins. Aus einem Board mit über 2.000. Genau diese Erfahrung ist aus meiner Sicht die häufigste Enttäuschung bei Entwicklern, die Pinterest mit Python scrapen wollen. Man wirft requests und BeautifulSoup an, ruft eine Pinterest-URL auf und bekommt entweder 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 bekommt den eigentlichen Inhalt nie zu Gesicht. In diesem Guide zeige ich dir, warum das so ist, welche Ansätze wirklich funktionieren (Playwright, internes API-Intercepting und No-Code-Tools wie Thunderbit), und gebe dir Schritt-für-Schritt-Code zum Scrapen von Pins, Boards, Nutzerprofilen, Infinite Scroll und Bildern in voller Auflösung. Ob du einen produktionsreifen Scraper bauen oder einfach schnell Daten einsammeln willst – hier wirst du fündig.
Was bedeutet Pinterest Scraping?
Pinterest Scraping meint das programmatische Extrahieren von Daten aus Pinterest – also etwa Pin-Bildern, Titeln, Beschreibungen, Board-Namen, Follower-Zahlen und URLs. Statt Pins einzeln zu öffnen und zu speichern, setzt du Code (oder ein Tool) ein, um strukturierte Daten aus Suchergebnissen, Boards oder Profilen im großen Stil zu erfassen.
Mit über 240 Milliarden Pins auf der Plattform und 619 Millionen monatlich aktiven Nutzern Ende 2025 ist Pinterest eine der reichhaltigsten visuellen Datenquellen im Web. Für Unternehmen sind diese Daten bares Geld wert – egal, ob du Produkttrends verfolgst, Inhalte von Wettbewerbern vergleichst oder Influencer-Listen für die Ansprache aufbaust.
Warum Pinterest mit Python scrapen?
Pinterest ist längst nicht mehr nur die Pinnwand für Hochzeitsplaner. Es ist eine ernstzunehmende Plattform für Business Intelligence – 85 % der wöchentlichen Pinner haben schon einmal etwas aufgrund von Brand-Pins gekauft, und 96–97 % der Top-Suchen sind nicht markengebunden. Heißt: Nutzer kommen mit einer klaren Absicht, aber ohne festgelegte Marke. 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 aufgeschlüsselt 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 jetzt 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 die Daten deines eigenen Kontos. Willst du öffentliche Boards, Suchergebnisse oder Wettbewerber-Profile abrufen, bleibt Scraping als 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. Rufst du eine Pinterest-URL mit einer normalen HTTP-Anfrage ab, 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 entstehen erst nach der JavaScript-Ausführung im Browser.
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 die Scroll-Simulation, wird aktiv gepflegt (78.600+ GitHub-Sterne, mit 180 % Wachstum im Jahresvergleich bei Stellenanzeigen) und ist in Benchmarks 35–45 % schneller als Selenium. Wer den No-Code-Weg bevorzugt, kommt weiter unten ebenfalls auf seine Kosten.
Pinterest Official API vs. Python Scraping vs. No-Code: Welcher Weg passt?
Bevor du anfängst zu coden, lohnt sich die Frage: Musst du das überhaupt selbst bauen? Hier 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 Thunderbits AI Web Scraper der Schnellweg. Du öffnest 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 rufst du sogar einzelne Pin-Links automatisch auf und reicherst die Daten an. Ich habe Teammitglieder ohne eine einzige Zeile Code dabei beobachtet, 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 schlicht 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
Leg zunächst einen Projektordner an und richte eine virtuelle Umgebung ein:
mkdir pinterest-scraper
cd pinterest-scraper
python -m venv venv
source venv/bin/activate # Unter Windows: venv\Scripts\activate
Installiere Playwright und lade das Chromium-Browser-Binary herunter:
pip install playwright
playwright install chromium
Für den Export der Daten nutzt 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:
pinterest-scraper/
├── scraper.py
├── config.py
├── output/
│ ├── pins.json
│ └── pins.csv
└── images/
├── board-name-1/
└── board-name-2/
In config.py legst du deinen User-Agent fest. Pinterest blockiert Standard-Signaturen von Headless-Browsern, also nimm einen realistischen Wert:
USER_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:
query = "mid century modern furniture"
url = f"https://www.pinterest.com/search/pins/?q={query.replace(' ', '%20')}&rs=typed"
Das lässt sich für jeden Suchbegriff parametrieren. Der Parameter rs=typed signalisiert Pinterest, dass die Suche getippt und nicht vorgeschlagen war, was die Relevanz der Ergebnisse mitunter beeinflusst.
Schritt 2: Einen Headless-Browser starten und die Seite laden
Hier das zentrale Playwright-Setup. Achte auf den benutzerdefinierten User-Agent – ohne ihn blockiert dich Pinterest wahrscheinlich oder zeigt eine Login-Sperre.
import asyncio
from playwright.async_api import async_playwright
from config import USER_AGENT
async def scrape_search(query, max_pins=100):
url = f"https://www.pinterest.com/search/pins/?q={query.replace(' ', '%20')}&rs=typed"
async with async_playwright() as p:
browser = await p.chromium.launch(headless=True)
page = await browser.new_page(
user_agent=USER_AGENT,
viewport={"width": 1920, "height": 1080}
)
await page.goto(url)
await asyncio.sleep(3) # Warten, bis JavaScript die ersten Pins rendert
Nach diesem Schritt sollte die erste Gruppe von Pins geladen sein – in der Regel 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.
results = []
pins = await page.query_selector_all("div[data-test-id='pinWrapper']")
for pin in pins:
link = await pin.query_selector("a")
if not link:
continue
title = await link.get_attribute("aria-label") or ""
href = await link.get_attribute("href") or ""
img = await link.query_selector("img")
src = await img.get_attribute("src") if img else ""
results.append({
"title": title,
"url": f"https://www.pinterest.com{href}" if href.startswith("/") else href,
"image_url": src
})
An diesem Punkt enthält results die Pins, die im ersten Viewport sichtbar sind. Für mehr musst du scrollen – und genau das ist der entscheidende Teil.
Schritt 4: Ergebnisse als JSON oder CSV speichern
Nach der Extraktion schreibst du die Daten in Dateien, damit du sie weiterverwenden kannst:
import json
import csv
def save_json(data, filepath="output/pins.json"):
with open(filepath, "w", encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False, indent=2)
def save_csv(data, filepath="output/pins.csv"):
if not data:
return
with open(filepath, "w", newline="", encoding="utf-8-sig") as f:
writer = csv.DictWriter(f, fieldnames=data[0].keys())
writer.writeheader()
writer.writerows(data)
Willst du die CSV später in Excel öffnen, nimm utf-8-sig als Encoding – so vermeidest du beschädigte Sonderzeichen.
Ganze Pinterest-Boards und Nutzerprofile scrapen
Hier fehlt in vielen bestehenden Tutorials ein wichtiges Stück. Ich habe kein einziges Konkurrenz-Tutorial gefunden, das Board- oder Profil-Scraping wirklich gründlich behandelt – obwohl genau das zu den am häufigsten gewünschten Funktionen in Foren zählt. Nutzer wollen 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 stecken in div[data-test-id='pinWrapper'] –, aber du musst scrollen, um sie alle zu laden.
async def scrape_board(board_url, max_pins=500):
async with async_playwright() as p:
browser = await p.chromium.launch(headless=True)
page = await browser.new_page(user_agent=USER_AGENT, viewport={"width": 1920, "height": 1080})
await page.goto(board_url)
await asyncio.sleep(3)
seen_ids = set()
all_pins = []
for scroll_round in range(100): # Sicherheitslimit
pins = await page.query_selector_all("div[data-test-id='pinWrapper']")
new_count = 0
for pin in pins:
link = await pin.query_selector("a")
if not link:
continue
href = await link.get_attribute("href") or ""
if href in seen_ids:
continue
seen_ids.add(href)
new_count += 1
title = await link.get_attribute("aria-label") or ""
img = await link.query_selector("img")
src = await img.get_attribute("src") if img else ""
all_pins.append({
"title": title,
"url": f"https://www.pinterest.com{href}" if href.startswith("/") else href,
"image_url": src
})
print(f"Scroll {scroll_round + 1}: {len(all_pins)} eindeutige Pins gesammelt")
if new_count == 0 or len(all_pins) >= max_pins:
break
prev_height = await page.evaluate("document.body.scrollHeight")
await page.evaluate("window.scrollTo(0, document.body.scrollHeight)")
await asyncio.sleep(2.5)
curr_height = await page.evaluate("document.body.scrollHeight")
if curr_height == prev_height:
break # Kein weiterer Inhalt
await browser.close()
return all_pins
Worauf du achten solltest: Auf Board-Seiten taucht mitunter ein Bereich „More Ideas“ auf, der gespeicherte Pins von algorithmischen Empfehlungen trennt. Willst du nur die tatsächlich gespeicherten Pins des Nutzers, 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 mitunter im Profil-Header angezeigt
async def scrape_profile(username):
url = f"https://www.pinterest.com/{username}/"
async with async_playwright() as p:
browser = await p.chromium.launch(headless=True)
page = await browser.new_page(user_agent=USER_AGENT, viewport={"width": 1920, "height": 1080})
await page.goto(url)
await asyncio.sleep(3)
# Follower-Zahl extrahieren
follower_el = await page.query_selector("div[data-test-id='follower-count']")
followers = await follower_el.inner_text() if follower_el else "N/A"
# Board-Links extrahieren
board_links = await page.query_selector_all("a[href*='/" + username + "/']")
boards = []
for bl in board_links:
href = await bl.get_attribute("href") or ""
name = await bl.get_attribute("aria-label") or href.split("/")[-2]
if href.count("/") >= 3 and href != f"/{username}/":
boards.append({"name": name, "url": f"https://www.pinterest.com{href}"})
await browser.close()
return {"username": username, "followers": followers, "boards": boards}
Wenn du sämtliche Pins über alle Boards eines Profils scrapen willst, iterierst du einfach durch die Board-Liste und rufst für jedes Board scrape_board() auf. Die heruntergeladenen Bilder lassen sich anschließend automatisch in separate Board-Ordner einsortieren.
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 schon reicht.
Dieser Ansatz ist unzuverlässig. Pinterest lädt neue Inhalte in Paketen von rund 25 Pins nach, ausgelöst durch Scroll-Events. Scrollst du fünfmal, bekommst du vielleicht 125 Pins – oder nur 75, wenn das Netzwerk langsam ist, oder 150, wenn die Pakete kleiner ausfielen. Du brauchst also ein klügeres Muster.
Das Scrollen-bis-keine-neuen-Inhalte-mehr-kommen-Muster
Hier eine robuste Scroll-Funktion, die eindeutige Pin-IDs verfolgt, ein konfigurierbares Timeout nutzt, Retry-Logik enthält und den Fortschritt ausgibt:
import time
import random
async def scroll_and_collect(page, max_pins=1000, max_scrolls=200, scroll_pause=2.5):
seen_ids = set()
all_pins = []
no_new_count = 0
for i in range(max_scrolls):
pins = await page.query_selector_all("div[data-test-id='pinWrapper']")
new_this_round = 0
for pin in pins:
link = await pin.query_selector("a")
if not link:
continue
href = await link.get_attribute("href") or ""
if href in seen_ids:
continue
seen_ids.add(href)
new_this_round += 1
title = await link.get_attribute("aria-label") or ""
img = await link.query_selector("img")
src = await img.get_attribute("src") if img else ""
all_pins.append({
"title": title,
"url": f"https://www.pinterest.com{href}" if href.startswith("/") else href,
"image_url": src
})
print(f" Scroll {i+1}: {new_this_round} neue Pins | {len(all_pins)} Pins insgesamt")
if len(all_pins) >= max_pins:
print(f" Max-Pins-Grenze ({max_pins}) erreicht. Abbruch.")
break
if new_this_round == 0:
no_new_count += 1
if no_new_count >= 3:
print(" Nach 3 aufeinanderfolgenden Scrolls keine neuen Pins. Inhalt offenbar erschöpft.")
break
else:
no_new_count = 0
prev_height = await page.evaluate("document.body.scrollHeight")
await page.evaluate("window.scrollTo(0, document.body.scrollHeight)")
await asyncio.sleep(scroll_pause + random.uniform(0.5, 1.5))
curr_height = await page.evaluate("document.body.scrollHeight")
if curr_height == prev_height and new_this_round == 0:
print(" Seitenhöhe unverändert und keine neuen Pins. Feed vermutlich am Ende.")
break
return all_pins
Warum dieses Design funktioniert:
- Deduplizierung über href: Die URL jedes Pins ist eindeutig, also nutzen wir sie als ID. So wird derselbe Pin beim erneuten Rendern des DOM nicht doppelt gezählt.
- Drei-Versuche-Regel: Liefern drei Scrolls hintereinander null neue Pins, stoppen wir. Das fängt den Fall ab, dass die Seite zwar noch lädt, aber kein neuer Inhalt da ist.
- Zufälliges Jitter bei den 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 schiefläuft.
Randfälle behandeln
- „More Ideas“-Unterbrechung: Auf Board-Seiten schiebt Pinterest gelegentlich einen Bereich „More Ideas“ ein. Willst du nur die eigentlichen Pins des Boards, kannst du auf dieses Element prüfen und das Scrollen beenden, sobald es erscheint.
- Rate-Limiting bei langen Sessions: Scrollst du dich durch ein Board mit Tausenden Pins, kann Pinterest die Anfragen drosseln. Liefern Scrolls gelegentlich keine neuen Pins (aber nicht drei in Folge), erhöhe die Scroll-Pause auf 5+ Sekunden.
Pinterest-Bilder in voller Auflösung abrufen, nicht nur Thumbnails
Daran verzweifeln viele. Du scrapst eine Menge Pins, lädst die Bilder herunter – und alle sind winzige 236px-Thumbnails. In Foren heißt es dazu oft „trash quality, viel zu klein“. Die Lösung steckt 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 eine Funktion, die jede Pinterest-Bild-URL auf die bestmögliche Qualität umschreibt, inklusive Fallback-Logik:
import requests as req
def upgrade_image_url(url, preferred_size="originals"):
"""Schreibt eine Pinterest-Bild-URL auf die höchstmögliche Auflösung um."""
sizes = ["originals", "736x", "474x", "236x"]
if preferred_size not in sizes:
preferred_size = "originals"
for size in sizes[sizes.index(preferred_size):]:
upgraded = url
for s in sizes:
upgraded = upgraded.replace(f"/{s}/", f"/{size}/")
try:
resp = req.head(upgraded, timeout=5, allow_redirects=True)
if resp.status_code == 200:
return upgraded
except Exception:
continue
return url # Gibt die Original-URL zurück, wenn alles fehlschlägt
Wichtig (Stand 2025): Der Pfad /originals/ liefert immer häufiger HTTP-403-Fehler. Ein dokumentiertes Problem in gallery-dl bestätigt dieses Verhalten ab 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
import os
import time
def download_images(pins, folder="images/default", delay=1.5):
os.makedirs(folder, exist_ok=True)
for i, pin in enumerate(pins):
img_url = upgrade_image_url(pin.get("image_url", ""), preferred_size="736x")
if not img_url:
continue
filename = f"pin_{i+1}.jpg"
filepath = os.path.join(folder, filename)
try:
resp = req.get(img_url, timeout=15)
if resp.status_code == 200:
with open(filepath, "wb") as f:
f.write(resp.content)
print(f" {filename} heruntergeladen ({len(resp.content) // 1024} KB)")
else:
print(f" Fehler bei {filename}: HTTP {resp.status_code}")
except Exception as e:
print(f" Fehler beim Download von {filename}: {e}")
time.sleep(delay + random.uniform(0.3, 0.8))
Füge zwischen den Downloads eine Verzögerung zur Begrenzung der Anfragerate ein. Ich nehme 1,5–2,3 Sekunden mit etwas Zufall. Ohne das blockiert Pinterest deine IP nach einigen Hundert Anfragen.
Deine gescrapten Pinterest-Daten exportieren
Export nach CSV oder JSON
Die Grundlagen haben wir oben bereits behandelt. Für größere Datensätze (10.000+ Pins) lohnt sich ein Blick auf JSON Lines – ein JSON-Objekt pro Zeile –, da sich das leichter streamen und verarbeiten lässt:
def save_jsonl(data, filepath="output/pins.jsonl"):
with open(filepath, "w", encoding="utf-8") as f:
for item in data:
f.write(json.dumps(item, ensure_ascii=False) + "\n")
Export nach Google Sheets, Airtable oder Notion
Willst du Daten direkt aus Python nach Google Sheets schicken, 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 verlangt ein API-Key-Setup und macht deine Pipeline spürbar komplexer.
Oder – und hier bin ich vielleicht voreingenommen, aber es ist wirklich der schnellste Weg – du nutzt Thunderbit, um Pinterest zu scrapen und per Klick direkt nach Google Sheets, Excel, Airtable oder Notion zu exportieren. Keine API-Keys, keine Service-Accounts, kein zusätzlicher Code. Die Thunderbit Chrome Extension erledigt den Export nativ.
Tipps, um beim Pinterest-Scraping nicht geblockt zu werden
Das Anti-Bot-System von Pinterest stuft ScrapeOps mit 6/10 Umgehungsschwierigkeit ein – also nicht trivial, aber auch nicht das härteste Ziel. Es setzt auf 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 erhöhst du das besser auf 10–15 Sekunden.
- Realistisches Viewport-Format: Setze
viewport={"width": 1920, "height": 1080}– keine kleinen oder ungewöhnlichen Dimensionen. - Bei Skalierung Proxies nutzen: Willst du Tausende Pins scrapen, 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 führt rund 180 Disallow-Regeln. Behalte das mit Blick auf Compliance im Hinterkopf.- Scraping im eingeloggten Zustand vermeiden: Bleib bei öffentlich sichtbaren Inhalten und scrape ausgeloggt. Scraping hinter einem Login erhöht die rechtlichen und technischen Risiken.
Thunderbit bewältigt Anti-Bot- und CAPTCHA-Herausforderungen automatisch über seine KI-Engine – also eine Sorge weniger, wenn du den No-Code-Weg gehst.
Rechtliche und ethische Aspekte beim Pinterest-Scraping
Ich fasse mich hier kurz, weil es nicht der Schwerpunkt des Artikels ist – wichtig ist es trotzdem.
Die Nutzungsbedingungen von Pinterest (Abschnitt 2a) besagen, dass du dich verpflichtest, 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 hiQ v. LinkedIn sowie Meta v. Bright Data (Januar 2024), wo das Gericht das Scrapen öffentlich sichtbarer Daten im ausgeloggten Zustand für legal befand.
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
- Willst du gescrapte Daten kommerziell nutzen, sprich mit einer Rechtsberatung
Einen tieferen Blick auf die Rechtslage liefert unser Guide zu den rechtlichen Implikationen von Web Scraping.
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 scrapst, wie du einen produktionsreifen Infinite-Scroll-Handler baust, der nicht schon nach 16 Pins aufgibt, und wie du Bilder in voller Auflösung statt winziger Thumbnails erhältst.
Die wichtigsten Punkte in Kurzform:
requests+ BeautifulSoup funktionieren auf Pinterest nicht. Verschwende 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 bloß 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 kommt in vielen Tutorials kaum vor, ist mit den richtigen Selektoren aber gut machbar.
- Für Nicht-Programmierer oder Teams, die Tempo wollen, lässt dich Thunderbit Pinterest in 2 Klicks scrapen und nach Google Sheets, Excel, Airtable oder Notion exportieren – ganz ohne Python. Teste es kostenlos über die Chrome Extension.
Baust du eine Python-Pipeline, gibt dir der Code in diesem Guide eine solide Grundlage. Brauchst du nur die Daten, ist Thunderbit die Abkürzung. So oder so bleibst du nicht länger bei 16 Pins und ratlos vor dem Bildschirm sitzen.
Mehr zu Scraping und Datenextraktion findest du in unseren Guides zu Web Scraping mit Python, den besten automatisierten Web-Scraping-Tools und Daten von Websites nach Excel scrapen. Außerdem lohnt sich ein Blick auf Thunderbit Pricing oder die Tutorials auf dem Thunderbit YouTube Channel.
FAQs
1. Kann man Pinterest mit BeautifulSoup scrapen?
Allein nicht wirklich effektiv. 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 nimmst 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) erfasst du zuverlässig Hunderte bis Tausende Pins pro Board oder Suchanfrage. 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), doch die Nutzungsbedingungen von Pinterest verbieten nicht autorisierten automatisierten Zugriff. Bleib bei öffentlichen Inhalten, nutze gescrapte Daten nicht für Spam, respektiere Urheberrechte und hol dir für kommerzielle Fälle juristischen Rat.
5. Was ist die beste No-Code-Alternative zum Scrapen von Pinterest?
Thunderbits AI Web Scraper extrahiert Pinterest-Daten – Titel, Bilder, URLs, Beschreibungen – in 2 Klicks und exportiert direkt nach Google Sheets, Excel, Airtable oder Notion. Er übernimmt JavaScript-Rendering, Infinite Scroll und Anti-Bot-Herausforderungen automatisch, sodass du keinen Code schreiben oder warten musst.
Mehr erfahren


