Etsy scrapen für Niche Research: Praktischer Leitfaden für POD-Teams

Lerne, wie du Etsy-Listings, Shop-Daten und Nischen-Metriken scrapest – mit CSS/XPath-Selektoren, Rate-Limit-Strategien und Residential Proxies über ProxyHat.

Etsy scrapen für Niche Research: Praktischer Leitfaden für POD-Teams
In diesem Artikel

Etsy scrapen: API-Endpunkte vs. HTML – was du wissen musst

Etsy betreibt eine öffentliche Open-API, aber sie ist seit 2022 für neue Apps praktisch geschlossen. Die rate-limits sind restriktiv (ca. 360 Requests/Minute für Lesezugriff), und wichtige Daten – Trending-Searches, Sales-Badges, Shop-Metriken – fehlen komplett. Für Niche-Research und POD-Konkurrenzanalyse bleibt HTML-Scraping der einzig realistische Weg.

Das bedeutet: Du parst gerenderte Seiten, kämpfst mit Cloudflare und musst residential IPs rotieren, damit Etsy dich nicht nach 20 Requests blockiert. Dieser Leitfaden zeigt dir genau, wie das funktioniert – mit konkreten Selektoren, Rate-Limits und ProxyHat-Konfiguration.

Etsys Seitenstruktur verstehen

Bevor du Code schreibst, musst du wissen, wo die Daten wohnen. Etsy hat vier relevante Seitentypen:

1. Suchergebnisseiten

URL-Muster: https://www.etsy.com/search?q=QUERY&ref=search_bar

  • Paginierung über &page=2, &page=3 etc.
  • Sortierung: &order=price_asc, &order=highest_review, &order=newest
  • Filter: &min_price=10&max_price=50, &ship_to=DE

Listing-Cards auf der Suchseite enthalten: Titel, Preis, Seller-Name, Bewertungsdurchschnitt, Anzahl Bewertungen, ob es ein Bestseller ist, ob kostenloses Shipping angeboten wird.

2. Listing-Detailseiten

URL-Muster: https://www.etsy.com/listing/LISTING_ID/LISTING_SLUG

Hier findest du die reichen Daten: Beschreibung, Varianten, Tags, Material, Shipping-Kosten, Verkaufszahlen (indirekt über „x sold"-Badge), Shop-Info.

3. Shop-Seiten

URL-Muster: https://www.etsy.com/shop/SHOP_NAME

Enthält: Shop-Banner, Bio, Gesamt-Verkaufszahl („X sales"), Gesamtbewertungen, Listing-Anzahl, Gründungsdatum.

4. Kategorienbaum

URL-Muster: https://www.etsy.com/c/CATEGORY_PATH

Etsy organisiert Produkte hierarchisch: JewelryRingsStatement Rings. Den Kategorienbaum kannst du über die Navigationslinks auf etsy.com/c/ rekursiv crawlen.

Anti-Bot-Maßnahmen: Cloudflare und Rate-Limits

Etsy nutzt Cloudflare als WAF – das bedeutet JavaScript-Challenges, TLS-Fingerprinting und Verhaltensanalyse. Zusätzlich hat Etsy interne Rate-Limits:

SchwellenwertVerhaltenEmpfehlung
~10-15 Requests/SekundeSoft rate-limit (HTTP 429)Max 5-8 req/s mit Pausen
~50-80 Requests/Minute von einer IPTemporärer Block (CAPTCHA-Seite)IP nach 30-40 Requests rotieren
Hunderte Requests ohne Session-KonsistenzCloudflare Challenge LoopResidential Proxies + Sticky Sessions

Warum Residential Proxies? Datacenter-IPs werden von Cloudflare fast sofort erkannt. Mobile Proxies funktionieren gut, sind aber teurer. Residential Proxies bieten das beste Preis-Leistungs-Verhältnis für Etsy – sie sehen aus wie echte Nutzer-Verbindungen.

Mit ProxyHat rotierst du residential IPs und nutzt Sticky Sessions, damit ein Crawl-Durchlauf konsistent bleibt:

# HTTP Proxy – pro Request neue IP
http://user-country-US:PASSWORD@gate.proxyhat.com:8080

# Sticky Session – gleiche IP für mehrere Requests
http://user-country-US-session-abc123:PASSWORD@gate.proxyhat.com:8080

Scraping-Patterns für Niche Discovery

Für POD-Teams sind drei Metriken besonders wertvoll:

Etsy zeigt auf der Startseite und in der Such-Autovervollständigung Trending-Queries. Die Autovervollständigungs-API ist öffentlich:

GET https://www.etsy.com/api/v3/ajax/member/suggestions?q=cat+&lang=de

Antwort (gekürzt):

{
  "results": [
    {"query": "cat shirt", "type": "trending"},
    {"query": "cat lover gift", "type": "trending"},
    {"query": "cat mom mug", "type": "suggestion"}
  ]
}

Damit kannst du systematisch Nischen-Keywords sammeln, indem du Seed-Keywords durchiterierst.

Seller-Count pro Nische

Scrape die Suchergebnisse für ein Keyword und zähle eindeutige Shop-Namen. Wenige Seller + hohe Nachfrage = ungesättigte Nische. Viele Seller + niedrige Preise = Commoditized – vermeiden für POD.

Durchschnittliche Preis-Punkte

Extrahiere alle Preise von der Suchseite und berechne Median und Quartile. Wenn der Median für „custom cat mug" bei 22€ liegt und dein POD-Kostenpunkt bei 12€, hast du Raum für Profit.

Python-Beispiel: Suchergebnisse → Listings → Details

Hier ist ein vollständiges Beispiel, das Suchergebnisse scrapet, Listing-Cards parst und dann Detailseiten abruft – alles mit ProxyHat Residential Proxies und IP-Rotation.

import requests
from bs4 import BeautifulSoup
import time
import random
from urllib.parse import quote

PROXY_URL = "http://user-country-US:PASSWORD@gate.proxyhat.com:8080"
PROXIES = {"http": PROXY_URL, "https": PROXY_URL}

HEADERS = {
    "User-Agent": (
        "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
        "AppleWebKit/537.36 (KHTML, like Gecko) "
        "Chrome/125.0.0.0 Safari/537.36"
    ),
    "Accept-Language": "en-US,en;q=0.9",
    "Accept": "text/html,application/xhtml+xml",
}

def scrape_search(keyword, max_pages=3):
    """Scrape Etsy search results for a given keyword."""
    listings = []
    for page in range(1, max_pages + 1):
        url = f"https://www.etsy.com/search?q={quote(keyword)}&page={page}"
        # Rotate IP every page via session flag
        session_id = f"niche-{keyword.replace(' ','-')}-p{page}"
        proxy = f"http://user-country-US-session-{session_id}:PASSWORD@gate.proxyhat.com:8080"
        proxies = {"http": proxy, "https": proxy}

        resp = requests.get(url, headers=HEADERS, proxies=proxies, timeout=30)
        if resp.status_code == 403:
            print(f"  Blocked on page {page}, rotating IP...")
            continue

        soup = BeautifulSoup(resp.text, "html.parser")
        cards = soup.select("div.v2-listing-card__info")

        for card in cards:
            title_el = card.select_one("h3")
            price_el = card.select_one("span.currency-value")
            seller_el = card.select_one("p.v2-listing-card__shop-name")
            rating_el = card.select_one("span.v2-listing-card__rating")

            listings.append({
                "title": title_el.text.strip() if title_el else None,
                "price": price_el.text.strip() if price_el else None,
                "seller": seller_el.text.strip() if seller_el else None,
                "rating": rating_el.text.strip() if rating_el else None,
                "listing_url": card.parent.get("href", "") if card.parent else None,
            })

        time.sleep(random.uniform(2.0, 4.5))  # respect rate limits
    return listings


def scrape_listing_detail(listing_url):
    """Scrape a single listing detail page."""
    # New IP per detail request
    proxy = f"http://user-country-US:PASSWORD@gate.proxyhat.com:8080"
    proxies = {"http": proxy, "https": proxy}

    resp = requests.get(listing_url, headers=HEADERS, proxies=proxies, timeout=30)
    soup = BeautifulSoup(resp.text, "html.parser")

    # Tags
    tags = [t.text.strip() for t in soup.select("a.tag")]

    # Sales badge (e.g. "2,415 sales")
    sales_el = soup.select_one("span[data-sales]")
    sales = sales_el.text.strip() if sales_el else None

    # Description
    desc_el = soup.select_one("div[data-appearance-id='description']")
    description = desc_el.text.strip()[:500] if desc_el else None

    return {"tags": tags, "sales": sales, "description": description}


# --- Run ---
results = scrape_search("custom cat mug", max_pages=3)
print(f"Found {len(results)} listings")

for listing in results[:5]:
    if listing["listing_url"]:
        detail = scrape_listing_detail(listing["listing_url"])
        print(f"  Tags: {detail['tags'][:5]}")
        print(f"  Sales: {detail['sales']}")
        time.sleep(random.uniform(1.5, 3.5))

Wichtige Hinweise:

  • Die CSS-Klassen (v2-listing-card__info, currency-value etc.) können sich ändern. Immer zuerst manuell im Browser prüfen.
  • Verwende Sticky Sessions für Paginierung, damit deine Session konsistent bleibt.
  • Pausen von 2-4 Sekunden zwischen Requests sind Pflicht – Etsy ist aggressiver als Amazon.

Shop-Analytics: Sales, Listings und Reviews

Shop-Daten sind Gold für POD-Research. Etsy zeigt Verkaufszahlen als grobe Badge an („1,234 sales"), was ausreicht, um Shop-Größen zu schätzen.

Verfügbare Shop-Metriken

  • Sales Count: XPath //span[contains(@class,'shop-sales')] oder CSS span.shop-sales
  • Listing Count: Auf der Shop-Seite unter dem Shop-Namen sichtbar
  • Review Count & Durchschnitt: CSS span.review-count, input[name='rating']
  • Gründungsdatum: Meist im Footer der Shop-Seite als „Since YYYY"

Shop-Scraping-Funktion

def scrape_shop(shop_name):
    """Scrape Etsy shop metrics."""
    url = f"https://www.etsy.com/shop/{shop_name}"
    session_id = f"shop-{shop_name}"
    proxy = f"http://user-country-US-session-{session_id}:PASSWORD@gate.proxyhat.com:8080"
    proxies = {"http": proxy, "https": proxy}

    resp = requests.get(url, headers=HEADERS, proxies=proxies, timeout=30)
    soup = BeautifulSoup(resp.text, "html.parser")

    # Sales badge
    sales_el = soup.select_one("span.shop-sales")
    sales_text = sales_el.text.strip() if sales_el else "0"
    # Parse "1,234 sales" → 1234
    sales_num = int(sales_text.lower().replace("sales", "").replace(",", "").strip() or "0")

    # Review count
    review_el = soup.select_one("span.review-count")
    review_count = review_el.text.strip() if review_el else "0"

    # Number of listings (from shop tab or pagination)
    listing_count_el = soup.select_one("span.listings-count")
    listing_count = listing_count_el.text.strip() if listing_count_el else "unknown"

    return {
        "shop": shop_name,
        "sales": sales_num,
        "reviews": review_count,
        "listing_count": listing_count,
    }


# Example: analyze top sellers in a niche
shops_seen = set()
for listing in results:
    seller = listing.get("seller")
    if seller and seller not in shops_seen:
        shops_seen.add(seller)
        shop_data = scrape_shop(seller)
        print(f"{seller}: {shop_data['sales']} sales, {shop_data['listing_count']} listings")
        time.sleep(random.uniform(3.0, 6.0))

Was du aus Shop-Metriken lernst

  • High Sales + Low Listings: Der Seller hat wenige Produkte, die aber extrem gut verkaufen → Nische mit hoher Conversion.
  • High Sales + High Listings: Volume-Seller – gute Inspiration für Katalog-Breite, aber schwer zu schlagen.
  • Low Sales + High Listings: Seller kämpft – Nische könnte übersättigt sein.

Proxy-Strategie im Vergleich

Proxy-TypEtsy-ErfolgsrateKostenBest für
Datacenter10-20% (Cloudflare blockiert)NiedrigNicht empfohlen für Etsy
Residential (rotierend)85-95%MittelBulk-Scraping, Suchseiten
Residential (Sticky Session)90-98%MittelPaginierte Crawl-Durchläufe
Mobile95-99%HochMaximale Zuverlässigkeit, niedriges Volumen

Für die meisten POD-Research-Use-Cases sind Residential Proxies mit Sticky Sessions optimal. Sie sind bezahlbar und liefern konsistente Sessions, die für Paginierung nötig sind. Sieh dir die ProxyHat-Preise an, um den richtigen Plan zu finden.

Ethik: Etsy-Seller sind kleine Unternehmen

Dieser Punkt ist wichtig und wird oft übersehen. Etsy-Seller sind überwiegend Einzelpersonen und kleine Familienbetriebe – nicht Amazon-Warehouse-Fulfillment-Zentren.

Was in Ordnung ist

  • Nischen-Research: Analysieren, welche Keywords Nachfrage haben, wo Preis-Lücken existieren, welche Tags konvertieren.
  • Marktanalyse: Seller-Counts, Preisverteilungen, Trending-Begriffe sammeln.
  • Konkurrenz-Beobachtung: Verstehen, wie erfolgreiche Shops ihre Listings strukturieren.

Was nicht in Ordnung ist

  • Designs kopieren: Ein Seller hat ein einzigartiges Design → du kopierst es 1:1 auf dein POD-Store.
  • Bilder stehlen: Listing-Bilder herunterladen und als eigene Listings verwenden.
  • Massenhaft Daten abrufen: Ganze Kategorien mit Tausenden Listings scrapen, nur um sie zu replizieren.

Scrape für Erkenntnisse, nicht für Diebstahl. Die Daten sind da, um dich zu inspirieren und zu informieren – nicht, um kreative Arbeit zu stehlen.

Praktische Ethik-Regeln

  • Respektiere robots.txt – Etsy erlaubt einige Pfade, verbietet andere.
  • Rate-limit dich selbst: Max 5-8 Requests/Sekunde, Pausen zwischen Seiten.
  • Scrape nur so viel wie du brauchst – nicht ganze Kategorien „just because".
  • Speichere keine Bilder, es sei denn, du analysierst Bildformate für eigene Listings.
  • Wenn du Daten weitergibst, anonymisiere Seller-Namen in veröffentlichten Berichten.

Rate-Limit-Strategien in der Praxis

Hier ist ein Muster, das Backoff und IP-Rotation kombiniert:

import requests
import time
import random
from itertools import cycle

class EtsyScraper:
    def __init__(self, proxy_user, proxy_pass):
        self.base_proxy = f"http://{proxy_user}:{{session}}@gate.proxyhat.com:8080"
        self.proxy_pass = proxy_pass
        self.session_counter = 0

    def _get_proxy(self, sticky=False):
        if sticky:
            session = f"{self.proxy_user}-session-s{self.session_counter}"
        else:
            self.session_counter += 1
            session = f"{self.proxy_user}-session-r{self.session_counter}"
        proxy_url = self.base_proxy.format(session=session).replace(
            "{session}", session
        )
        # Build correct proxy URL
        proxy_url = f"http://{session}:{self.proxy_pass}@gate.proxyhat.com:8080"
        return {"http": proxy_url, "https": proxy_url}

    def fetch_with_retry(self, url, max_retries=3, sticky=False):
        for attempt in range(max_retries):
            proxies = self._get_proxy(sticky=sticky)
            try:
                resp = requests.get(
                    url, headers=HEADERS, proxies=proxies, timeout=30
                )
                if resp.status_code == 200:
                    return resp
                elif resp.status_code == 429:
                    wait = (2 ** attempt) + random.uniform(1, 5)
                    print(f"  Rate-limited, waiting {wait:.1f}s...")
                    time.sleep(wait)
                elif resp.status_code == 403:
                    print(f"  Blocked (403), rotating IP...")
                    time.sleep(random.uniform(2, 5))
                else:
                    print(f"  HTTP {resp.status_code}, retrying...")
                    time.sleep(2)
            except requests.exceptions.RequestException as e:
                print(f"  Request failed: {e}")
                time.sleep(3)
        return None


# Usage
scraper = EtsyScraper(proxy_user="user-country-US", proxy_pass="PASSWORD")
resp = scraper.fetch_with_retry("https://www.etsy.com/search?q=custom+cat+mug")

Key Takeaways

  • Etsys API ist de facto geschlossen – HTML-Scraping bleibt der einzige Weg für Niche-Research.
  • Cloudflare + interne Rate-Limits machen Residential Proxies obligatorisch; Datacenter-IPs funktionieren nicht.
  • Sticky Sessions sind für paginierte Crawl-Durchläufe essenziell – rotiere IPs alle 30-40 Requests.
  • Konzentriere dich auf drei Metriken: Seller-Count pro Nische, durchschnittliche Preis-Punkte, Trending-Search-Terms.
  • Shop-Sales-Badges geben dir grobe Verkaufszahlen – genug für Größenordnungen und Competitive-Analyse.
  • Ethisch scrapen: Nischen finden, Designs nicht kopieren. Etsy-Seller sind kleine Unternehmen.
  • Rate-limit dich selbst: Max 5-8 req/s, Pausen von 2-4 Sekunden, Backoff bei 429/403.

Wenn du bereit bist, Etsy-Nischen systematisch zu analysieren, starte mit ProxyHat Residential Proxies auf dem Dashboard und baue deine Niche-Research-Pipeline auf. Weitere Scraping-Strategien findest du in unserem Web-Scraping-Use-Case und SERP-Tracking-Leitfaden.

Häufig gestellte Fragen

Ist es legal, Etsy zu scrapen?

Das Scraping öffentlich zugänglicher Daten ist in den meisten Jurisdiktionen legal, aber Etsys Nutzungsbedingungen verbieten automatisierten Zugriff. Scrape nur für persönliche Marktforschung, respektiere robots.txt und rate-limit dich selbst. Kopiere keine Designs oder Bilder – das wäre Urheberrechtsverletzung.

Welche Proxy-Typen funktionieren am besten für Etsy?

Residential Proxies mit Sticky Sessions sind optimal für Etsy. Datacenter-IPs werden von Cloudflare fast immer blockiert. Mobile Proxies funktionieren am besten, sind aber teurer. Für die meisten POD-Research-Use-Cases reichen Residential Proxies völlig aus.

Wie finde ich Trending-Keywords auf Etsy?

Nutze Etsys Autovervollständigungs-API unter /api/v3/ajax/member/suggestions?q=SEED, iteriere durch Seed-Keywords und filtere nach dem Typ 'trending'. Alternativ kannst du die Suchergebnisseiten für verschiedene Keywords scrapen und Listing-Counts vergleichen.

Wie oft sollte ich die IP rotieren beim Etsy-Scraping?

Rotiere die IP alle 30-40 Requests oder wenn du HTTP 429/403 erhältst. Für paginierte Suchen nutze Sticky Sessions (gleiche IP für 5-10 Minuten), damit die Session konsistent bleibt. Zwischen Requests solltest du 2-4 Sekunden warten.

Kann ich echte Verkaufszahlen von Etsy-Shops scrapen?

Etsy zeigt nur grobe Verkaufszahlen als Badge (z.B. '1,234 sales'). Diese sind aufgerundet und nicht tagesaktuell, aber ausreichend für Größenordnungen und Competitive-Analyse. Exakte Tages-Verkaufszahlen sind öffentlich nicht verfügbar.

Preise und Wettbewerber verfolgen, ohne blockiert zu werden

Zuverlässige Residential-Proxys für E-Commerce-Daten. Registriere dich und hol dir saubere Daten.

Loslegen
← Zurück zum Blog