Anleitung · Serverlogs · JavaScript · GEO

Was der Crawler wirklich sieht: Serverlogs und der Blick ohne JavaScript

Ein Score sagt, was ein Crawler auf einer Website finden würde. Ob überhaupt einer vorbeikommt und was er tatsächlich mitnimmt, zeigen zwei alte Werkzeuge: die eigenen Serverlogs und ein Abruf ohne JavaScript.

Andreas Reuter · Oktober 2026 · 6 Min. Lesedauer

Ein Score ist eine Behauptung über eine Website. Er sagt: Wenn ein Crawler hier vorbeikommt, findet er sauberes HTML, eine erlaubende robots.txt, verständliches Markup. Was er nicht sagen kann, ist, ob überhaupt jemand vorbeikommt, und was dieser Jemand tatsächlich mitnimmt. Dafür gibt es zwei Werkzeuge, die älter sind als jede KI-Debatte und trotzdem kaum jemand nutzt: die eigenen Serverlogs und einen Abruf der Seite, bei dem kein JavaScript ausgeführt wird.

Dieser Beitrag beschreibt, wie wir beides kombinieren. Es ist eine Anleitung, keine Studie. Die Befehle laufen auf einem gewöhnlichen Nginx-Server und brauchen nichts, was nicht ohnehin installiert ist.

Warum JavaScript hier die entscheidende Grenze ist

Moderne Websites liefern oft nur eine leere Hülle aus und bauen den eigentlichen Inhalt erst im Browser per JavaScript zusammen. Für Menschen macht das keinen Unterschied. Für die Crawler hinter ChatGPT und Claude macht es den ganzen Unterschied.

Die belastbarste Messung dazu stammt von Vercel und MERJ aus dem Dezember 2024. Sie haben den Crawler-Verkehr auf Vercels Netzwerk ausgewertet, in einem einzigen Monat waren das 569 Millionen Abrufe von GPTBot und 370 Millionen von ClaudeBot. Das Ergebnis war eindeutig: Keiner der großen KI-Crawler führte JavaScript aus, weder die drei Bots von OpenAI noch ClaudeBot. Bemerkenswert ist das Detail dahinter. GPTBot lud in rund 11,5 Prozent seiner Abrufe JavaScript-Dateien herunter, ClaudeBot in knapp 24 Prozent, aber keiner von beiden führte sie aus. Die Ausnahme ist Gemini, das auf Googles Crawling-Infrastruktur aufsetzt und damit rendert.

Die Studie ist knapp zwei Jahre alt, und Crawler ändern sich. Wir haben keine neuere Messung gefunden, die ihr widerspricht, aber genau deshalb lohnt es sich, nicht auf fremde Zahlen zu vertrauen, sondern die eigene Seite selbst zu prüfen.

Schritt eins: Die Seite so abrufen, wie ein Crawler sie sieht

Der einfachste Test ist ein Abruf mit curl. Curl führt kein JavaScript aus, es holt genau das HTML, das der Server ausliefert. Damit der Server sich so verhält wie gegenüber dem echten Bot, geben wir den User-Agent von GPTBot mit:

curl -s -A "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko); compatible; GPTBot/1.2; +https://openai.com/gptbot" \
  https://example.com/meine-seite > roh.html

Dann suchen wir in dieser Datei nach einem Satz, der im Hauptinhalt der Seite steht, am besten aus der Mitte des Textes, nicht aus der Überschrift:

grep -c "ein Satz aus der Mitte des Artikels" roh.html

Eine Null heißt: Dieser Text existiert für GPTBot und ClaudeBot nicht. Er wird erst im Browser erzeugt.

Für einen gröberen Vergleich lässt sich dieselbe Seite einmal mit einem Headless-Browser rendern und die Textmenge gegenüberstellen:

chromium --headless --dump-dom https://example.com/meine-seite > gerendert.html

sed 's/<[^>]*>//g' roh.html | wc -w
sed 's/<[^>]*>//g' gerendert.html | wc -w

Die Zählung ist unsauber, sie zählt auch Inline-Skripte und Stil-Angaben mit. Aber wenn die erste Zahl bei 300 liegt und die zweite bei 3.000, braucht man keine Präzision mehr.

Schritt zwei: In den Logs nachsehen, wer tatsächlich kommt

Der curl-Test zeigt, was ein Crawler sehen würde. Die Logs zeigen, ob er da war, welche Seiten er wollte und was er bekommen hat. Zuerst filtern wir alle Zeilen heraus, deren User-Agent zu einem bekannten KI-Crawler gehört. Der Befehl liest auch rotierte und komprimierte Logs mit:

zcat -f /var/log/nginx/access.log* \
  | grep -E 'GPTBot|OAI-SearchBot|ChatGPT-User|ClaudeBot|Claude-SearchBot|Claude-User|PerplexityBot|CCBot' \
  > ki-bots.log

Ein Name, der in dieser Liste fehlt, ist Google-Extended. Das ist kein eigener Crawler, sondern nur ein Steuerungswort für die robots.txt. Google crawlt weiterhin als Googlebot, und in den Logs taucht Google-Extended deshalb nie auf.

Wie viele Abrufe pro Bot:

grep -oE 'GPTBot|OAI-SearchBot|ChatGPT-User|ClaudeBot|Claude-SearchBot|Claude-User|PerplexityBot|CCBot' ki-bots.log \
  | sort | uniq -c | sort -rn

Und welche Pfade sie mit welchem Statuscode und welcher Antwortgröße abgerufen haben. Das Beispiel setzt das Standardformat combined von Nginx voraus:

awk -F'"' '{split($2,r," "); split($3,s," "); print s[1], s[2], r[2]}' ki-bots.log \
  | sort | uniq -c | sort -rn | head -30

Die Spalten sind Anzahl, Statuscode, ausgelieferte Bytes und Pfad. Viele 404er heißen, dass Crawler alte oder falsche URLs aufrufen, oft aus einer veralteten Sitemap. Viele Abrufe von .js-Dateien sagen nichts darüber, ob der Bot sie ausführt. Das hat die Vercel-Studie gezeigt.

Schritt drei: Echte Bots von Verkleidungen unterscheiden

Ein User-Agent ist eine Selbstauskunft. Jeder kann sich GPTBot nennen, das dauert genau so lange, wie es dauert, den curl-Befehl oben abzutippen. Unsere eigenen Tests aus Schritt eins landen ebenfalls in diesen Logs. Wer Zahlen veröffentlichen will, muss sie herausrechnen.

OpenAI veröffentlicht die IP-Bereiche seiner Crawler als JSON-Dateien, für GPTBot unter openai.com/gptbot.json, für die anderen Bots in eigenen Dateien. Ein kurzes Python-Skript prüft, welche Adressen in unseren Logs wirklich dazugehören:

curl -s https://openai.com/gptbot.json -o gptbot.json
grep 'GPTBot' ki-bots.log | awk '{print $1}' | sort -u > gptbot-ips.txt
import ipaddress, json

netze = [ipaddress.ip_network(p.get("ipv4Prefix") or p.get("ipv6Prefix"))
         for p in json.load(open("gptbot.json"))["prefixes"]]

for zeile in open("gptbot-ips.txt"):
    ip = ipaddress.ip_address(zeile.strip())
    echt = any(ip in n for n in netze)
    print(ip, "echt" if echt else "NICHT in den veroeffentlichten Bereichen")

Nicht jeder Anbieter macht es einem so leicht. Für Crawler ohne veröffentlichte Bereiche bleibt die Rückwärtsauflösung per DNS oder, wenn auch die fehlt, nur die ehrliche Feststellung, dass sich die Herkunft nicht prüfen lässt.

Was die Kombination zeigt, was keiner der beiden Teile allein zeigt

Erst zusammen werden die beiden Methoden aussagekräftig. Die Logs verraten, welche Seiten GPTBot tatsächlich abruft und wie viele Bytes er dafür bekommt. Der curl-Test verrät, wie viel Inhalt in diesen Bytes steckt. Wenn ein Bot eine Produktseite zwanzigmal im Monat abholt, jedes Mal 4 Kilobyte bekommt, und der curl-Test für genau diese Seite eine leere Hülle zeigt, dann ist die Diagnose klar: Der Crawler ist willkommen, er kommt regelmäßig, und er geht jedes Mal mit leeren Händen.

Das kann kein Score von außen feststellen, auch unserer nicht. Ein Analysewerkzeug sieht die Seite, aber nicht den Server. Es kann prüfen, ob die robots.txt GPTBot hereinlässt. Ob GPTBot dann auch kommt, steht nur in den Logs.

Der naheliegende Einwand

Man kann einwenden, dass das alles für die meisten Betreiber zu viel Aufwand ist. Wer auf einem Baukasten-System sitzt, hat keinen Zugriff auf Nginx-Logs, und wer ihn hat, will nicht mit awk hantieren. Das stimmt. Aber der erste Schritt, der curl-Test, braucht keinen Serverzugang und dauert eine Minute. Er allein beantwortet schon die wichtigste Frage, ob der Inhalt ohne JavaScript überhaupt da ist. Die Logs sind die Vertiefung für die, die wissen wollen, ob ihre Annahmen über Crawler mit der Wirklichkeit übereinstimmen. Unsere eigenen haben zum Beispiel gezeigt, dass von 1.252 KI-Bot-Abrufen in drei Wochen kein einziger der llms.txt galt, ganz gleich, was das GEO-Marketing über diese Datei verspricht.

Die Erfahrung dahinter ist schlicht. Zwischen dem, was man über seine Website glaubt, und dem, was in den Logs steht, liegt meistens eine Überraschung. Es lohnt sich, sie selbst zu finden, bevor ein Sprachmodell sie stillschweigend für einen findet.

— Andreas Kurt Peter Reuter

Eigene Website prüfen →