Automatisiertes Rank-Tracking sieht aus wie ein Cron-Job um einen API-Aufruf gewickelt, und in der ersten Woche ist es das auch. Die Probleme kommen später: zwei Durchläufe, die nicht vergleichbar sind, weil einer zu einer anderen Stunde lief, ein Tag fehlt in der Serie, den niemand bemerkt, bis ein Chart falsch aussieht, ein Alert, der auf Rauschen anspricht, und ein Kunde, der fragt, warum Ihre Zahl von seiner abweicht.
Keines davon sind Abrufprobleme. Es sind Pipeline-Probleme, und es lohnt sich, dafür zu planen, bevor man sechs Monate Daten mit Löchern hat. Hier ist der Aufbau.
Erst den Messvertrag festlegen
Bevor Sie irgendeinen Code schreiben, legen Sie die Variablen fest, die zwei Messungen vergleichbar machen, denn ein Rank ist ohne sie bedeutungslos: den Standort, das Gerät, die Sprache und ob die Suche personalisiert ist. Diese Entscheidungen werden zu Konstanten in Ihrem Job, nicht zu Optionen pro Lauf.
Der Grund ist, dass jede Drift in ihnen sich in Ihren Daten als Ranking-Bewegung zeigt, die nie stattgefunden hat. Ein Keyword, das am Montag aus einer Stadt gemessen wurde und am Dienstag aus einer anderen, wird sich scheinbar bewegen. Die vollständige Begründung finden Sie in measuring accurate keyword rankings, und die Kurzversion ist, dass Konsistenz wichtiger ist als absolute Präzision.
Schreiben Sie den Vertrag als Schema nieder, denn das ist auch das, was Sie einem Kunden geben, wenn er fragt, was Ihre Zahlen bedeuten:
# one row per keyword per market: this is the unit of measurement
TARGET = {
"keyword": "residential proxies",
"country": "de",
"city": "berlin", # optional, only where local intent matters
"language": "de",
"device": "desktop",
}
Über eine SERP API abrufen
Sie können die Sammelschicht selbst auf Proxies aufbauen oder eine API aufrufen, die geparste Ergebnisse zurückgibt. Für einen täglichen Monitoring-Job entfernt der API-Weg die zwei Wartungslasten, die tatsächlich Zeit kosten: mit Änderungen am Layout der Ergebnisseite Schritt zu halten und die Sammelinfrastruktur zu betreiben.
Eine SERP API nimmt die oben genannten Parameter und liefert strukturierte Ergebnisse zurück, sodass Ihr Job ein Request und ein Write ist, statt ein Fetch und ein Parser:
import requests, datetime as dt
def fetch_serp(t):
r = requests.get("https://serp.shifter.io/v1", timeout=45, params={
"api_key": API_KEY,
"q": t["keyword"],
"gl": t["country"], # market
"hl": t["language"], # interface language
"location": t.get("city"),
"device": t["device"],
})
r.raise_for_status()
return r.json()
Prüfen Sie die aktuellen Parameternamen anhand der API-Dokumentation, statt einem Blogbeitrag zu vertrauen, da diese sich weiterentwickeln. Die Alternative, das Sammeln selbst über residential Exits durchzuführen, wird in why accurate rank tracking requires residential proxies behandelt, und der Trade-off ist Kontrolle gegen Wartung.
Das gesamte Ergebnis speichern, nicht nur Ihre Position
Der häufigste Designfehler, und derjenige, der teuer zu korrigieren ist, ist das Speichern einer einzelnen Zahl pro Keyword pro Tag.
Speichern Sie die vollständige Rangliste der URLs, das Vorhandensein und die Position von Ergebnisfunktionen und den rohen Payload. Drei Gründe. Die Bewegungen Ihrer Wettbewerber sind der Kontext, der Ihre eigene Bewegung interpretierbar macht. Feature-Änderungen, etwa ein AI Overview, das über der Falz erscheint, ändern, was eine Position wert ist, ohne die Zahl zu ändern. Und Sie können eine SERP von letztem Dienstag nicht rückwirkend sammeln, also ist alles, was Sie nicht gespeichert haben, verloren.
CREATE TABLE serp_snapshot (
id BIGSERIAL PRIMARY KEY,
keyword TEXT NOT NULL,
country TEXT NOT NULL,
city TEXT,
device TEXT NOT NULL,
captured_at TIMESTAMPTZ NOT NULL,
results JSONB NOT NULL, -- full ranked list
features JSONB NOT NULL, -- ai overview, local pack, shopping
raw JSONB -- keep it, storage is cheaper than regret
);
CREATE INDEX ON serp_snapshot (keyword, country, device, captured_at DESC);
Positionen werden dann aus Snapshots abgeleitet, statt als primärer Datensatz gespeichert zu werden, was bedeutet, dass eine Parsing-Korrektur auf die Historie rückwirkend angewendet werden kann, statt nur auf zukünftige Läufe.
Für Vergleichbarkeit planen
Laufen Sie jeden Tag zur gleichen Zeit, in einem Fenster, das Sie stabil halten, denn Ergebnisse verschieben sich im Laufe des Tages, und eine Serie, die zu unterschiedlichen Stunden gesammelt wurde, hat eine Varianz, die Sie nicht zuordnen können.
Verteilen Sie die Arbeit über dieses Fenster, statt alle Keywords auf einmal abzufeuern. Ein Burst ist sowohl für die Quelle härter als auch wahrscheinlicher, gedrosselt zu werden, und Verteilen kostet Sie nichts, wenn die Deadline Stunden entfernt ist. Fügen Sie Jitter zwischen Requests hinzu, begrenzen Sie die Nebenläufigkeit und lassen Sie den Lauf eine Stunde statt vier Minuten dauern.
import random, time
def run_daily(targets, window_seconds=3600):
gap = window_seconds / max(len(targets), 1)
for t in targets:
snapshot = fetch_with_retries(t)
store(t, snapshot)
time.sleep(gap * random.uniform(0.7, 1.3)) # spread, with jitter
”Keine Änderung” von “keine Daten” unterscheiden
Das ist das Detail, das eine vertrauenswürdige Serie von einer irreführenden trennt. Wenn ein Fetch fehlschlägt und Sie nichts schreiben, sieht ein späterer Leser eine Lücke, die identisch mit einem Tag aussieht, an dem sich nichts bewegt hat. Dann überspannt ein Vergleich gegen “gestern” stillschweigend zwei Tage und meldet eine Bewegung, die nicht stattgefunden hat.
Zeichnen Sie jeden Versuch mit einem expliziten Ergebnis auf, und lassen Sie die nachgelagerte Analyse einen Vergleich über eine Lücke hinweg verweigern:
def fetch_with_retries(t, attempts=3):
for i in range(attempts):
try:
data = fetch_serp(t)
if is_valid(data): # sanity-check the payload
return {"status": "ok", "data": data}
record_status(t, "invalid") # parsed, but not a real SERP
except requests.RequestException:
record_status(t, "error")
time.sleep(2 ** i * random.uniform(0.5, 1.5))
return {"status": "failed", "data": None} # written as a failure, not skipped
Die Validierung des Payloads ist ebenso wichtig wie das Abfangen von Exceptions, denn eine Antwort kann erfolgreich eintreffen und trotzdem keine brauchbare Ergebnisseite sein, was das allgemeine Problem in detecting blocked or fake content ist.
Bei Bewegung alarmieren, die etwas bedeutet
Ein naiver Alert bei jeder Positionsänderung wird ständig ausgelöst, und ein Alerting-System, dem niemand vertraut, ist schlimmer als keines.
Drei Regeln machen Alerts nützlich. Verlangen Sie einen Schwellenwert proportional zur Position, da eine Bewegung von 3 zu 6 weit mehr bedeutet als 47 zu 50. Verlangen Sie Persistenz, das heißt zwei oder drei aufeinanderfolgende Läufe, denn Ein-Tages-Ausschläge sind normal. Und alarmieren Sie separat beim Eintreten oder Verlassen der ersten Seite, da diese Grenze echte Traffic-Konsequenzen hat.
Fügen Sie dann den einen Alert hinzu, den Leute vergessen: die Sammel-Gesundheit selbst. Wenn ein Markt vor drei Tagen still aufgehört hat, Daten zu liefern, ist das dringender als jede Ranking-Änderung, und es ist nur sichtbar, wenn Sie Lauf-Ergebnisse als erstklassige Daten verfolgen, gemäß monitoring a scraping pipeline.
Die Daten sich selbst erklären lassen
Zwei Ergänzungen verwandeln eine Rank-Tabelle in etwas, das Sie einem Kunden vorlegen können.
Annotieren Sie Ihre eigene Zeitleiste: Deployments, Content-Veröffentlichungen, Migrationen. Die Hälfte aller “Warum sind wir gefallen”-Untersuchungen endet mit einem Release, der in dieser Woche herausging, und ein annotiertes Chart findet das sofort.
Berechnen Sie Bewegung auf Portfolio-Ebene, nicht nur Positionen pro Keyword, denn eine breite Verschiebung über viele unabhängige Keywords ist ein anderes Ereignis als eine einzelne Seite, die abrutscht. Das ist die Volatilitätsanalyse in detecting SERP volatility and algorithm updates, und sie ist nur möglich, weil Sie das vollständige Ergebnisset gespeichert haben, statt nur Ihre eigene Position.
Verantwortungsvoll sammeln
Bleiben Sie bei öffentlichen Suchergebnissen, respektieren Sie die Nutzungsbedingungen jeder Suchmaschine und halten Sie ein höfliches Tempo, statt Rate Limits als Hindernis zu behandeln. Ein täglicher Monitoring-Job hat keinen Grund, aggressiv zu sein: Die Deadline ist der nächste Morgen, also kostet das Verteilen der Arbeit nichts.
Das Wesentliche
Der Cron-Job ist der einfache Teil. Legen Sie zuerst Ihren Messvertrag fest, sodass Standort, Gerät, Sprache und Personalisierung Konstanten sind statt zufälliger Variablen. Speichern Sie das vollständige Ergebnisset und den rohen Payload, nicht nur Ihre Position, denn Wettbewerberkontext und Ergebnisfunktionen sind es, die eine Zahl interpretierbar machen, und Sie können nicht dafür zurückgehen. Laufen Sie zu einer konsistenten Zeit, verteilt über das Fenster mit Jitter. Zeichnen Sie Fehler explizit auf, damit eine Lücke niemals mit Stabilität verwechselt werden kann. Alarmieren Sie bei anhaltender, positionsgewichteter Bewegung sowie Sammel-Gesundheit. Annotieren Sie dann Ihre eigenen Änderungen, sodass das Chart die Frage beantwortet, die Leute tatsächlich stellen.
Die Abrufschicht ist eine SERP API, wenn Sie geparste Ergebnisse wollen, ohne das Sammeln zu warten, oder residential proxies mit Land- und Stadt-Targeting, wenn Sie es lieber selbst betreiben möchten, mit per-GB pricing, das für kleine, häufige Checks passt.