Wie du die großen Datenmengen aus den SERPs einfach analysieren kannst

Evgeni Sereda

Jan 11, 202317 min read
Wie du die großen Datenmengen aus den SERPs einfach analysieren kannst

Als SEO-Profi weißt du, dass ein großer Teil deiner Aufgabe in der Verfolgung von Suchergebnis-Rängen besteht, sowohl deine eigenen sowie auch die deiner Mitbewerber. Im Folgenden teile ich eine Methode mit dir, Suchergebnisdaten zu erheben und zur Analyse in einen DataFrame (Tabelle, CSV, Excelliste) zu importieren – in großem Maßstab und automatisiert.

Ich verwende dazu die Programmiersprache Python. Unten begegnen uns also einige Code-Bausteine. Wenn du dich damit nicht auskennst, kannst du diese ignorieren. Du musst sie nicht verstehen, um zu folgen.

Wie kommen wir also an die Daten und was stellen wir damit an? Finden wir es heraus.

Der Daten-Import 

Googles benutzerdefinierte Suchmaschine ist ein Service, bei dem du Websites zum Durchsuchen angeben und deine eigenen Relevanzregeln festlegen kannst. Wenn du keine Regeln formulierst, durchsucht die benutzerdefinierte Suchmaschine standardmäßig das ganze Netz.

Du kannst die benutzerdefinierte Suche weiter auf deinen Bedarf zuschneiden, indem du Parameter für deine Suchanfragen festlegst, etwa den Standort des Nutzers, die Sprache der Website, Bildsuche und vieles mehr.

Ebenso hast du die Möglichkeit, die Daten über eine API (Was ist eine API?) anzufordern, und das ist der Weg, den wir uns hier näher anschauen.

Folgendes sind die Schritte, um einen Account für den Datenimport zu erstellen (überspringe diese, wenn du nicht selbst den Code ausführen willst):

  1. Erstelle eine benutzerdefinierte Suchmaschine. Zuerst wirst du aufgefordert, eine Website anzugeben, die durchsucht werden soll. Gib eine beliebige Domain ein und klicke dann im Menü links auf "In bestimmten Websites oder Seiten suchen". Weiter unten auf der Seite kannst du nun die Domain wieder entfernen und direkt darunter die Option "Im gesamten Web suchen" einschalten.
  2. Aktiviere die Custom Search API. Der Service ermöglicht es dir, Daten aus deiner benutzerdefinierten Suchmaschine durch ein Programm abzurufen und anzuzeigen. Dazu musst du zuerst ein Projekt erstellen.
  3. Gib deine persönlichen Daten ein, um deinen Key zu erhalten.
  4. Aktiviere eine Zahlungsweise für dein Projekt, wenn du mehr als 100 Abfragen pro Tag durchführen willst. Die ersten 100 Abfragen sind kostenlos; darüber zahlst du 5 US-Dollar pro 1.000 Abfragen.

Die Programmierumgebung

Für diese Analyse verwende ich das Jupyter Notebook als Editor. Wenn du es nicht kennst – es handelt sich um ein browserbasiertes Tool, das einfachen Text mit Programmcode und dem Output ausgeführten Codes kombiniert. Das Output kann Text sein, es können Tabellen oder auch Bilder sein (zum Beispiel Daten-Visualisierungen wie die, die du unten siehst).

Es ähnelt stark einer Textverarbeitung und eignet sich sehr gut für die Durchführung von Analysen, die Entwicklung von Kampagnen und generell die Programmierarbeit. Ich verwende es für fast alle meine Aufgaben.

Das Notebook erlaubt es dir, Zwischenschritte zu speichern. So kannst du immer zurückgehen und nachvollziehen, wie du zu deinen Schlussfolgerungen gelangt bist und ob du Fehler findest oder Verbesserungsbedarf siehst. Ebenso können andere Nutzer die Analyse fortsetzen, wo du aufgehört hast.

Deinen Text oder Code gibst du im Notebook in Textkästen ein, die als "Zellen" ("Cells") bezeichnet werden. Hier siehst du die Darstellung mit kurzen Beschreibungen der Zellen.

Code- und Markdown-Zellen in Jupyter Notebook
Code- und Markdown-Zellen in Jupyter Notebook

Es folgt eine simple Daten-Visualisierung mit Erläuterung, was dieser Code bewirkt: 

Daten-Visualisierung in Jupyter Notebook
Daten-Visualisierung in Jupyter Notebook

Zeile 1: Der Import eines Packages macht dieses zunächst einmal verfügbar, ähnlich wie beim Start einer Anwendung auf deinem Computer. Hier importieren wir ein Package namens "matplotlib" mit dem Submodul "pyplot" für die Daten-Visualisierung. Da der Name recht lang ist und wir ihn nicht jedes Mal tippen wollen, wenn wir einen Befehl ausführen, verwenden wir das Kürzel "plt", wie du in Zeilen 6-10 siehst. 

Wenn wir nun einen Befehl von matplotlib ausführen wollen, geben wir einfach "plt.<befehlname>" ein, zum Beispiel "plt.plot".

Zeilen 3 und 4: Hier definieren wir zwei Variablen, "x" and "y", wobei jede eine Liste von Zahlen ist, die wir grafisch darstellen wollen. Das Gleichheitszeichen ist ein Zuweisungsoperator und wird hier nicht in seinem mathematischen Sinn gebraucht. Wir definieren in diesem Fall eine Liste von Zahlen [1, 2, 3, 4, 5] und nennen sie "x". Stell dir das wie eine Abkürzung vor. Wir wissen, was die Liste beinhaltet, und müssen daher nicht jedes Mal die Zahlen selbst eingeben. 

Zeile 6: Wir stellen "x" und "y" grafisch dar.

Zeilen 7, 8 und 9: Hier fügen wir einige Optionen hinzu. Wie du später im Tutorial sehen wirst, sind eine ganze Reihe von Optionen verfügbar. Die Ergebnisse dieser Einstellungen siehst du im Diagramm als Titel, "xlabel" und "ylabel".

Zeile 10: Zeichnet das Diagramm.

In "[5]": Dies identifiziert die Zelle als Inputzelle. Es handelt sich um die fünfte Instruktion, die ich durchgeführt habe, weshalb die Ziffer "5" angezeigt wird.

Die Ausführung dieser Codezeilen bringt obiges Diagramm hervor.

Ganz unten habe ich Links zu allen verwendeten Datasets eingefügt, ebenso das Notebook zu diesem Tutorial in einem Repository. Alle Schritte des Datenimports, der Verarbeitung und Visualisierung sind enthalten, sodass du den gesamten Code siehst, der diese Ergebnisse erzeugt hat. Wie erwähnt, kannst du den Code ignorieren und dennoch folgen, wenn du nicht mit Python vertraut bist.

Die Datenverarbeitung

Wie verwenden drei Python-Packages für unsere Arbeit:

  • advertools: Um die Verbindung zur Google-API für die benutzerdefinierte Suche herzustellen und SERPs als Tabelle zu erhalten. (Dies ist ein Package, das ich geschrieben habe und unterhalte. Es enthält eine Reihe von Produktivitäts- und Analyse-Tools für das Online-Marketing.)
  • pandas: Für die Datenmanipulation, -umformung, -zusammenführung, -sortierung etc.
  • matplotlib: Für die Datenvisualisierung.

Um dir einen Eindruck vom Datenmaterial zu vermitteln, ist hier ein Ausschnitt der benutzerdefinierten Suchergebnisse, mit denen wir arbeiten werden:

import pandas as pd
serp_flights = pd.read_csv('serp_flights.csv')
serp_flights.head()
Google-Suchergebnisse als Excel-Tabelle
Google-Suchergebnisse als Excel-Tabelle

Nicht alle Spalten sind sichtbar, aber ich möchte dir trotzdem ein paar Erläuterungen zu den verfügbaren Spalten geben:

"queryTime" ist der Zeitpunkt, zu dem die Suchanfrage durchgeführt wurde. Dieser Wert ist nicht zu verwechseln mit der "searchTime", die angibt, wie lange Google gebraucht hat, um die Anfrage zu bearbeiten (in der Regel weniger als eine Sekunde). Die meisten der Hauptspalten sind immer vorhanden, doch wenn du andere Parameter übergibst, erhältst du dementsprechend mehr oder auch weniger Spalten. Beispielsweise kommen Spalten mit Bildbeschreibungen hinzu, wenn du die Art der Suche auf "Bilder" festlegst.

Der Datensatz

Wir werden uns mit dem Verkauf von Flugtickets beschäftigen, und zwar mit diesen Details:

  • Ziele: Ich habe die Top-100-Flugziele aus Wikipedia entnommen und als Basis der Suchanfragen verwendet.
  • Keywords: Jedes Ziel tauchte in zwei Variationen auf: wir sehen uns "flights to destination" und "tickets to destination" an.
  • Länder: Jede Variation wurde in zwei englischsprachigen Ländern abgefragt, den USA und dem Vereinigten Königreich.
  • SERPs: Jedes Suchergebnis besteht aus zehn Links mit dazugehörigen Metadaten.

Im Ergebnis haben wir 100 Ziele x 2 Variationen x 2 Länder x 10 Ergebnisse = 4.000 Datenzeilen.

Das ist eine sehr große Datenmenge und für einen Menschen ist es unmöglich sie komplett konzentriert durchzuschauen. Wirklich anschaulich ist sie auch nicht. Ohne Hilfe wird die Datenanalyse und die Auswertung schwierig.

Um Keywords für die weitere Verarbeitung zu erhalten, kannst du auf die große Datenbank von SEMrush im Keyword Magic Tool zugreifen.

Beginnen wir mit dem Import der Packages, die wir benutzen wollen, und der Definition unserer Google-ID für die benutzerdefinierte Suche sowie unseres Google-Developer-Keys:

%config InlineBackend.figure_format = 'retina'
import matplotlib.pyplot as plt
import advertools as adv
import pandas as pd
pd.set_option('display.max_columns', None)
cx = 'YOUR_GOOGLE_CUSTOM_SEARCH_ENGINE_ID'
key = 'YOUR_GOOGLE_DEVELOPER_KEY'

Nun können wir die Wikipedia-Tabelle importieren, welche die Top-Flugziele und einige weitere Daten enthält:

top_dest = pd.read_html('https://en.wikipedia.org/wiki/List_of_cities_by_international_visitors', 
header=0)[0]
top_dest.head().style.format({'Arrivals 2016Euromonitor': '{:,}'})
Top-Reiseziele aus Wikipedia
Top-Reiseziele aus Wikipedia

Als nächstes erstellen wir unsere Keywords, indem wir die zwei oben genannten Variationen verketten:

cities = top_dest['City'].tolist()
queries = ['flights to ' + c.lower() for c in cities] + ['tickets to ' + c.lower() for c in cities]
queries[:3] + queries[-3:] + ['etc...']
['flights to hong kong',
'flights to bangkok',
'flights to london',
'tickets to washington d.c.',
'tickets to chiba',
'tickets to nice',
'etc...']

Nachdem die Hauptparameter definiert sind, senden wir die Abfrage wie folgt an Google:

serp_flights = adv.serp_goog(cx=cx, key=key, q=queries, gl=['us', 'uk'])# imports data
serp_flights = pd.read_csv('serp_flights.csv',parse_dates=['queryTime'])# saves it in a csv file
serp_us = serp_flights[serp_flights['gl'] == 'us'].copy() # create a subset for US
serp_uk = serp_flights[serp_flights['gl'] == 'uk'].copy() # create a subset for UK

Werfen wir nun einen kurzen Blick auf die führenden Domains:

print('Domain Summary - Overall')
(serp_flights
.pivot_table('rank', 'displayLink', 
aggfunc=['count', 'mean'])
.sort_values([('count', 'rank'), ('mean', 'rank')], 
ascending=[False, True])
.assign(coverage=lambda df: df[('count', 'rank')] / len(serp_flights)*10)
.head(10).style.format({("coverage", ''): "{:.1%}", 
('mean', 'rank'): '{:.2f}'}))
Top-10-Domains - Flüge und Tickets
Top-10-Domains - Flüge und Tickets

Da wir hauptsächlich an den Rängen von Domains interessiert sind (Website Ranking), lassen wir sie nach drei Metriken zusammenfassen:

1. Häufigkeit: Die Zahl des Vorkommens einer Domain in unseren Suchergebnissen.

2Mittelwert: Der mittlere (durchschnittliche) Rang jeder Domain.

3. Abdeckung: Die Häufigkeit geteilt durch die Anzahl der Suchanfragen.

Die obige Pivot-Tabelle beinhaltet alle Ergebnisse und ermöglicht einen schnellen Überblick. Ich halte es jedoch für aussagekräftiger, die Daten in zwei Pivot-Tabellen zu unterteilen, eine für jedes der zwei Länder:

print('Domain Summary - US')
(serp_flights[serp_flights['gl']=='us']
.pivot_table('rank', 'displayLink', 
aggfunc=['count', 'mean'])
.sort_values([('count', 'rank'), ('mean', 'rank')], 
ascending=[False, True])
.assign(coverage=lambda df: df[('count', 'rank')] / len(serp_flights)*10 * 2)
.head(10).style.format({("coverage", ''): "{:.1%}", 
('mean', 'rank'): '{:.2f}'}))
Top-10-Domains - Flüge und Tickets in den USA
Top-10-Domains - Flüge und Tickets in den USA

Zur Berechnung der Abdeckung habe ich in der ersten Tabelle durch 400 geteilt. Für die Länder teile ich nun durch 200, da wir uns die Suchanfragen pro Land ansehen wollen. Ein interessanter Fund ist hier, dass kayak.com eine geringere Abdeckung hat als tripadvisor.com, aber zugleich einen höheren durchschnittlichen Rang. Bei den Top-Positionen ist der Unterschied im Wert eines zweiten und dritten Platzes recht groß. Je nach Situation kann es sinnvoll sein, die eine Kennzahl oder die andere höher zu gewichten.

print('Domain Summary - UK')
(serp_flights[serp_flights['gl']=='uk']
.pivot_table('rank', 'displayLink', 
aggfunc=['count', 'mean'])
.sort_values([('count', 'rank'), ('mean', 'rank')], 
ascending=[False, True])
.assign(coverage=lambda df: df[('count', 'rank')] / len(serp_flights)*10*2)
.head(10).style.format({("coverage", ''): "{:.1%}", 
('mean', 'rank'): '{:.2f}'}))
Top-10-Domains für Flüge und Tickets - Vereinigtes Königreich
Top-10-Domains für Flüge und Tickets - Vereinigtes Königreich

Eine Abdeckung von 108 % bedeutet, dass skyskanner.net in allen Suchergebnissen vorgekommen ist – in manchen Fällen mehr als einmal. Beachte, dass der mittlere Rang mit 1,45 deutlich höher ist als derjenige der zweiten Domain. Mit SkySkanner ist nicht zu spaßen!

Nachdem wir nun eine Vorstellung davon haben, wie oft die Websites in der Suche erschienen sind und auf welchen Rängen, wird es nützlich sein, die Daten zu visualisieren, um ihre Verteilung zu sehen und Erkenntnisse daraus zu ziehen.

Dazu rufen wir die Top-10-Domains für jedes Land ab und definieren zwei neue DataFrames (Tabellen) mit nur den gefilterten Daten. Diese werden dann visualisiert:

top10_domains = serp_flights.displayLink.value_counts()[:10].index
top10_df = serp_flights[serp_flights['displayLink'].isin(top10_domains)]

top10_domains_us = serp_us.displayLink.value_counts()[:10].index
top10_df_us = serp_flights[serp_flights['displayLink'].isin(top10_domains_us)]

top10_domains_uk = serp_uk.displayLink.value_counts()[:10].index
top10_df_uk = serp_flights[serp_flights['displayLink'].isin(top10_domains_uk)]

fig, ax = plt.subplots(facecolor='#ebebeb')
fig.set_size_inches(15, 9)
ax.set_frame_on(False)
ax.scatter(top10_df['displayLink'].str.replace('www.', ''), 
top10_df['rank'], s=850, alpha=0.02, edgecolor='k', lw=2)
ax.grid(alpha=0.25)
ax.invert_yaxis()
ax.yaxis.set_ticks(range(1, 11))
ax.tick_params(labelsize=15, rotation=9, labeltop=True,
labelbottom=False)
ax.set_ylabel('Search engine results page rank', fontsize=16)
ax.set_title('Top 10 Tickets and Flights Domains', pad=75, fontsize=24)
ax.text(4.5, -0.5, 'Organic Search Rankings for 200 Keywords in US & UK', 
ha='center', fontsize=15)
fig.savefig(ax.get_title() + '.png', 
facecolor='#eeeeee', dpi=150, bbox_inches='tight')
plt.show()
Top-10-Tickets und Flüge - SERP-Visualisierung
Top-10-Tickets und Flüge - SERP-Visualisierung

Jedes Vorkommen auf einer Suchergebnisseite ist mit einem hellen Kreis an der Position der Domain (von 1 bis 10) dargestellt. Je häufiger eine Domain erscheint, desto dunkler wird der Kreis. Zum Beispiel haben kayak.com, expedia.com und skyskanner.net kräftig blaue Kreise auf Platz 1, und daneben hellere auf verschiedenen Plätzen.

Eine Schwäche dieser statistischen Analyse ist, dass sie alle Keywords gleich behandelt. Die Anzahl der Touristen in der Liste der Top-100-Orte variiert zwischen 2 und 26 Millionen, sodass die Ziele nicht direkt vergleichbar sind. In deinem speziellen Fall hast du vielleicht deine eigenen "Top 100", je nach der Website, an der du arbeitest. Doch da wir gerade diese Branche erforschen und die Marktpositionen der Anbieter verstehen wollen, halte ich die gewählte Herangehensweise für brauchbar. Behalte dies jedoch für ähnliche Analysen im Hinterkopf.

Wie oben bezog sich die vorangehende Visualisierung auf den gesamten Datensatz der Datenquellen. Hier folgt nun derselbe Prozess mit Unterscheidung nach Ländern:

top10_dfs = [top10_df_us, top10_df_uk]
colors = ['darkred', 'olive']
suffixes = [' - US', ' - UK']
fig, ax = plt.subplots(2, 1, facecolor='#ebebeb')
fig.set_size_inches(15, 18)
for i in range(2):
ax[i].set_frame_on(False)
ax[i].scatter(top10_dfs[i]['displayLink'].str.replace('www.', ''), 
top10_dfs[i]['rank'], s=850, alpha=0.02, 
edgecolor='k', lw=2, color='darkred')
ax[i].grid(alpha=0.25)
ax[i].invert_yaxis()
ax[i].yaxis.set_ticks(range(1, 11))
ax[i].tick_params(labelsize=15, rotation=12, labeltop=True,
labelbottom=False)
ax[i].set_ylabel('Search engine results page rank', fontsize=16)
ax[i].set_title('Top 10 Tickets and Flights Domains' + suffixes[i], 
pad=75, fontsize=24)
ax[i].text(4.5, -0.5, 'Organic Search Rankings for 200 Keywords', 
ha='center', fontsize=15)
plt.tight_layout()
fig.savefig(ax[i].get_title() + '.png', 
facecolor='#eeeeee', dpi=150, bbox_inches='tight')
plt.show()
Top-10-Tickets und Flüge - SERP-Visualisierung: USA vs. UK
Top-10-Tickets und Flüge - SERP-Visualisierung: USA vs. UK

Content-Quantität

Darüber hinaus willst du vielleicht wissen, wie viele Einzelseiten jede Domain für die verschiedenen Städte bereithält. Wenn wir annehmen, dass der Content real ist und ein Minimum an Qualität aufweist (SEO Content), hast du mit jeder zusätzlichen Seite eine höhere Chance, im Suchergebnis zu erscheinen – insbesondere für Keyword-Variationen und die verschiedenen Kombinationen (Keyword Analyse), in denen Nutzer sie verwenden.

Einer der Abfrage-Parameter, die Google ermöglicht, ist die Website, die du durchsuchen willst. Ebenso kannst du Websites ausschließen. Wenn wir also nach "tickets to hong kong" suchen und die Suche eingrenzen mit "siteSearch=www.tripadvisor.com" und "siteSearchFilter=i" (für "Einschluss"), erhalten wir lediglich Suchergebnisse von dieser Website.

Eine wichtige Spalte in jedem Ergebnis ist "totalResults". Hier erfährst du, wie viele Seiten Google für diese Suchanfrage ausgibt. Da die Anfrage auf eine Domain und ein Keyword eingegrenzt ist, können wir so herausfinden, wie viele Seiten dieser Domain eine Chance haben, für dieses Keyword gefunden zu werden.

Ich habe Abfragen für die Top-5-Ziele sowie für die beiden Länder durchgeführt:

pagesperdomain_us = adv.serp_goog(cx=cx, key=key, q=queries[:5], 
siteSearch=top10_domains_us.tolist(), 
siteSearchFilter='i', num=1)
pagesperdomain_uk = adv.serp_goog(cx=cx, key=key, q=queries[:5], 
siteSearch=top10_domains_uk.tolist() , 
siteSearchFilter='i', num=1)

Hier sind die ersten zehn Ergebnisse aus den USA für "flights to hong kong". Darunter folgt eine statistische Visualisierung für jedes Keyword und die Zielländer:

(pagesperdomain_us
[['searchTerms', 'displayLink', 'totalResults']]
.head(10)
.style.format({'totalResults': '{:,}'}))
Anzahl der Suchergebnisse für 'flights to hong kong'
Anzahl der Suchergebnisse
from matplotlib.cm import tab10
from matplotlib.ticker import EngFormatter
fig, ax = plt.subplots(5, 2, facecolor='#eeeeee')
fig.set_size_inches(17, 20)
countries = [' - US', ' - UK']
pages_df = [pagesperdomain_us, pagesperdomain_uk]
for i in range(5):
for j in range(2):
ax[i, j].set_frame_on(False)
ax[i, j].barh((pages_df[j][pages_df[j]['searchTerms']== queries[i]]
.sort_values('totalResults')['displayLink']
.str.replace('www.', '')),
(pages_df[j][pages_df[j]['searchTerms']== queries[i]]
.sort_values('totalResults')['totalResults']),
color=tab10.colors[i+5*j])
ax[i, j].grid(axis='x')
ax[i, j].set_title('Pages per domain. Keyword: "' +queries[i] + '"' + countries[j],
fontsize=15)
ax[i, j].tick_params(labelsize=12)
ax[i, j].xaxis.set_major_formatter(EngFormatter())
plt.tight_layout()
fig.savefig('Pages per domain' + '.png', 
facecolor='#eeeeee', dpi=150, bbox_inches='tight')
plt.show()
Anzahl der Seiten pro Domain
Anzahl der Seiten pro Domain

Wie du siehst, ist der Unterschied in einigen Fällen dramatisch, und das korreliert nicht immer mit Top-Positionen. Fühl dich frei, die Analyse zu vertiefen oder andere Keywords einzubeziehen.

Mit dieser Methode erfährst du wertvolle Insights deiner Datenquellen und kannst eine effizientere, optimierte Datenanalyse mit allen relevanten Erkenntnissen durchführen.

Aber es ist noch mehr möglich!

Titel analysieren

Es gibt viele Möglichkeiten, Meta Titel und u.U. herhovgehobene Snippets zu analysieren, aber in diesem Fall hat eine davon meine Aufmerksamkeit erregt, die ich in dieser Branche für bedeutsam halte. Viele Websites fügen Ticketpreise in die Seitentitel ein, was sie nicht nur im Suchergebnis sichtbar macht, sondern als einer der wichtigsten Faktoren darüber entscheidet, ob die Nutzer klicken.

Beispiel:

serp_flights[serp_flights['searchTerms'] == 'flights to paris'][['searchTerms', 'title']].head(10)
Flüge nach Paris - Seitentitel
Flüge nach Paris - Seitentitel

Extrahieren wir nun Preise und Währungen, um weitere Analysen zu ermöglichen.

serp_flights['price'] = (serp_flights['title']
.str.extract('[$£](\d+,?\d+\.?\d+)')[0]
.str.replace(',', '').astype(float))
serp_flights['currency'] = serp_flights['title'].str.extract('([$£])')
serp_flights[['searchTerms', 'title', 'price', 'currency', 'displayLink']].head(15)
Seitentitel mit Preisen
Seitentitel mit Preisen

Zwei weitere Spalten sind aufgetaucht, "price" und "currency". In manchen Fällen findet sich kein Preis im Titel ("NaN" für "not a number"), doch bei anderen sind Dollar- und Pfund-Symbole vorhanden. Manche Sites zeigen die Preise auch in anderen Währungen an, doch da es sich hier nur um wenige handelt, würde sich ein Vergleich nicht lohnen. Wir beschränken uns also auf Dollar und Pfund.

Für die ersten fünf Abfragen können wir die verschiedenen Preise (soweit verfügbar) grafisch darstellen. Dadurch erhalten wir einen schnellen Überblick der Preise im Vergleich.

Hier ist Ihr Preisvergleichs-Tool Marke Eigenbau:

fig, ax = plt.subplots(5, 2, facecolor='#eeeeee')
fig.set_size_inches(17, 20)
countries = [' - US ($)', ' - UK (£)']
country_codes = ['us', 'uk']
currency = ['$', '£']
top10dfs = [top10_domains_us, top10_domains_uk]
for i in range(5):
for j in range(2):
ax[i, j].grid()
ax[i, j].set_frame_on(False)
df = serp_flights[(serp_flights['gl'] == country_codes[j]) & 
(serp_flights['searchTerms'] == queries[i]) &
(serp_flights['currency'] == currency[j])]
for country in top10dfs[j]:

ax[i, j].scatter(df.sort_values('totalResults')['displayLink'].str.replace('www.', ''),
df.sort_values('totalResults')['price'],
color=tab10.colors[i+5*j], s=300)
ax[i, j].set_title('Price per domain. Keyword: "' +queries[i] + '"' + countries[j],
fontsize=15)
ax[i, j].tick_params(labelsize=12, rotation=9, axis='x')
plt.tight_layout()
fig.savefig('Prices per domain' + '.png', 
facecolor='#eeeeee', dpi=150, bbox_inches='tight')
plt.show()

Ticketpreise nach Domain
Ticketpreise nach Domain

Um einen allgemeinen Überblick der Preise für die Top-Domains zu erhalten, können wir auch alle Fälle grafisch darstellen, in denen ein Preis im Seitentitel erscheint. So erfahren wir, wie sich die Preise unter den Seiten einer Domain verteilen:

fig, ax = plt.subplots(1, 2, facecolor='#eeeeee')
fig.set_size_inches(17, 8)
countries = [' - US ($)', ' - UK (£)']
country_codes = ['us', 'uk']
currency = ['$', '£']
top10dfs = [top10_domains_us, top10_domains_uk]
for j in range(2):
ax[j].grid()
ax[j].set_frame_on(False)
df = serp_flights[(serp_flights['gl'] == country_codes[j]) & 
(serp_flights['currency'] == currency[j]) &
(serp_flights['displayLink'].isin(top10dfs[j]))]
ax[j].scatter(df.sort_values('totalResults')['displayLink'].str.replace('www.', ''),
df.sort_values('totalResults')['price'] ,
color=tab10.colors[j], 
s=300, alpha=0.1)
ax[j].set_title('Prices per domain'+ countries[j],
fontsize=21)
ax[j].tick_params(labelsize=18, rotation=18, axis='x')
ax[j].tick_params(labelsize=18, axis='y')
plt.tight_layout()
fig.savefig('Prices per country' + '.png', 
facecolor='#eeeeee', dpi=150, bbox_inches='tight')
plt.show()
Ticketpreise nach Domain pro Land
Ticketpreise nach Domain pro Land

In den USA hat expedia.com eindeutig im Durchschnitt niedrigere Preise, und ein guter Teil davon liegt unter 200 US-Dollar. Tripadvisor.com scheint durchschnittlich am teuersten zu sein, doch hier finden wir auch größere Schwankungen als bei anderen. Opodo.co.uk ist mit Preisen fast ausschließlich unter 200 Pfund klar der preisgünstigste Anbieter im Vereinigten Königreich.

Beachte, dass die beiden Diagramme verschiedene Y-Achsen haben und Preise in verschiedenen Währungen anzeigen. Bei Entstehung dieses Artikels ist das britische Pfund etwa 1,30 US-Dollar wert. Dies heißt nicht unbedingt, dass expedia.com günstigere Preise anbietet, denn es könnte sich um "ab"-Angaben oder Preise handeln, die an bestimmte Bedingungen geknüpft sind. Es sind jedoch die Preise, die der Anbieter auf seiner Website bewirbt.

Ein Blick auf die Snippets

Wir können die Snippets auf ähnliche Weise analysieren wie die Seitentitel. Eine Website hat mit ihren Snippet-Texten besonders mein Interesse erregt, und zwar kayak.com.

Unten findet sich ein Auszug der Snippets von kayak.com. Wie du siehst, werden die Namen von Airlines, Preise und Zielorte genannt, obwohl die Anfragen nicht aussagen, von wo der Nutzer fliegen will. Beachte ebenso, dass die Angaben für jede Anfrage unterschiedlich sind. Für das Ziel Hong Kong werden Flüge aus San Francisco und New York angegeben, für Dubai gibt es Verbindungen aus New York, Chicago und Orlando.

Anscheinend werden die Snippet-Texte dynamisch generiert und orientieren sich an den am häufigsten nachgefragten Abflugorten und Airlines. Dies könnte ein interessanter Einblick in diesen Markt sein, oder zumindest die Sicht von Kayak auf diesen Markt und die eigene Positionierung darin. Es könnte interessant sein, die Kayak-Snippets zu exportieren und ein Diagramm der Abflug- und Zielorte sowie der Airlines zu erstellen, die am häufigsten damit einhergehen.

serp_flights[serp_flights['displayLink'] == 'www.kayak.com'][['snippet']][:10]`
Snippet-Text auf Suchergebnisseiten
Snippet-Text auf Suchergebnisseiten

Abschließende Anregungen

Dieser Artikel zeigt im Überblick eine schnelle Möglichkeit, anhand einer benutzerdefinierten Suchmaschine von Google eine große Zahl von Suchergebnissen abzufragen, und schlägt einige Ideen zu einer strukturierten Analyse großer Datenmengen vor.

Hier einige weitere Optionen, mit denen du experimentieren kannst:

  • In regelmäßigen Abständen den gleichen Bericht erstellen: In der Regel interessiert uns nicht nur eine Momentaufnahme unserer Position, sondern die Performance unserer Seiten im Zeitverlauf. Du kannst zum Beispiel denselben Bericht einmal pro Monat erstellen und an den Diagrammen ablesen, wie sich deine Positionen verändern.
  • Ziele unterschiedlich gewichten: Wie oben erwähnt, gehen wir davon aus, dass alle Ziele den gleichen Wert haben, aber das ist meist nicht der Fall. Füge für jedes Ziel deine eigene Gewichtung hinzu, beispielsweise, indem du der Wikipedia-Tabelle die jährliche Besucheranzahl entnimmst oder deine eigenen Daten zu Conversions, Sales und Profitabilität verrechnest.
  • Andere Keywords und Kombinationen ausprobieren: Die Reisebranche ist eine der kompliziertesten, wenn es darum geht, Keywords zu erzeugen und zu recherchieren. Es gibt so viele Möglichkeiten, eine Reiseabsicht auszudrücken (zum Beispiel: "New York", "New York City", "NY", "NYC", "JFK" – alle bedeuten dasselbe, wenn es um Reisen geht). Beachte, dass wir keinen Abflugort bestimmt haben, was einen großen Unterschied macht. Versuche auch "travel", "holidays" und/oder preisbezogene Keywords.
  • Dieselbe Methode auf YouTube-Suchergebnisse anwenden: advertools bietet eine ähnliche Funktion zum Abruf von YouTube-Suchergebnissen, also Daten zu Videos. Diese sind erheblich reichhaltiger, da sie Informationen über Aufrufe, Bewertungen, Anzahl der Kommentare, Metadaten zum Kanal und mehr einschließen.
  • Auf dem Notebook aufbauen: Anstatt das Rad neu zu erfinden, kannst du dir eine Kopie des hier genutzten Codes einschließlich der verarbeiteten Daten sichern oder die interaktive Version online ansehen (Du benötigst dazu deine eigenen Keys für die benutzerdefinierte Suchmaschine) und eine andere Analyse durchführen, oder auch andere Visualisierungen erstellen. Ich würde mich freuen, deine Ideen und Ansätze zu sehen.

Viel Erfolg!

Share
Author Photo
Seit 5 Jahren verantworte ich das Marketing von Semrush in den deutschsprachigen Ländern. Seit 2010 bin ich ein leidenschaftlicher SEO. Die Kombination aus SEO und Marketing setzte ich bei großen Projekten wie die Implementierung der SEO-Maßnahmen und Marketing-Prozessen bei einem großen Retailer. Dabei betreue ich auch kleine Projekte, denn auch mal Hand anzulegen, das macht mir viel Spass. Meine Erfahrung und mein Wissen teile ich gerne mit dir.