RStudio-Server updaten


Die AMIs von Louis Aslett sind nützlich, um kurz mal einen RStudio-Server auf einer AWS EC2-Instanz zu starten. Allerdings enthalten diese AMIs nicht immer die aktuelle Version von R oder RStudio. Diese beiden Befehle helfen, sowohl R als auch RStudio upzudaten:

sudo apt-get install gdebi-core<br /> wget https://download2.rstudio.org/rstudio-server-1.1.442-amd64.deb<br /> sudo gdebi rstudio-server-1.1.442-amd64.deb

echo "deb http://cran.stat.ucla.edu/bin/linux/ubuntu `lsb_release -sc`/" | sudo tee --append /etc/apt/sources.list.d/cran.list<br /> sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys E084DAB9<br /> sudo apt update<br /> apt list --upgradable

SEO-Monitoring mit R, AWS und Shiny


Dies ist der vorläufig letzte Teil der Serie über SEO mit R und AWS. Im ersten Teil hatten wir die AWS-Instanz mit RStudio vorbereitet, im zweiten Teil eine kleine SEO-Analyse durchgeführt, im dritten Teil ging es um die Erstellung eines Sichtbarkeitsindexes und eines “actionable Reportings”. In diesem Teil geht es darum, dass es selbst dem hartgesottensten Data Scientist zu anstrengend ist, die einzelnen Skripte täglich durch RStudio laufen zu lassen. Das SEO Monitoring soll also über eine ansprechende Oberfläche laufen.

GUI-Entwicklung mit Shiny

Die Entwickler von RStudio haben mit Shiny ein Framework zur Verfügung gestellt, welches Interaktion mit Daten ermöglicht, und das mit wenigen Zeilen Code. Glücklicherweise wird Shiny in dem AMI, das wir in Teil 1 dieser Serie installiert hatten, gleich mitgeliefert.

Der Code unterteilt sich in zwei Teile, dem Server-Code und dem UI-Code; beide Teile können in eine Datei, die dann als app.R in einen speziellen Ordner in RStudio abgelegt wird. In dem Server-Teil werden die einzelnen Funktionen genutzt, die wir für die ersten Teile dieser Serie verwendet haben (darum ist hier auch nicht der ganze Code zu finden).

`
server <- function(input, output, session) {

get data from db and create dropdown-items

sites <- unique(results$website)
output$moreControls <- renderUI({
selectInput(“moreControls”, “Website auswählen”, choices=sites)
output$sviPlot <- renderPlot({

Sichtbarkeitsindex-Code

})
output$actions <- renderTable({

Actionable Daten-Code

})
}
`

Im UI-Teil wird dann einfach nur das UI zusammengeschraubt:

<br /> ui <- fluidPage(<br /> title = "Tom's SEO Tool",<br /> uiOutput("moreControls"),<br /> hr(),<br /> plotOutput("sviPlot"),<br /> tableOutput("actions")<br /> )<br />

Und zum Schluß wird die App dann gestartet:

`

Run the application

shinyApp(ui = ui, server = server)
`

Das wars. Simpel und einfach:

Nicht unbedingt schön für einen Kunden, aber vollkommen ausreichend, um ein Reporting für sich selbst zu bauen. Links oben wähle ich die Webseite aus, für die ich das Reporting haben möchte, und nachdem die Skripte durchgelaufen sind, erscheint der Sichtbarkeitsindex-Plot sowie die Tabelle mit den größten Ranking-Verlusten. Das Erstellen dieses Dashboards hat gerade mal 20 Minuten gedauert (ok, fairerweise hatte ich auch schon mal andere Dashboards mit Shiny gebaut, so dass ich etwas Erfahrung hatte

Nächste Schritte

In meinem gegenwärtigen Setup habe ich einfach nur den Code genutzt, den ich bisher verwendet hatte, was aber auch bedeutet, dass es erst mal dauert, bis etwas zu sehen ist. Besser wäre es, wenn die Daten jeden Tag automatisch ausgewertet werden und das Dashboard dann einfach nur die aggregierten Daten abruft. Steht auf meiner Aufgabenliste.

Dann wäre es schön, wenn man in der Tabelle auf einen Eintrag klicken könnte, um dann diesen weiter zu analysieren. Steht auch auf meiner Aufgabenliste.

Eine Verbindung zu Google Analytics wäre toll.

Nicht jedes Keyword ist interessant und sollte in den Report kommen.

Alles gute Punkte, die ich beizeiten mal angehen könnte, und vor allem guter Stoff für weitere Posts Und ich bin immer offen für weitere Ideen

Fazit

Mit etwas Gehirnschmalz, wenig Code und der Hilfe von Amazon Web Services und R haben wir ein automatisiertes und kostenloses SEO-Reporting gebaut. Natürlich bieten Sistrix & Co noch mehr Funktionen. In diesem Ansatz geht es vor allem darum, die kostenlos zur Verfügung stehenden Daten aus der Webmaster Console besser zu nutzen. Denn sind wir mal ehrlich: Daten haben wir in der Regel genug. Wir machen nur meistens nicht viel daraus.

Diese Vorgehensweise hat noch einen Vorteil: Die Daten aus der Search Console sind nach 90 Tagen weg. Man kann nicht weiter zurück schauen. Hier aber bauen wir ein Archiv auf und können uns auch längerfristige Entwicklungen ansehen.

Ein eigener Sichtbarkeitsindex mit R und AWS


In der dritten Folge über Suchmaschinenoptimierung mit R und AWS geht es um das Erstellen eines eigenen Sichtbarkeitsindex, um eine aggregierte Übersicht über das Ranking vieler Keywords zu erhalten. Im ersten Teil hatten wir uns angeschaut, wie man mit R und einer AWS Free Tier EC2-Instanz automatisiert Daten aus der Webmaster Console zieht, im zweiten Teil ging es um erste Analysen anhand von Klickraten auf Positionen.

Was macht ein Sichtbarkeitsindex?

Dazu schauen wir erst einmal, was ein Sichtbarkeitsindex überhaupt leisten soll. Bei Sistrix ist der Sichtbarkeitsindex unabhängig von saisonalen Effekten, was ganz charmant ist, denn so weiß man schon im Sommer, ob man mit winterreifen.de einen Blumentopf gewinnen kann. Sowas kann zum Beispiel dadurch gelöst werden, dass man die durchschnittliche Anzahl von Suchen aus dem AdWords Keyword Planner nutzt. Dumm nur, dass dieses Tool nur noch dann einigermaßen nützliche Werte ausspuckt, wenn man auch ausreichend Budget in Google AdWords ausgibt. Dieser Ansatz fällt schon mal flach, denn wir wollen unser Monitoring so günstig wie möglich, bestenfalls kostenlos halten.

Sistrix hat den Nachteil, dass es a) für Studenten, die meine SEO-Kurse besuchen, trotz des günstigen Preises immer noch zu teuer ist und b) meine kleinen Nischengeschichten eben nicht immer vorhanden sind in der Sistrix-Keyword-Datenbank. Sistrix und Co. sind vor allem dann spannend, wenn man eine Seite mit anderen Seiten vergleichen will (idealerweise aus der gleichen Industrie mit dem gleichen Portfolio). Eine abstrakte Zahl wie ein Sichtbarkeitsindex von 2 ist ansonsten ziemlich sinnfrei. Diese Zahl ergibt nur dann Sinn, wenn ich sie in Bezug zu anderen Webseiten setzen kann und/oder wenn ich daraus die Entwicklung meiner eigenen Webseiten-Rankings im Zeitverlauf verfolgen kann. Die Zahl selbst ist dabei immer noch nicht aussagekräftig, denn in was für einer Metrik wird gemessen? Wenn ich 2 Kilo abnehme, dann ist die Metrik klar. Aber 0,002 SI abnehmen? Wie viele Besucher sind das?

Wir wollen uns einen Index bauen, der es uns ermöglicht zu schauen, ob sich unser Ranking über sehr viele Keywords im Zeitverlauf verändert. Wie sich unsere Marktbegleiter entwickeln, das ließe sich nur ablesen, wenn man Google scrapte, und das ist nicht erlaubt.

Sichtbarkeitsindex auf Basis der Webmaster Console

Offensichtlich ist es besser, mit einem Suchbegriff auf Platz 3 zu ranken, der 100 Mal am Tag gesucht wird als für einen Suchbegriff auf Platz 1, der nur 2 Mal am Tag gesucht wird. Die Anzahl der Suchen sollte also eine Rolle spielen in unserem Sichtbarkeitsindex. Das Suchvolumen über den AdWords Keyword Planner schließen wir aus den oben genannten Gründen aus, die einzige Quelle, die uns bleibt, sind die Impressions aus der Webmaster Console. Sobald wir auf der ersten Seite sind und weit genug oben (ich bin nicht sicher, ob es als Impression zählt, wenn man auf Platz 10 ist und nie im sichtbaren Bereich war), sollten wir die Anzahl der Impressions aus der Webmaster Console nutzen können, und das sogar auf Tagesbasis!

Kleiner Health-Check für das Keyword “Scalable Capital Erfahrungen” (AdWords / reale Daten aus der Webmaster Console):

  • 2400 / 1795 (September, aber nur halber Monat)
  • 5400 / 5438 (Oktober)
  • 1000 / 1789 (November)

Für September und Oktober sieht das gut aus, nur im November ist es etwas seltsam, dass ich knapp 80% mehr Impressions hatte als es angeblich Suchen gab. Irgendetwas muß ausserdem im September/Oktober passiert sein, dass Scalable Capital plötzlich so viele Suchen hatte. Tatsächlich war das auch im Traffic auf meiner Seite zu sehen. Den ersten Punkt kriegen wir nicht geklärt und akzeptieren, dass auch die AdWords-Zahlen nicht perfekt sind.

Wie unterschiedlich die Sichtbarkeits-Indices sind je nach Gewichtung, wird in den folgenden Abbildungen deutlich:

  • Im einfachsten Modell wird einfach nur 11 minus Position gerechnet, alles oberhalb von (größer als) Position 10 bekommt dann 1 Punkt. Pro Ergebnis werden die Daten für jeden Tag zusammengerechnet. Dieses Modell hat den Nachteil, dass ich ganz schnell nach oben klettern kann, selbst wenn ich nur Begriffe auf Platz 1 bin, die nur einmal im Monat gesucht werden.
  • Im zweiten Modell wird das gleiche Vorgehen gewählt, nur dass hier der Wert mit den Impressions multipliziert wird
  • Im dritten Modell wird die durchschnittliche CTR auf der SERP aus dem zweiten Teil dieser Serie mit den Impressions multipliziert.

Schaut man sich nun den tatsächlichen Traffic an, so sieht man, dass das 3. Modell dem Traffic schon sehr nahe kommt. Die Ausschläge im echten Traffic sind nicht ganz so stark wie im Index, und zum Schluss bekomme ich nicht so viel Traffic, allerdings kann das daran liegen, dass die tatsächliche CTR unter der erwarteten CTR liegt.

Alternativer Ansatz mit der Webmaster Console

Wenn man sich die Plots anschaut, dann wird aber klar, dass dieser Ansatz mit dem Impressions auf Tagesbasis wenig Sinn ergibt. Denn wenn die Kurve nach unten geht, dann bedeutet das nicht, dass ich auch etwas tun kann, denn eventuell wird nun mal einfach nur weniger nach diesem Thema gesucht und meine Rankings haben sich gar nicht geändert (normalerweise schreibt man ja nur darüber, was funktioniert, aber ich finde auch die Misserfolge spannend, denn daraus kann man eine Menge lernen :-)). Genau deswegen wird Sistrix wohl auch die saisonalen Schwankungen rausrechnen.

Alternativ könnte man einfach den Durchschnitt über alle Impression-Daten eines Keyword-Landing-Page-Paares bilden und diesen Durchschnitt zur Berechnung nutzen, wieder mit der gewichteten CTR pro Position. Das Gute an diesem Ansatz ist, dass sich saisonale oder temporäre Ausschläge ausgleichen. Geplottet sieht das wie folgt aus:

Dieser Plot sieht dem ersten Plot sehr ähnlich, was aber nicht bedeutet, dass das immer so sein muss. Doch wenn ich mir die Sistrix-Werte anschaue (auch wenn ich da auf einem ganz niedrigen Niveau unterwegs bin), dann sieht das schon sehr ähnlich aus.

Von Daten zur Handlungsrelevanz

Nun haben wir einen Plot, der uns die gewichtete Entwicklung unserer Rankings anzeigt, aber was machen wir nun damit? So richtig “actionable” ist das nicht. Spannend wird es erst, wenn wir uns zusätzlich anschauen, welche Rankings sich am meisten verändert und einen Einfluss auf unseren Sichtbarkeitsindex haben. Dazu nehmen wir uns wieder für jedes Keyword-Landing-Page-Paar zunächst das minimalste Ranking (minimal weil niedrig, und niedriger als Platz 1 gehts nicht) und dann das aktuelle Ranking. Zum Schluss berechnen wir das Delta und sortieren danach:

Je höher das Delta, desto größer ist sozusagen der Verlust an Ranking-Plätzen. Und desto größer der Handlungsbedarf, vorausgesetzt, dass das Keyword auch wirklich interessant ist. In meinem Beispiel fände ich es zum Beispiel nicht schlecht für “seo monitoring” zu ranken, schließlich sind die Artikel aus dieser Reihe relevant dafür. Man könnte nun noch gewichten anhand der Impressions oder dem Sichtbarkeitsindex, den wir vorher gewählt haben:

Das sieht schon spannender aus: Tatsächlich sind einige Suchanfragen oben (nach “Actionability” sortiert), die ich ganz interessant finde. Und nun könnte man das mit den Daten aus dem zweiten Teil verbinden und ein Dashboard bauen… dazu mehr im vierten Teil

“Actionable” SEO-Reporting mit R und AWS


In dem ersten Teil ging es darum, wie mit R und einer zunächst kostenlosen AWS-Instanz ein automatisiertes SEO-Monitoring erstellt wird. Dabei wird die Webmaster Console per API jeden Tag abgefragt, und die Daten werden in eine Datenbank geschrieben. Das Datensammeln allein bringt natürlich nichts, irgendwas sollten wir damit auch anfangen, und mein Mantra, das jeder Student in meinen Veranstaltungen mehrmals pro Tag hört, ist “Daten – Information – Aktion”. In den meisten Abhandlungen steht Wissen an der Stelle von Aktion, denn die Verarbeitung von Informationen erst schafft Wissen. Im Bereich der Datenanalyse oder sogar Data Science aber geht es häufiger darum, nicht nur zu wissen, sondern mit dem Wissen auch etwas zu tun, idealerweise zu wissen, was zu tun ist. Der Grund, warum die meisten Reportings nicht gelesen werden, ist in der Regel, dass keine Aktion abgeleitet werden kann. 5 Likes mehr diese Woche. Ja und? Was mache ich jetzt morgen anders? Wir wollen also nicht einfach nur ein SEO-Reporting bauen, sondern ein SEO-Reporting erstellen, das uns sagt, wo etwas zu tun ist und was man tun sollte. “Actionable” heißt es auf Neudeutsch, und eine richtig schöne Übersetzung gibt es tatsächlich nicht im Deutschen. “Handlungsrelevant”? Ist irgendwie nicht das Gleiche. Leben wir also zunächst mit diesem Begriff.

Der Mehrwert der Webmaster Console-API

Schauen wir uns erst einmal die Daten an, die wir aus der Webmaster Console bekommen haben. Hier ist nämlich schon eine Besonderheit zu sehen, die wir im Interface nicht bekommen. Dort bekommen wir entweder die Suchanfragen oder die Seiten, auf die die Nutzer nach dem Klick auf ein Suchergebnis kamen, aber nicht beides gleichzeitig. Das ist schon ein Mehrwert, denn wir können sozusagen Pärchen bilden aus Keyword und Landing Page. Eine Landing Page kann mehrere Keywords haben, umgekehrt übrigens auch, wenn für ein Keyword mehrere Seiten von einem Host ranken. Wir nutzen für unsere Auswertung diese Pärchen, um einen unique Identifier zu haben, zum Beispiel indem wir beides zusammenpacken und daraus einen MD5-Hash basteln (dem genauen Beobachter wird auffallen, dass die gleiche Kombination zwei Mal an einem Tag auftritt, aber das sieht nur so aus, denn die eine Version der URL hat noch ein /amp/ dahinter, was aber in der Tabelle nicht zu sehen ist).

Sollten wir das nicht schon beim Schreiben in die Tabelle getan haben, so tun wir es jetzt:

library(digest)<br /> i <- 1<br /> newResults <- results<br /> newResults["Hash"] <- NA<br /> for (i in i:nrow(newResults)) {<br /> newResults$Hash[i] <- digest(paste(newResults$query[i],newResults$page[i],sep=""))<br /> i <- i+1<br /> }

Sicherlich geht das mit apply noch hübscher, aber wir sind gerade im Hacker-Modus, nicht im Schön-Programmier-Modus

Eine weitere Besonderheit ist, dass wir uns wahrscheinlich im Interface nicht die Mühe machen werden, uns die Daten für jeden Tag einzeln anzuschauen. Das ist aber extrem hilfreich, denn die Voreinstellung in der Webmaster Console sind die letzten 28 Tage, und hier wird ein Durchschnitt für die einzelnen Werte berechnet. Die, die mich näher kennen, werden jetzt betreten auf den Boden schauen, denn ich sage hier immer wieder dasselbe: Der Durchschnitt, und zwar das arithmetische Mittel, ist der Feind der Statistik. Denn diese Art des Durschnitts zeigt uns nicht die Ausschläge. Dazu ein andermal mehr, wenn ich das Skript zur Datenanalyse-Veranstaltung mal online stelle. Der Punkt ist hier, dass ich im arithmetischen Mittel des Interfaces sehe, dass ein Keyword auf einer bestimmten Position gewesen ist in den letzten 28 Tagen, aber tatsächlich ist die Range pro Tag viel interessanter, denn wenn ich sie pro Tag abgreife, dann kann ich genauere Trends abbilden. Zu guter Letzt schenkt uns die Webmaster Console auch Impressions sowie Keywörter, die nicht in den Datenbanken der gängigen Tools zu finden sind. Sistrix, so sehr ich es auch liebgewonnen habe, findet mich nicht für “Cookidoo” oder “Scalable Capital”. Klar, ich könnte Sistrix meine Webmaster Console-Daten zur Verfügung stellen, aber das darf ich leider nicht bei jedem Projekt tun.

Da wir die Daten jeden Tag abfragen, können wir nun durch die Tabelle laufen und uns die Werte für den erstellten Identifer holen, so dass wir alle Werte für eine Keyword-Landingpage-Kombination erhalten und diese plotten können. Auf der x-Achse haben wir den Zeitverlauf, auf der y-Achse die Position. Hier sind übrigens zwei kleine R-Tricks zu sehen. R plottet nämlich normalerweise auf der Y-Achse vom niedrigen Wert nach oben zu einem höheren Wert. Und dann wird genau der Bereich erwischt, der für uns interessant ist, nämlich nicht alle Positionen von 1 bis 100, sondern nur der Bereich, wofür gerankt wurde. Der Plot benötigt nur wenige Zeilen Code:

maxValue <- max(currentQuery$position)<br /> minValue <- min(currentQuery$position)<br /> x <- minValue:maxValue<br /> query <- currentQuery$query[1]<br /> plot(df$Date,df$Position,ylim = rev(range(x)))<br /> title(main=query)

Wir sehen auf unserem Plot die Entwicklung des Rankings für ein Keyword, aber so richtig “actionable” ist es noch nicht. Wir schauen uns nun einmal daneben die CTR an:

Je höher die Position, desto höher die Klickrate. Das ist offensichtlich. Aber in diesen beiden Plots sieht man, dass zuerst die Klickrate runterging und dann die Position. Nicht dass die Klickrate der einzige Rankingfaktor wäre, aber eine schlechte Klickrate auf ein Ergebnis zeugt von einer suboptimalen wahrgenommenen Relevanz, und keine Suchmaschine möchte, dass die Ergebnisse als weniger relevant wahrgenommen werden. Hier wäre also ein Blick auf Titel und Description eine gute Handlungsempfehlung. Aber woher wissen wir eigentlich, was eine gute CTR für eine Position ist? Dazu können wir zum Beispiel einen Plot aus den eigenen Rankings nehmen:

Und diesen könnten wir vergleichen mit den Ergebnissen von Advanced Web Ranking, die Plots aus den Webmaster Console-Daten der Vielzahl ihrer Kunden erstellen. Jedes Land und jede Industrie ist anders, auch hängt die CTR von der SERP ab, ob vielleicht noch andere Elemente vorhanden sind, die die CTR beeinflussen. Aber allein aus dem Plot sieht man, dass bestimmte CTRs auf bestimmte Ergebnisse suboptimal sind. Hier müsste also “nur” noch ein Report erstellt werden, welche Keyword-Landingpage-Kombinationen unterdurchschnittlich sind.

Schauen wir uns den Plot mit den CTRs pro Position noch einmal genauer an, dann sehen wir ein paar ungewöhnliche Dinge. Zum einen gibt es immer ein paar Ergebnisse, wo ich egal auf welcher Position immer 100% CTR habe. Und dann gibt es zwischen den Positionen 1, 2, 3 und so weiter ganz viel Rauschen. Letzteres erklärt sich ganz leicht, denn die API gibt uns wie oben beschrieben durchschnittliche Positionen mit Nachkommastellen. Wir müssten also nur runden, um tatsächliche Positionen zu erhalten. Die 100% CTR betrifft vor allem Ergebnisse mit wenig Impressions. Werden zum Beispiel alle Ergebnisse rausgefiltert, die weniger als 10 Impressions pro Tag hatten, dann sieht das Bild schon anders aus:

Und siehe da, ich habe gar nicht so viele Nummer 1-Platzierungen mit mehr als einer homöopathischen Dosis an Impressions. Aber wenn ich die Augen etwas zukneife, so könnte ich eine Linie sehen. Und tatsächlich, berechnen wir die Mittelwerte (hier mit Summary), dann sehe ich eine nicht-lineare absteigende Kurve im Mean:<br /> Position 1:<br /> Min. 1st Qu. Median Mean 3rd Qu. Max.<br /> 0.2143 0.3971 0.4929 0.4828 0.5786 0.7059<br /> Position 2:<br /> Min. 1st Qu. Median Mean 3rd Qu. Max.<br /> 0.0000 0.2667 0.4118 0.3744 0.5000 0.7692<br /> Position 3:<br /> Min. 1st Qu. Median Mean 3rd Qu. Max.<br /> 0.0000 0.1176 0.1818 0.2217 0.3205 0.5769<br /> Position 4:<br /> Min. 1st Qu. Median Mean 3rd Qu. Max.<br /> 0.00000 0.08333 0.18182 0.17266 0.26667 0.45454<br /> Position 5:<br /> Min. 1st Qu. Median Mean 3rd Qu. Max.<br /> 0.0000 0.1240 0.1579 0.1584 0.2053 0.3200<br /> Position 6:<br /> Min. 1st Qu. Median Mean 3rd Qu. Max.<br /> 0.00000 0.06977 0.11765 0.12223 0.16667 0.30769<br /> Position 7:<br /> Min. 1st Qu. Median Mean 3rd Qu. Max.<br /> 0.00000 0.05043 0.09091 0.09246 0.13229 0.22222<br /> Position 8:<br /> Min. 1st Qu. Median Mean 3rd Qu. Max.<br /> 0.00000 0.00000 0.03880 0.04594 0.08052 0.19048<br /> Position 9:<br /> Min. 1st Qu. Median Mean 3rd Qu. Max.<br /> 0.00000 0.00000 0.00000 0.01412 0.01205 0.16514<br /> Position 10:<br /> Min. 1st Qu. Median Mean 3rd Qu. Max.<br /> 0.000000 0.000000 0.000000 0.010284 0.004045 0.093023

Im nächsten Schritt müssen wir also “nur” noch auswerten, welches Ergebnis unter einer bestimmten Grenze der CTR liegt. Glücklicherweise existiert in der Statistik eine Maßzahl, die uns hilft, die Streuung um einen Mittelwert zu identifizieren, die Standardabweichung. Diese wird hier jetzt nicht erklärt (aber im Skript zur Datenanalyse-Veranstaltung). Aber auf dem Weg zur Standardabweichung sollten wir uns eine Übersicht über die Verteilung der CTRs ansehen. Wie man schön sehen kann, sieht das nach einer Normalverteilung aus. Nun berechnen wir guten Gewissens die Standardabweichung pro Position:

<br /> [1] 0.139202<br /> [2] 0.1691641<br /> [3] 0.1405702<br /> [4] 0.1116699<br /> [5] 0.07492808<br /> [6] 0.07420478<br /> [7] 0.05702427<br /> [8] 0.05028635<br /> [9] 0.03001044<br /> [10] 0.02134183

Für die Position 1 könnten wir also rechnen Mittelwert minus Standardabweichung gleich Ergebnis mit Klickrate, das Beachtung verdient, hier

0.4828 - 0.139202 = 0.3436019

Alle Ergebnisse mit einer gerundeten Position 1 und einer CTR von 0.43… verdienen also Beachtung. In meinem Fall sind das die Suchanfragen für scalable capital erfahrung und cookidoo. Zwar gibt es auch CTRs an manchen Tagen über dem Durchschnitt, aber manchmal fallen sie drunter. Dies wird dann für jede Position wiederholt.

Zu viele Daten?

Wir haben nun ein Problem. Denn mein Blog ist noch eine relativ kleine Seite. Was machen wir mit einer Seite mit vielen Keywords und vielen Rankings? Dazu kommen wir beim nächsten Mal, indem wir einen eigenen Sichtbarkeitsindex erstellen.

Kostenloses und automatisiertes SEO-Monitoring mit R und AWS


Langsam hält R Einzug in die Welt der Suchmaschinenoptimierung, und auch wenn R am Anfang etwas verwirrend sein mag (funktionale Programmierung anstatt prozedural), so kann man mit wenigen Zeilen Code coole Sachen bauen. Als Beispiel soll hier ein kostenloses SEO-Monitoring dienen, das natürlich kein bisschen mit Sistrix und Co mithalten kann, aber wenn man nur seine eigenen Rankings verfolgen will, dann ist dies eine tolle und vor allem kostenlose Lösung.

Fangen wir mit der Infrastruktur an, wir benötigen nur drei Komponenten:

  • Eine (kostenlose) EC2-Instanz
  • Einen Google Webmaster-Account
  • Einen Google API-Service Account

Amazon bietet EC2-Instanzen im “free tier” (kostenlosen Kontingent) an, nach 12 Monaten wird hier zwar eine Gebühr fällig, aber die ist eher im homöopathischen Bereich. Die t2.micro-Instanz ist relativ schwach auf der Brust mit ihrer einen vCPU, 1GB RAM und 30GB SSD, aber für unsere Zwecke reicht sie vollkommen aus. R ist natürlich nicht von vornherein vorhanden, ABER Luis Aslett bietet kostenlose AMIs (Amazon Machine Images) an, wo RStudio Server bereits vorkonfiguriert ist. Matt erklärt sehr gut, wie man mit diesen AMIs seine eigene RStudio-Instanz auf AWS installiert. Das alles dauert maximal 15 Minuten, schon hat man seinen eigenen kostenlosen RStudio Server-Rechner in der AWS-Cloud. Große Berechnungen sind damit nicht möglich, aber ist man erst einmal auf den Geschmack gekommen, so findet man sich schnell in der Situation wieder, dass mal kurz eine Instanz mit viel Speicher für größere Rechenaufgaben genutzt wird. Ein Klick, ein paar Euro am Tag, und schon hat man ein ganzes Cluster mit 16 Prozessoren und 128 GB RAM für sich. Aber ich schweife ab.

Im nächsten Schritt nehmen wir das R Package searchConsoleR von Mark Edmonson. Dies ist der elementare Grundstein unseres SEO-Monitoring. In Marks Beispiel schreibt er die Daten einfach auf Platte, aber wir wollen die Daten lieber in eine Datenbank schreiben (wie man MySQL auf unserer frisch erworbenen EC2-Instanz installiert steht hier. Bitte beachten, dass man nur einen Nutzer “ubuntu” hat, d.h. man muss alles mit sudo erledigen; ansonsten kann man kostenpflichtig auch eine RDS-Instanz buchen). Um von einem Server auf die Webmaster Console-Daten zugreifen zu können, wird ein Service Account benötigt. Dieser ist nicht ganz so einfach aufzusetzen, aber das würde den Rahmen dieses Artikels sprengen. Wichtig ist, dass die Mail-Adresse des Service Accounts als ganzer Nutzer in der Webmaster Console eingetragen wird. Und hier ist nun der Code:

library(jsonlite) library(googleAuthR) library(searchConsoleR) library(RMySQL) options(googleAuthR.scopes.selected=“https://www.googleapis.com/auth/webmasters“)` gar_auth_service( json_file = “/home/rstudio/XXXXXXX.json”, scope = “https://www.googleapis.com/auth/webmasters” )

Wir holen uns die Daten von vor 5 Tagen, dann sind sie auf jeden Fall in der Webmaster Console vorhanden:

delay <- 5 start <- Sys.Date() – delay end <- Sys.Date() – delay

Hier nun die Abfrage:

website <;- “XXXXX” download_dimensions <- c(‘query’,‘page’) type <- c(‘web’) sc_data <- search_analytics(siteURL = website, startDate = start, endDate = end, dimensions = download_dimensions, searchType = type)

Wir fügen noch ein Datum und die Webseite hinzu (falls wir mehrere Webseiten abfragen)

sc_data7 <- website sc_data8 <- start colnames(sc_data)7 <- “website” colnames(sc_data)8 <- “date”

Jetzt schreiben wir den Dataframe in die Datenbank (die DB und die Tabelle haben wir vorher bereits hinzugefügt):

mydb = dbConnect(MySQL(), user=‘XXXXX’, password=‘XXXXX’, host=‘XXXXX’) dbSendQuery(mydb, “USE XXXXX”) dbWriteTable(mydb, value = sc_data, name = “rankings”, append = TRUE, row.names = FALSE) dbDisconnect(mydb)

Nun fehlt uns nur noch ein Cronjob, der täglich diese Abfrage durchführt. Dazu nutze ich zunächst ein kleines Shell-Skript, das dann das R-Skript aufruft:

cd /home/rstudio/SearchConsole/ Rscript /home/rstudio/SearchConsole/rankings.R

Dann wird mit sudo crontab -e der Cronjob eingerichtet, mein Cronjob startet jeden Tag um 10:30, bzw 11:30, denn die Instanz ist in einer anderen Zeitzone:

30 10 * * * /home/rstudio/SearchConsole/rankings.sh 2>&1 | /usr/bin/logger -t rstudio

Wichtig: Newline nach der letzten Zeile, sonst meckert cron. Fertig ist das automatische und kostenlose SEO-Monitoring! In einem der nächsten Postings zeige ich, wie man die Daten dann auswerten kann.