In den letzten Tagen kamen wiederholt Nachrichten von euch: „Mein Otto-Tracker hängt seit Tagen auf demselben Preis”, „Adidas zeigt 6 € obwohl der Artikel 70 € kostet”, „Warum springt der Preis nicht?”. Die Antwort ist in allen drei Fällen dieselbe — und sie hat nichts mit unserem Scraper zu tun, sondern damit, dass uns der Shop bewusst nicht reinlässt. Hier ist, was wirklich passiert, und was wir vor ein paar Tagen daran gefixt haben.
Wie ein Preis bei uns überhaupt aktualisiert wird
Wenn dein Tracker fällig wird, läuft im Hintergrund eine kleine Pipeline ab:
- HTTP-Anfrage — wir holen die Produktseite wie ein normaler Browser, lesen den Quellcode
- Preis-Erkennung — unser ML-Modell sucht in der Seite nach dem Preis, vergleicht mit dem Referenzpreis, bestätigt das Ergebnis
- Headless-Browser-Fallback — wenn der schnelle HTTP-Pfad nichts findet (zu viel JavaScript, dynamische Preise), rendern wir die Seite in einem echten Browser auf einem separaten Server
Bei den allermeisten Shops — Amazon, IKEA, MediaMarkt, Cyberport, Zalando, hsnstore und ein paar tausend weiteren — funktioniert das einwandfrei. Du merkst die Pipeline nie, der Preis ist einfach aktuell.
Was bei Otto und Adidas anders ist
Otto und Adidas (und ein paar andere große Marken) haben in den letzten Monaten eine besondere Art von Schutz eingebaut: kommerzielle Bot-Erkennung. Konkret heißen die Anbieter Kasada (Otto) und DataDome (Adidas). Das sind keine simplen Captchas — das sind hochentwickelte Fingerprinting-Systeme, die Hunderte von Browser-Signalen auswerten (Canvas-Rendering, WebGL, Audio-Kontext, Timing-Patterns, Maus-Bewegungen) und in Sekundenbruchteilen entscheiden: Mensch oder Maschine?
Unsere Antwort ist immer dieselbe: Maschine. Das stimmt ja auch. Und dann passiert Folgendes:
Statt der echten Produktseite (typischerweise 200–400 KB HTML mit Bildern, Beschreibung, Preisen) bekommen wir eine winzige Challenge-Page zurück — bei Otto sind das genau 912 Bytes. Inhalt: ein bisschen Javascript-Initialisierung, der Hinweis dass ein Browser den Challenge lösen soll. Kein Preis, kein Produktname, nichts brauchbares.
Das eigentliche Problem war nicht die Wall — sondern unsere Reaktion
Bisher hat unser Scraper diese 912-Byte-Seiten so behandelt wie jede andere „leere” Seite: kein Preis gefunden, versuch's nochmal anders. Konkret hieß das: nach drei solchen leeren Versuchen hat das System angenommen, der Headless-Browser sei kaputt, ist auf eine andere Strategie umgeschwenkt, hat dort auch nichts gefunden, ist wieder zurückgeschwenkt, und so weiter — ein endloses Hin und Her zwischen Strategien, die alle keine Chance haben.
Aus deiner Sicht: Preis bleibt seit Tagen gleich, manchmal kommt eine „Tracker hat Probleme”-E-Mail, manchmal ein falscher Mismatch-Alarm wenn aus den 912 Bytes zufällig eine Zahl extrahiert wird (genau das war der Adidas-Fall: aus einer 403-Fehlerseite hat unser ML-Modell „6.0” rausgefischt und gemeldet — obwohl der Schuh 70 € kostet).
Was wir geändert haben
Statt blind weiterzuversuchen erkennt der Scraper jetzt die typischen Signaturen dieser Bot-Walls:
- Bei Kasada: charakteristische
KPSDK-Initialisierung,KP_UIDz-Tokens in Script-URLs, kleiner versteckter iFrame - Bei DataDome: Verweise auf
js.datadome.co,dd-captcha-container-Elemente,ddjskey-Konfiguration
Sobald eine dieser Signaturen in einer kurzen Antwort (< 10 KB) auftaucht, ist klar: das ist eine Challenge-Page, keine Produktseite. Drei direkte Konsequenzen:
- Keine Fehler-Zähler mehr — der Shop wird nicht weiter zwischen Scraping-Strategien hin- und hergeworfen, weil kein Strategie-Wechsel das Problem löst
- Keine falschen Mismatch-Alarme — wir wissen, dass es keinen echten Preis gibt, also alarmieren wir auch keinen
- Sichtbarkeit im Daily-Status — in unserem täglichen Health-Report erscheint jetzt eine Zeile
🛡️ Bot-Schutz blockt N Shops, mit Aufschlüsselung nach Anbieter
Was das für deinen Tracker bedeutet
Wenn du einen Tracker für otto.de oder adidas.de hast, der seit dem 24. Mai nicht mehr aktualisiert wurde: das liegt nicht am Tracker, sondern daran dass uns der Shop systematisch nicht reinlässt. Wir markieren das ab sofort intern sauber, du bekommst keinen „Tracker kaputt”-Alarm mehr, und der gespeicherte letzte Preis bleibt erhalten.
Es bedeutet aber auch ehrlich: solange diese Bot-Walls aktiv sind, können wir den Preis nicht aktiv tracken. Wir versuchen keine technischen Umgehungs-Tricks — die wären ein Wettrüsten ohne Ende, und die Bot-Schutz-Anbieter rollen wöchentlich Updates aus.
Was wir stattdessen vorhaben
Der saubere Weg, an Otto- und Adidas-Preise zu kommen, sind offizielle Produkt-Feeds über Affiliate-Netzwerke wie Awin. Beide Shops bieten dort tägliche XML-Feeds mit allen Produkten und Preisen an — kein Scraping, keine Bot-Walls, dafür verlässliche Daten. Wir bewerben uns gerade um Aufnahme; sobald wir freigeschaltet sind (üblicherweise 1–4 Wochen), werden Tracker für diese Shops über die Feeds bedient.
Bis dahin: ein bisschen Geduld. Und falls du dich gefragt hast, ob du was falsch gemacht hast — hast du nicht. Wir auch nicht. Manche Türen sind einfach zu.
Nebenher: Backend-Hausputz
Während wir die Bot-Walls angeschaut haben, ist uns auch aufgefallen, dass unser Backend-Container den eingebauten Chrome-Pool nie ganz aufgeräumt hat — über lange Laufzeiten gefressener RAM, irgendwann hängt das Dashboard. Wir haben deshalb zwei Dinge gemacht: ein Sicherheitsnetz, das den Container neu startet bevor er den Speicher-Cap erreicht, und (saubererer Schritt) Chrome ganz aus dem Backend rausgenommen — der laufende Browser ist jetzt nur noch im Scheduler-Container, wo er hingehört. Falls du in den letzten Tagen mal Dashboard-Hänger hattest: die sollten weg sein.
Was kommt als Nächstes
Anfang Juni steht die Affiliate-Bewerbung für die wichtigsten Shops an. Parallel dazu: persistente Browser-Sessions im Scheduler (für stabilere Preiserkennung an dynamischen Shops) und die Microsoft-Edge-Version unserer Browser-Erweiterung. Wenn du Themen oder Shops hast, die dir besonders wichtig sind — kurze Mail an [email protected].
