eBay scrapen mit Proxies: Praktischer Leitfaden für Listing-Daten, Auktionen & Verkäufer-Analyse

Lerne, wie du eBay-Suchergebnisse, Auktionsdaten und Verkäufer-Profile scrapest – mit funktionierendem Python-Code, CSS-Selektoren und Proxy-Strategien, die eBays Anti-Bot-Systeme umgehen.

eBay scrapen mit Proxies: Praktischer Leitfaden für Listing-Daten, Auktionen & Verkäufer-Analyse

API vs. HTML-Scraping: Wann du eBay direkt scrapen solltest

Wenn du eBay-Daten brauchst, stehen dir zwei Wege offen: die offiziellen eBay Finding- und Browse-APIs oder klassisches HTML-Scraping. Die APIs sind sauber und stabil – aber sie haben harte Limits, die für ernsthafte Marktforschung oder Reseller-Intelligence schnell zum Flaschenhals werden.

Die Finding API erlaubt typischerweise 5.000 Calls pro Tag pro App-Key. Die Browse API (Teil der Buy API-Familie) ist für Käufer-Szenarien gedacht und verlangt oft OAuth-Tokens plus ein aktives eBay-Entwicklerprogramm. Für sporadische Abfragen reicht das – für breite Preisüberwachung, Konkurrenz-Analyse oder Auktions-Tracking über Tausende von Listings pro Stunde jedoch nicht.

Deswegen greifen Teams auf HTML-Scraping zurück: keine API-Quoten, kein OAuth-Overhead, Zugriff auf alles, was im Browser sichtbar ist – inklusive Auktions-Countdowns, Verkäufer-Feedback-Scores und regionale Preisdifferenzen. Der Kompromiss: du brauchst zuverlässige Proxies, weil eBay Datacenter-IPs aggressiv blockiert.

eBay-API-Limits auf einen Blick

APITägliches Limit (Standard)Auth-AufwandDatenabdeckung
Finding API~5.000 Calls/TagApp-KeySuchergebnisse, Item-IDs
Browse API~10.000 Calls/TagOAuth + App-KeyItem-Details, Preis, Bilder
Trading API~1.500 Calls/TagOAuth + User-TokenEigene Listings, Orders
HTML-ScrapingKein festes LimitProxiesAlles sichtbare + dynamische Daten

Regel: Nutze die API für kleine, stabile Abfragen. Scalierst du über die Quoten hinaus oder brauchst du Daten, die die API nicht liefert (Auktions-Timer, Verkäufer-Feedback-Verlauf), wechsle zum Scraping mit Residential Proxies.

Die HTML-Struktur von eBay verstehen

Bevor du Code schreibst, musst du wissen, wo die Daten sitzen. eBay nutzt serverseitiges Rendering für die wichtigsten Inhalte – Glück für Scraper, weil die Daten im initialen HTML landen und nicht erst per JavaScript nachgeladen werden.

Suchergebnisse: das .s-item-Grid

Die Suchergebnisseite listet jedes Listing in einem Container mit der Klasse .s-item. Innerhalb jedes Containers findest du:

  • Titel: .s-item__title – Produktname, manchmal mit Zusätzen wie "NEW LISTING"
  • Preis: .s-item__price – formatierter Preisstring, z.B. "EUR 129,99"
  • Versand: .s-item__shipping – Versandkosten oder "Kostenloser Versand"
  • Auktions-Info: .s-item__bid-count (Gebote), .s-item__time-left (Restzeit)
  • Buy-It-Now: .s-item__purchase-option mit Text "Sofort-Kaufen"
  • Verkäufer: .s-item__seller-info – Verkäufername und Feedback
  • URL: .s-item__link – Link zur Detailseite

Listing-Detailseite

Auf der Detailseite (/itm/ITEM_ID) liegen tiefere Informationen:

  • Preis: [itemprop="price"] oder #prcIsum
  • Artikelnummer: #descItemNumber oder [itemprop="productID"]
  • Verkäufer-Feedback: .mbg (Verkäufer-Link) + .mbg-l (Feedback-Score)
  • Auktions-Timer: #vi-cdown_timeLeft – dynamischer Countdown, serverseitig initialisiert
  • Gebote: #bidBtn-Text oder .vi-bid-count

Verkäufer-Profilseite

Unter /usr/SELLER_NAME findest du:

  • Feedback-Score: .mbg-l – Zahl neben dem Stern
  • Positive-Feedback-%: #feedback_percent
  • Mitglied seit: .mbg-Bereich, Info-Label
  • Aktive Listings: .seller-item-card im "Other items"-Bereich

Proxy-Auswahl: Warum Residential für eBay Pflicht ist

eBay betreibt ein aggressives Anti-Bot-System, das Datacenter-IP-Ranges kennt und blockiert. Wenn du von einem DC-Proxy scrapst, bekommst du nach wenigen Requests CAPTCHAs, Rate-Limit-Fehler oder leere Seiten. Residential Proxies sind hier kein Luxus, sondern Voraussetzung.

Proxy-Typen im Vergleich für eBay

Proxy-TypeBay-Blockier-RisikoGeschwindigkeitBestes Einsatzgebiet
DatacenterSehr hochSchnellNicht empfohlen für eBay
Residential (rotierend)NiedrigMittelBreite Such-Scrapes, Preisüberwachung
Residential (Sticky)NiedrigMittelAuktions-Tracking, Session-basierte Scrapes
MobileSehr niedrigLangsamerHöchste Vertrauensstufe, seltene Anfragen

Geo-Targeting für regionale eBay-Domains

eBay zeigt unterschiedliche Preise, Listings und Versandoptionen je nach Standort des Nutzers. Wenn du eBay.de, eBay.co.uk oder eBay.com.au scrapen willst, musst du Proxies aus dem jeweiligen Land verwenden – sonst siehst du entweder umgeleitete Ergebnisse oder regional eingeschränkte Daten.

Mit ProxyHat kannst du das Land direkt im Benutzernamen festlegen:

# Deutschland-IP für eBay.de
http://user-country-DE:pass@gate.proxyhat.com:8080

# UK-IP für eBay.co.uk
http://user-country-GB:pass@gate.proxyhat.com:8080

# Stadtgenau: Berlin für lokalisierte Versanddaten
http://user-country-DE-city-berlin:pass@gate.proxyhat.com:8080

Für Auktions-Tracking, bei dem du über Minuten hinweg dieselbe IP brauchst, nutzt du Sticky Sessions:

# 10-Minuten-Session für Auktions-Monitoring
http://user-country-DE-session-auc456:pass@gate.proxyhat.com:8080

Python-Beispiel: eBay-Suchergebnisse scrapen und parsen

Hier ist ein vollständiges, funktionierendes Beispiel, das eBay.de nach einem Suchbegriff abfragt, die .s-item-Container parsed und strukturierte Datensätze erzeugt.

import requests
from bs4 import BeautifulSoup
from dataclasses import dataclass
from typing import List
import time
import random

PROXY_URL = "http://user-country-DE: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": "de-DE,de;q=0.9,en;q=0.5",
    "Accept": "text/html,application/xhtml+xml",
}


@dataclass
class EbayListing:
    title: str
    price: str
    shipping: str
    url: str
    bid_count: str | None
    time_left: str | None
    is_buy_it_now: bool
    seller: str


def scrape_ebay_search(query: str, max_pages: int = 3) -> List[EbayListing]:
    listings = []
    for page in range(1, max_pages + 1):
        url = f"https://www.ebay.de/sch/i.html?_nkw={query}&_pgn={page}"
        resp = requests.get(url, headers=HEADERS, proxies=PROXIES, timeout=30)
        resp.raise_for_status()

        soup = BeautifulSoup(resp.text, "html.parser")
        items = soup.select(".s-item")

        for item in items:
            title_el = item.select_one(".s-item__title")
            if not title_el or "Shop auf eBay" in title_el.text:
                continue  # Skip placeholder entries

            price_el = item.select_one(".s-item__price")
            shipping_el = item.select_one(".s-item__shipping")
            link_el = item.select_one(".s-item__link")
            bid_el = item.select_one(".s-item__bid-count")
            time_el = item.select_one(".s-item__time-left")
            bin_el = item.select_one(".s-item__purchase-option")
            seller_el = item.select_one(".s-item__seller-info")

            listings.append(EbayListing(
                title=title_el.text.strip(),
                price=price_el.text.strip() if price_el else "N/A",
                shipping=shipping_el.text.strip() if shipping_el else "N/A",
                url=link_el["href"] if link_el else "",
                bid_count=bid_el.text.strip() if bid_el else None,
                time_left=time_el.text.strip() if time_el else None,
                is_buy_it_now=bin_el is not None and "Sofort" in bin_el.text,
                seller=seller_el.text.strip() if seller_el else "N/A",
            ))

        # Rate limiting: 2-5 Sekunden zwischen Seiten
        time.sleep(random.uniform(2, 5))

    return listings


# Ausführung
results = scrape_ebay_search("mechanische tastatur", max_pages=2)
for r in results[:5]:
    print(f"{r.title[:50]}... | {r.price} | Gebote: {r.bid_count} | BIN: {r.is_buy_it_now}")

Beispielausgabe (gekürzt)

Logitech G915 TKL Wireless... | EUR 89,99 | Gebote: None | BIN: True
Razer Huntsman V2 Analog... | EUR 124,90 | Gebote: 3 Gebote | BIN: False
Corsair K100 RGB... | EUR 64,50 | Gebote: 7 Gebote | BIN: False

Auktionen handhaben: Timer, Gebote und Sofort-Kaufen

Auktionsdaten sind besonders wertvoll für Reseller, weil sie Echtzeit-Marktdynamik zeigen. Die Herausforderung: Auktions-Timer werden clientseitig per JavaScript heruntergezählt, aber der Startwert kommt vom Server und steht im initialen HTML.

Strategien für Auktions-Scraping

  1. Einmaliger Snapshot: Scrape die Suchergebnisseite und extrahiere .s-item__time-left plus .s-item__bid-count. Gut für Trend-Analysen über viele Listings.
  2. Polling mit Sticky Sessions: Nutze eine Session-IP und frage die Detailseite alle 30–60 Sekunden ab. Der Countdown-Wert im HTML wird serverseitig aktualisiert.
  3. Endpreis-Erfassung: Scrape abgeschlossene Listings unter /sch/i.html?_nkw=QUERY&LH_Complete=1&LH_Sold=1, um tatsächliche Verkaufspreise zu erhalten.

Hier ein Snippet für abgeschlossene Listings:

def scrape_completed_listings(query: str) -> List[dict]:
    """Scrape abgeschlossene eBay-Listings für Preis-Trendanalyse."""
    url = (
        f"https://www.ebay.de/sch/i.html?"
        f"_nkw={query}&LH_Complete=1&LH_Sold=1&_pgn=1"
    )
    resp = requests.get(url, headers=HEADERS, proxies=PROXIES, timeout=30)
    soup = BeautifulSoup(resp.text, "html.parser")

    results = []
    for item in soup.select(".s-item"):
        title = item.select_one(".s-item__title")
        price = item.select_one(".s-item__price")
        sold_status = item.select_one(".s-item__purchase-option")

        if title and price and "Shop auf eBay" not in title.text:
            results.append({
                "title": title.text.strip(),
                "sold_price": price.text.strip(),
                "sold": sold_status is not None and "verkauft" in sold_status.text.lower(),
            })
    return results

# Verwendung
completed = scrape_completed_listings("airpods pro 2")
print(f"{len(completed)} verkaufte Listings gefunden")

Verkäufer-Analyse: Feedback, Kategorien und Cross-Listing-Muster

Für Competitive Intelligence ist die Verkäufer-Ebene oft wertvoller als einzelne Listings. Du willst wissen: Wer verkauft am meisten? Welche Kategorien dominieren sie? Wie cross-listen sie Produkte?

Schritt-für-Schritt-Verkäufer-Analyse

  1. Verkäufer-IDs aus Suchergebnissen sammeln – extrahiere den Verkäufername aus .s-item__seller-info oder der Detailseite.
  2. Verkäufer-Profil scrapen – rufe /usr/SELLER_NAME auf und extrahiere Feedback-Score und Positive-Rate.
  3. Andere Listings des Verkäufers erfassen – der "Andere Artikel"-Bereich zeigt aktive Listings desselben Verkäufers.
  4. Kategorien aggregieren – zähle, in welchen Kategorien ein Verkäufer aktiv ist, um sein Geschäftsmodell zu verstehen.
def scrape_seller_profile(seller_name: str) -> dict:
    """Extrahiere Verkäufer-Metadaten vom Profil."""
    url = f"https://www.ebay.de/usr/{seller_name}"
    resp = requests.get(url, headers=HEADERS, proxies=PROXIES, timeout=30)
    soup = BeautifulSoup(resp.text, "html.parser")

    feedback_score_el = soup.select_one(".mbg-l")
    feedback_pct_el = soup.select_one("#feedback_percent")
    member_since_el = soup.select_one(".mbg .info")

    # Aktive Listings des Verkäufers
    seller_items = []
    for card in soup.select(".seller-item-card"):
        title_el = card.select_one(".seller-item-card__title")
        price_el = card.select_one(".seller-item-card__price")
        if title_el and price_el:
            seller_items.append({
                "title": title_el.text.strip(),
                "price": price_el.text.strip(),
            })

    return {
        "seller": seller_name,
        "feedback_score": feedback_score_el.text.strip() if feedback_score_el else "N/A",
        "positive_pct": feedback_pct_el.text.strip() if feedback_pct_el else "N/A",
        "member_since": member_since_el.text.strip() if member_since_el else "N/A",
        "active_listings_count": len(seller_items),
        "sample_listings": seller_items[:5],
    }

# Verwendung
profile = scrape_seller_profile("topseller_electronics")
print(f"Feedback: {profile['feedback_score']} | Positiv: {profile['positive_pct']}")
print(f"Aktive Listings: {profile['active_listings_count']}")

Cross-Listing-Muster erkennen

Um zu verstehen, ob ein Verkäufer in mehreren Nischen aktiv ist, scrapst du die Suchergebnisse für verschiedene Keywords, sammelst die Verkäufer-Namen und zählst, wie oft jeder Verkäufer in welchen Suchergebnissen auftaucht. Das ergibt eine Verkäufer-Kategorie-Matrix, die du in eine Pivot-Tabelle oder Heatmap umwandeln kannst.

eBays Anti-Bot-Technologie und wie du sie umgehst

eBay nutzt mehrere Verteidigungslinien:

  • IP-Reputation: Datacenter-IP-Ranges werden direkt blockiert oder mit CAPTCHAs belegt.
  • Rate-Limiting: Mehr als ~100 Requests pro Minute von derselben IP lösen Temp-Blocks aus (HTTP 429 oder leere Seiten).
  • Browser-Fingerprinting: eBay prüft JavaScript-Fähigkeiten, Canvas-Rendering und TLS-Fingerabdrücke. Reine HTTP-Requests ohne passenden User-Agent fallen auf.
  • Verhaltensanalyse: Seitenaufrufe in zu regelmäßigen Intervallen oder zu schnelle Navigation durch Paginierung werden erkannt.

Gegenmaßnahmen:

  1. Residential Proxies mit Rotation – neue IP pro Request oder alle 5 Requests.
  2. Realistische User-Agent-Strings – rotiere zwischen aktuellen Chrome/Firefox-Versionen.
  3. Zufällige Verzögerungen – 2–8 Sekunden zwischen Requests, nicht konstant.
  4. Session-Konsistenz wo nötig – Sticky Sessions für Auktions-Tracking, damit die IP-Wechsel nicht auffallen.

Node.js-Beispiel: eBay mit SOCKS5 scrapen

Für Node.js-Umgebungen bietet SOCKS5 manchmal bessere Kompatibilität. Hier ein Minimalbeispiel mit socks-proxy-agent:

const axios = require('axios');
const { SocksProxyAgent } = require('socks-proxy-agent');

const agent = new SocksProxyAgent(
  'socks5://user-country-DE:PASSWORD@gate.proxyhat.com:1080'
);

async function fetchEbayPage(url) {
  const resp = await axios.get(url, {
    httpsAgent: agent,
    headers: {
      'User-Agent':
        'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) ' +
        'AppleWebKit/537.36 (KHTML, like Gecko) ' +
        'Chrome/125.0.0.0 Safari/537.36',
      'Accept-Language': 'de-DE,de;q=0.9',
    },
    timeout: 30000,
  });
  return resp.data;
}

// Verwendung
fetchEbayPage('https://www.ebay.de/sch/i.html?_nkw=mechanische+tastatur')
  .then(html => console.log('HTML-Länge:', html.length))
  .catch(err => console.error('Fehler:', err.message));

curl: Schneller Test mit ProxyHat

Bevor du ein volles Skript schreibst, teste die Verbindung manuell:

# HTTP-Proxy
curl -x http://user-country-DE:PASSWORD@gate.proxyhat.com:8080 \
  -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/125.0.0.0" \
  "https://www.ebay.de/sch/i.html?_nkw=iphone+15" 2>/dev/null | grep -c 's-item'

# SOCKS5-Proxy
curl -x socks5://user-country-DE:PASSWORD@gate.proxyhat.com:1080 \
  -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/125.0.0.0" \
  "https://www.ebay.de/sch/i.html?_nkw=iphone+15" 2>/dev/null | grep -c 's-item'

Wenn die Ausgabe eine Zahl > 0 liefert, funktioniert die Verbindung und du siehst Suchergebnisse. Bei 0 oder einer CAPTCHA-Seite musst du den Proxy-Typ oder die Geo-Einstellung prüfen.

Ethische und rechtliche Überlegungen

eBays Terms of Use verbieten automatisiertes Scraping ausdrücklich. In der Praxis scrapen Teams trotzdem – aber sie sollten dabei verantwortungsvoll vorgehen:

  • Respektiere robots.txt: Prüfe https://www.ebay.de/robots.txt für gesperrte Pfade.
  • Rate-Limits einhalten: Auch mit Proxies – nicht mehr als 1 Request pro 2–3 Sekunden pro IP.
  • Keine persönlichen Daten speichern: Verkäufer-Namen sind geschäftlich, aber vermeide die Speicherung von Käufer-Daten unter DSGVO/GDPR.
  • Daten nur für legitime Zwecke: Marktforschung und Preisvergleich sind vertretbar; Betrug oder Manipulation nicht.

Key Takeaways

  • Die eBay-API reicht für kleine Abfragen – für breite Scrapes brauchst du HTML-Extraktion mit Residential Proxies.
  • Die .s-item-Klasse ist dein Haupteinstiegspunkt für Suchergebnisse; Detailseiten liefern Auktions-Timer und Verkäufer-Feedback.
  • Residential Proxies sind Pflicht – Datacenter-IPs werden auf eBay innerhalb weniger Requests blockiert.
  • Geo-Targeting ist entscheidend für regionale Domains wie eBay.de und eBay.co.uk – die Preise und Listings unterscheiden sich je nach Standort.
  • Auktionsdaten erfordern Sticky Sessions für Polling; abgeschlossene Listings liefern tatsächliche Verkaufspreise.
  • Verkäufer-Analyse (Feedback, Kategorien, Cross-Listing) liefert strategische Insights, die die API nicht bietet.

Fazit und nächste Schritte

eBay scrapen ist kein Hexenwerk – aber es erfordert die richtige Infrastruktur. Mit Residential Proxies aus ProxyHat, realistischen Headers und sauberem Parsing der .s-item-Struktur bekommst du zuverlässig Zugriff auf Suchergebnisse, Auktionsdaten und Verkäufer-Profile. Starte klein mit einem curl-Test, skaliere dann mit dem Python- oder Node.js-Beispiel, und passe die Rate-Limits an dein Volumen an.

Bereit loszulegen? Hol dir deine ProxyHat-Zugangsdaten unter ProxyHat Pricing und teste die Beispiele aus diesem Artikel. Für tiefergehende Scraping-Strategien sieh dir unseren Guide zu Web-Scraping-Best-Practices und die Web-Scraping-Anwendungsfälle an.

Bereit loszulegen?

Zugang zu über 50 Mio. Residential-IPs in über 148 Ländern mit KI-gesteuerter Filterung.

Preise ansehenResidential Proxies
← Zurück zum Blog