Die 10.000-Ergebnisse-Grenze: Wie Sie über Paginierungslimits hinaus scrapen
Sie bauen einen Scraper für eine Suchergebnisseite. Er funktioniert. Sie paginieren: Seite 1, Seite 2, Seite 10, Seite 40. Neue Einträge kommen weiter. Und dann, irgendwo um Seite 65, versiegen die Ergebnisse. Die Seite lädt noch. Das Layout ist intakt. Kein CAPTCHA, keine Sperrmeldung. Es gibt einfach keine weiteren Angebote mehr, obwohl der eigene Header der Website “48.000+ Ergebnisse” anzeigt.
Sie wurden nicht gesperrt. Sie sind auf eine Ergebnisgrenze gestoßen. Fast jede große Suchoberfläche hat eine, und wenn Sie sie nicht einplanen, endet Ihr Datensatz still bei einem Bruchteil dessen, was tatsächlich vorhanden ist. Dieser Beitrag erklärt, was diese Grenze ist, warum es sie gibt, wie Sie sie von einer Sperre unterscheiden und die einzige zuverlässige Technik, um trotzdem den vollständigen Satz zu erfassen: die Partitionierung des Abfrageraums.
Wie die Ergebnisgrenze aussieht
Das Symptom ist eindeutig. Flache Seiten liefern frische Daten. Tiefe Seiten liefern ein leeres Raster, oder wiederholen dieselbe letzte Seite, oder leiten zu Seite 1 zurück. Und das Entscheidende: Die Antwort ist eine gültige Seite. Statuscode 200. Korrekter Titel. Korrekte Navigation. Nur ohne Einträge.
Meist definieren zwei Zahlen die Grenze:
- Ein maximaler Offset, oft 10.000. Viele Websites paginieren mit einem
offsetoder einer Seitenzahl, die aufSeite * Seitengrößeabgebildet wird. Sobald deroffset~10.000 überschreitet, weigert sich das Backend, tiefer zu gehen. - Ein Maximum an Ergebnissen pro Abfrage, was dieselbe Grenze von der anderen Seite betrachtet ist. Bei einer Seitengröße von 240 erhalten Sie etwa
10.000 / 240 = 41nutzbare Seiten. Bei 50 erhalten Sie 200 Seiten. So oder so landen Sie nahe 10.000 Einträgen.
Sie sehen das bei großen E-Commerce-Marktplätzen, Jobbörsen, Immobilienportalen und allgemeinen Suchmaschinen. Es ist kein Fehler. Es ist eine bewusste Obergrenze.
Warum Websites tiefe Paginierung begrenzen
Hier steckt keine Verschwörung dahinter. Die Grenze ist eine Performance-Entscheidung, und sie zu verstehen zeigt Ihnen, wie Sie sie überwinden.
Die meisten Such-Backends nutzen Offset-Paginierung. Um Seite 400 auszuliefern, muss die Datenbank die ersten 399 Ergebnisseiten durchlaufen und dann den nächsten Ausschnitt zurückgeben. Diese “Durchlauf”-Arbeit wächst linear mit der Tiefe. Seite 1 ist billig. Seite 4.000 ist teuer. Um tiefe Seiten zurückzugeben, muss die Engine eine riesige Kandidatenmenge sortieren und scannen, und das für jeden Crawler, der das Ende durchläuft. Also ziehen die Betreiber eine Linie. Jenseits von Offset 10.000 wird die Anfrage einfach abgelehnt oder liefert leer zurück.
Suchmaschinen wie Elasticsearch machen das explizit. Ihr index.max_result_window hat einen Standardwert von genau 10.000, und die Dokumentation empfiehlt, search_after oder die Scroll-API statt tiefer from/size-Paginierung zu verwenden. Wenn eine Website auf diesem Stack aufbaut, wird die 10.000er-Grenze direkt von der Engine geerbt.
Die wichtige Erkenntnis: Die Grenze gilt für eine einzelne Abfrage, nicht für den gesamten Katalog. Der Katalog hat Millionen Einträge. Jede einzelne Abfrage kann nur die ersten 10.000 davon offenlegen. Die Lösung besteht also nicht darin, härter zu paginieren. Die Lösung besteht darin, mehr und kleinere Fragen zu stellen.
Zuerst: Bestätigen, dass es eine Grenze und keine Sperre ist
Bevor Sie Ihren Crawler umbauen, schließen Sie eine sanfte Sperre aus. Leere tiefe Seiten und heimliche Sperren können von außen identisch aussehen, also prüfen Sie drei Dinge:
- Ist die Seite strukturell gültig? Eine echt begrenzte Seite hat den normalen Header, Footer und die “keine Ergebnisse”-Meldungen der Website. Eine Sperre liefert oft eine abgespeckte Seite, eine Challenge oder ein Interstitial. Falls Sie unsicher sind, wie man das unterscheidet: Unser Beitrag über das Erkennen sanfter Sperren behandelt die Signale.
- Reproduziert sich die Grenze? Fordern Sie dieselbe tiefe Seite dreimal an. Eine Grenze ist deterministisch: Seite 70 ist immer leer. Eine Sperre ist oft sporadisch und verschwindet nach einer Pause oder einer neuen Sitzung.
- Funktioniert eine flachere Seite in derselben Sitzung noch? Wenn Seite 5 Daten liefert, Seite 70 aber nicht, mit denselben Cookies und Headern, dann haben Sie es mit einer Grenze zu tun, nicht mit einer IP-Sperre.
Sobald Sie bestätigt haben, dass es eine Grenze ist, hören Sie auf, sie überwinden zu wollen. Keine Menge an Proxys oder Wiederholungsversuchen bewegt ein hartes Offset-Limit.
Die Lösung: Den Abfrageraum partitionieren
Die ganze Technik besteht aus einer einzigen Idee. Teilen Sie den Katalog in Stücke, die klein genug sind, damit jedes weniger als 10.000 Ergebnisse enthält, scrapen Sie jedes Stück vollständig, und führen Sie dann zusammen und entfernen Duplikate. Jede große Suchoberfläche bietet Ihnen Filter, und jeder Filter ist ein Messer, mit dem Sie schneiden können.
Nach Kategorie aufteilen
Der natürlichste Schnitt. Statt nach “Laptops” zu suchen (500.000 Ergebnisse, auf 10.000 begrenzt), suchen Sie jede Unterkategorie: “Gaming-Laptops”, “Business-Laptops”, “Chromebooks” und so weiter. Kategoriefilter werden fast immer als URL-Parameter offengelegt, was das Iterieren trivial macht.
Nach Preisspanne aufteilen
Der Preis ist eine saubere numerische Achse. Die meisten Suchoberflächen akzeptieren einen Mindest- und Höchstpreis. Durchlaufen Sie den Bereich in Spannen:
def preisspannen(lo, hi, schritt):
kante = lo
while kante < hi:
yield (kante, min(kante + schritt, hi))
kante += schritt
# 0-25, 25-50, 50-75, ...
for niedrig, hoch in preisspannen(0, 1000, 25):
scrape_abfrage(preis_min=niedrig, preis_max=hoch)
Wenn eine einzelne Spanne immer noch mehr als 10.000 Ergebnisse liefert, teilen Sie sie weiter auf. Schmale Spannen im unteren Bereich, wo sich das Angebot ballt, und breitere Spannen im oberen.
Nach Zeitfenster aufteilen
Für alles, was nach Aktualität geordnet ist, wie Stellenangebote, Nachrichten oder neu eingestellte Artikel, teilen Sie nach Zeit auf. Fragen Sie “in den letzten 24 Stunden veröffentlicht” ab, gehen Sie einen Tag zurück, wiederholen Sie. Das Aufteilen nach Datum hat einen Bonus: Es verwandelt einen einmaligen Crawl in einen wartbaren, inkrementellen. Nach dem ersten vollständigen Durchlauf ziehen Sie nur noch das neueste Fenster.
Nach Standort aufteilen
Region, Land, Stadt oder Postleitzahl. Diese Achse funktioniert gut bei Marktplätzen und Verzeichnissen, bei denen dieselbe Abfrage an verschiedenen Standorten weitgehend unterschiedliches Angebot liefert. Gehen Sie aber nicht davon aus, dass die Stücke disjunkt sind. Derselbe Verkäufer oder dasselbe Angebot kann in mehreren Regionen auftauchen, weshalb der Deduplizierungsschritt weiter unten wichtig ist.
Achsen kombinieren, wenn eine nicht reicht
Wenn die Kategorie allein die Grenze immer noch sprengt, kombinieren Sie Achsen: Kategorie mal Preisspanne, oder Standort mal Zeitfenster. Jede zusätzliche Achse vervielfacht Ihre Anzahl an Stücken, verkleinert aber jedes unter die Obergrenze. Das Ziel ist einfach: Keine einzelne Abfrage sollte mehr als ~10.000 Ergebnisse liefern.
Über Stücke hinweg deduplizieren
Überlappende Stücke bringen dieselben Einträge erneut hervor. Sie brauchen einen stabilen Identitätsschlüssel und ein Set bereits gesehener Elemente. Bevorzugen Sie den permanenten Bezeichner der Website selbst, meist in der Element-URL eingebettet, gegenüber allem Kosmetischen wie einem Titel oder einem Anzeigenamen, der sich zwischen Anfragen ändern kann.
gesehen = set()
ergebnisse = []
for stueck_abfrage in stuecke_bauen():
for item in scrape_alle_seiten(stueck_abfrage):
item_id = id_extrahieren(item["url"]) # stabil, aus der URL
if item_id in gesehen:
continue
gesehen.add(item_id)
ergebnisse.append(item)
Halten Sie das “gesehen”-Set über Läufe hinweg persistent, wenn Sie nach einem Zeitplan scrapen. So überspringt ein inkrementeller Durchlauf, was Sie bereits haben, und Ihr Anfragebudget fließt in wirklich neue Einträge.
Achten Sie auf den Grenzertrag
Partitionierung ist mächtig, aber nicht umsonst. Jedes Stück kostet Anfragen, und Stücke überlappen sich, also zahlen Sie für Duplikate. Verfolgen Sie, wie viele neue Einträge jedes Stück beiträgt. Wenn ein Stück fast nichts liefert, das Sie nicht schon gesehen haben, sind Sie nahe an der Sättigung und können aufhören. Diese “Aufhören, wenn versiegt”-Regel bewahrt Sie davor, sich durch Tausende fast leerer Abfragen zu mahlen, um die letzte Handvoll Long-Tail-Einträge zu jagen. Für die meisten Projekte kostet das Erfassen des Großteils des Katalogs einen Bruchteil dessen, was die vollständige Abdeckung jedes Einzeleintrags kosten würde.
Seien Sie auch sanft. Tiefe Suchseiten gehören zu den schwersten, die eine Website rendert, und sie parallel zu hämmern ist der schnellste Weg, einen sauberen Crawl in eine Welle von 503-Fehlern zu verwandeln. Halten Sie die Parallelität bei diesen Endpunkten moderat und lassen Sie die Stücke, nicht rohe Parallelität, die Skalierung übernehmen.
Häufige Fragen
Ist die Grenze immer 10.000? Nein, aber es ist der häufigste Wert, weil es der Standardwert von Elasticsearch ist. Manche Websites begrenzen auf 1.000, andere auf 25.000. Messen Sie sie: Suchen Sie per binärer Suche die Tiefe, bei der die Ergebnisse leer werden, und gestalten Sie die Stücke so, dass sie komfortabel unter dieser Zahl bleiben.
Kann ich eine API nutzen, um die Grenze zu vermeiden?
Manchmal. Cursor-basierte APIs (search_after, Scroll-Tokens, “nächste Seite”-Cursor) leiden nicht unter dem Offset-Problem, also bevorzugen Sie eine dokumentierte API mit Cursor-Paginierung, wenn es sie gibt. Aber die meisten öffentlichen APIs wenden dieselbe Ergebnisobergrenze pro Abfrage an, sodass Sie oft trotzdem partitionieren müssen. Prüfen Sie stets die Nutzungsbedingungen, bevor Sie eine API für die Massensammlung verwenden.
Warum nicht einfach die Seitengröße erhöhen? Weil die Grenze für die Gesamtergebnisse pro Abfrage gilt, nicht für die Seitenzahl. Eine größere Seitengröße bringt Sie mit weniger Anfragen an die Obergrenze, aber die Obergrenze bewegt sich nicht. Größere Seiten lohnen sich weiterhin, um das Anfragevolumen zu senken, erwarten Sie nur nicht, dass sie mehr Daten freischalten.
Woher weiß ich, dass ich alles habe? Sicher wissen Sie es nicht. Nutzen Sie das Grenzertrags-Signal: Wenn neue Stücke keine Einträge mehr hinzufügen und unabhängige Achsen (etwa Kategorie-Aufteilung und Preis-Aufteilung) auf dieselbe Gesamtzahl konvergieren, haben Sie starke Hinweise auf eine nahezu vollständige Abdeckung.
Alles zusammengeführt
Ergebnisgrenzen sind eine Tatsache, wenn Sie im großen Maßstab scrapen. Der Instinkt, härter zu paginieren oder mehr Proxys auf eine tiefe Seite zu werfen, ist verschwendete Mühe, denn das Limit ist strukturell, nicht defensiv. Der zuverlässige Zug ist Partitionierung: Schneiden Sie den Katalog nach Kategorie, Preis, Datum und Standort, bis jede Abfrage unter die Obergrenze passt, und führen Sie dann mit einem stabilen Schlüssel zusammen und deduplizieren.
Das Einzige, was Partitionierung nicht löst, ist überhaupt erst jede einzelne Seite zu bekommen. Tiefe Suchseiten sind genau dort, wo sich Anti-Bot-Systeme konzentrieren, und ein Crawler, der Hunderte schwerer Render-Anfragen abfeuert, wird Aufmerksamkeit erregen, egal wie sauber Sie schneiden. Wenn Sie die Proxy-Rotation und das Browser-Fingerprinting, die zuverlässiges Seitenabrufen erfordert, lieber nicht selbst pflegen möchten, übernimmt ScrapeUnblocker diese Schicht und gibt Ihnen das gerenderte HTML zurück, damit Sie sich auf die Aufteilungslogik konzentrieren können. So oder so ist die Strategie dieselbe: Hören Sie auf, gegen die Grenze zu kämpfen, und fangen Sie an, das Problem zu teilen.
ScrapeUnblocker kostenlos testen
Über 95 % Erfolgsquote · ab 0,55 € pro 1.000 Aufrufe · 500 kostenlose Anfragen bei der Registrierung.