SEO QA & Monitoring mit Python – Teil 1 – Status Codes

Vor allem im SEO Bereich muss man oft viele Seiten im Überblick behalten. Natürlich gibt es eine Vielzahl an Tools die einem diese Aufgabe abnehmen. Wenn man aber nicht viel Budget übrig hat, kann es sich durchaus lohnen, diese Aufgaben selbst zu automatisieren.

Im Folgenden möchte ich meinen Ansatz teilen, Seiten mit Python zu monitoren und gängige SEO-Fehler einfach und schnell zu finden.

Disclaimer: Ich bin kein Entwickler und auch kein Python-Profi, daher sind die vorgestellten Methoden vermutlich nicht die Besten und Schönsten, aber sie funktionieren. Da ich auch immer noch weiter lerne, werden die Scripte natürlich bei Bedarf erweitert / angepasst.

Virtuelle Umgebung einrichten

Im ersten Schritt betrachten wir das ganze als lokales Python-Script welches auf meinem Mac läuft und on demand ausgeführt werden kann. Das Setup ist relativ einfach. Ihr benötigt Python (ich verwende 3.6 es geht aber auch mit 3.7) und am besten gleich eine passende IDE. Ich verwende PyCharm, da damit das Einrichten einer virtuellen Umgebung relativ einfach ist und die Community-Edition sogar kostenlos ist.

Sobald das Grundsetup steht, kann man ein neues Projekt anlegen.

PyCharm Create Project Screen

Nun könnt ihr euch eine neue Datei (Python-File) anlegen, welche uns als Startpunkt dient. Nennen wir sie einfach seq-qa.py. Im ersten Schritt holen wir uns nun einfach mal den Inhalt einer URL. Dafür benötigen wir die Requests Library welche wir mit pip einfach installieren können. Dafür im Terminal (integriert in PyCharm) folgenden Befehl absetzen.

pip install requests

Danach können wir die Requests Library verwenden indem wir es mit import requests importieren. Damit haben wir das Grundgerüst fertig um einen URL abzufragen und den Status-Code dieser URL herauszufinden. Ein simples Script dafür würde wie folgt aussehen:

import requests

url = 'https://www.google.de'
response = requests.get(url)
print(response.status_code)

Führt man dieses mit python seo-qa.py aus, erhält man 200 zurück. Sprich, die Seite ist erreichbar. Will man nur den Status-Code der Seite erhalten, reicht außerdem ein einfacher head-request, das gesamte HTML-Dokument muss in diesem Fall nicht geladen werden.

import requests

url = 'https://www.google.de'
response = requests.head(url)
print(response.status_code)

Batch-Check von mehreren URLs

Hier checken wir nur eine URL. In der Praxis hat man aber meist ein ganzes Set an URLs die man gerne prüfen möchte. Daher wollen wir nun 5 URLs auf einmal überprüfen. Für dieses Vorhaben legen wir uns nun eine neue Datei an. Diese nennen wir einfach urllist.json. In diese packen wir nun die gewünschten URLs:

{
  "urls": [
    "https://www.google.com",
    "https://www.youtube.com",
    "https://www.amazon.de",
    "https://de.wikipedia.org",
    "https://www.ebay.de"
  ]
}

Um die json-Datei verarbeiten zu können, müssen wir nun zusätzlich die json Library importieren

import requests
import json

with open('urllist.json') as json_file:
    data = json.load(json_file)
    for url in data['urls']:
        response = requests.get(url)
        print(f'{url} returns status-code {response.status_code}')

Danach öffnen wir die urllist und iterieren über die einzelnen URLs. Die Ausgabe sieht nun wie folgt aus.

https://www.google.com returns status-code 200
https://www.youtube.com returns status-code 200
https://www.mozilla.org returns status-code 200
https://de.wikipedia.org returns status-code 200
https://www.ebay.de returns status-code 200

Wir sehen also, dass alle getesteten Seiten erreichbar sind. Wenn man die Liste nun mit den eigenen URLs befüllt, kann man relativ einfach sehen, ob die Seiten online erreichbar sind. Mit dieser Methode kann man auch sehr schön sehen, ob es eventuell Redirects gegeben hat bzw. ob die URLs die man überprüft redirecten. Requests speichert Redirects in eine History und so kann man alle Schritte nachvollziehen.

Dafür reduzieren wir erst einmal die URL-Liste auf eine URL und verwenden

{
  "urls": [
    "http://de.wikipedia.org"
  ]
}

Redirects nachverfolgen und Ketten finden

Wie ihr seht, haben wir nun die non-secure Version von Wikipedia. Wenn wir unsere Script ausführen, sehen wir wieder einen Status-Code 200. In Wahrheit wird aber ein Redirect durchgeführt.

Wenn wir unser Skript leicht anpassen, können wir diese Fälle jedoch auch abfangen und die einzelnen Redirect-Schritte sowie Statuscodes anzeigen lassen

import requests
import json

with open('urllist.json') as json_file:
    data = json.load(json_file)
    for url in data['urls']:
        response = requests.get(url, allow_redirects=True)
        if len(response.history) > 0:
            print (f'{url} redirected:')
            redirectindex = 1
            for history in response.history:
                print(f'{redirectindex}. Schritt: {history.url} leitet um auf {history.headers["location"]} mit Statuscode {history.status_code}')
                redirectindex += 1
            print(f'Finale URL ist {response.url} mit Statuscode {response.status_code}')
        elif response.status_code != 200:
            print(f'Finale URL ist {response.url} mit Statuscode {response.status_code}')

Führen wir unser Script nun erneut aus, sehen wir, dass beim Aufruf von http://de.wikipedia.org sogar zwei redirects durchgeführt werden bis wir bei der finalen URL https://de.wikipedia.org/ angekommen sind.

http://de.wikipedia.org/ redirected:
1. Schritt: http://de.wikipedia.org/ leitet um auf https://de.wikipedia.org/ mit Statuscode 301
2. Schritt: https://de.wikipedia.org/ leitet um auf https://de.wikipedia.org/wiki/Wikipedia:Hauptseite mit Statuscode 301
Finale URL ist https://de.wikipedia.org/wiki/Wikipedia:Hauptseite mit Statuscode 200

Wenn man dieses Redirect-Verhalten unterbinden möchte, kann man Redirects auch deaktivieren beim request.

response = requests.get(url, allow_redirects=False)

Dann würde unser Skript nun folgende Ausgabe erzeugen:

http://de.wikipedia.org returns status-code 301