Kurs
Wenn du Web Scraping betreiben willst, greifst du normalerweise zu Hadley Wickhams rvest-Paket. Dieses Paket bietet eine einfache, sofort einsetzbare Lösung, um den HTML-Code abzurufen, der eine Webseite erzeugt. Nutzt die Seite oder Unterseite jedoch JavaScript, um die für dich interessanten Daten anzuzeigen, fehlt rvest die nötige Funktionalität. Eine Lösung ist der Einsatz von PhantomJS.
(Du willst mehr Daten nach R importieren? Probiere dieses Tutorial.)
\nLade die benötigten Pakete
\nAls ersten Schritt lädst du alle Pakete, die wir für diese Analyse brauchen, in den Workspace (falls du sie lokal noch nicht installiert hast, nutze install.packages(), um sie verfügbar zu machen):
library(rvest)\nlibrary(stringr)\nlibrary(plyr)\nlibrary(dplyr)\nlibrary(ggvis)\nlibrary(knitr)\noptions(digits = 4)\n\nJavaScript-generierte Daten mit R scrapen
\nAls Nächstes sammeln wir die TechStars-Daten mit PhantomJS. Sieh dir diese einfache .js-Datei an:
\n// scrape_techstars.js\n\nvar webPage = require('webpage');\nvar page = webPage.create();\n\nvar fs = require('fs');\nvar path = 'techstars.html'\n\npage.open('http://www.techstars.com/companies/stats/', function (status) {\n var content = page.content;\n fs.write(path,content,'w')\n phantom.exit();\n});\n\nDas Skript rendert die HTML-Seite, nachdem der zugrunde liegende JavaScript-Code seine Arbeit erledigt hat. So kannst du die HTML-Seite inklusive aller Tabellen abrufen. Damit wir für den Rest der Analyse in R bleiben, empfehlen wir, die Funktion system() zu nutzen, um PhantomJS aufzurufen (du musst PhantomJS herunterladen und installieren und in dein Arbeitsverzeichnis legen):
# Lass PhantomJS Techstars scrapen, die Ausgabe wird in techstars.html geschrieben\nsystem(\"./phantomjs scrape_techstars.js\")\n\nNach diesem kurzen Abstecher hast du endlich eine HTML-Datei, techstars.html, auf deinem lokalen System, die sich mit rvest scrapen lässt. Eine Inspektion der Techstars-Webseite zeigt, dass die Tabellen, die uns interessieren, in Divs mit der CSS-Klasse batch liegen:
batches <- html(\"techstars.html\") %>%\n html_nodes(\".batch\")\n\nclass(batches)\n\n[1] \"XMLNodeSet\"\n\nDu hast jetzt eine Liste von XMLNodeSet-Objekten: Jedes Objekt enthält die Daten für eine einzelne TechStars-Batch. Darin finden wir Informationen zum Standort, Jahr und zur Saison, aber auch zu den Unternehmen, ihren aktuellen Hauptsitzen, ihrem aktuellen Status und der gesamten eingeworbenen Finanzierung. Wir gehen unten nicht ins Detail der Datensammlung und -bereinigung; du kannst den Code selbst ausführen und prüfen, was er leistet. Du wirst sehen, dass einige individuelle Bereinigungsschritte nötig sind, damit jede Information sauber formatiert ist:
batch_titles <- batches %>%\n html_nodes(\".batch_class\") %>%\n html_text()\n\nbatch_season <- str_extract(batch_titles, \"(Fall|Spring|Winter|Summer)\")\nbatch_year <- str_extract(batch_titles, \"([[:digit:]]{4})\")\n# location info is everything in the batch title that is not year info or season info\nbatch_location <- sub(\"\\\\s+$\", \"\",\n sub(\"([[:digit:]]{4})\", \"\",\n sub(\"(Fall|Spring|Winter|Summer)\",\"\",batch_titles)))\n\n# create data frame with batch info.\nbatch_info <- data.frame(location = batch_location,\n year = batch_year,\n season = batch_season)\n\nbreakdown <- lapply(batches, function(x) {\n company_info <- x %>% html_nodes(\".parent\")\n companies_single_batch <- lapply(company_info, function(y){\n as.list(gsub(\"\\\\[\\\\+\\\\]\\\\[\\\\-\\\\]\\\\s\", \"\", y %>%\n html_nodes(\"td\") %>%\n html_text()))\n })\n df <- data.frame(matrix(unlist(companies_single_batch),\n nrow=length(companies_single_batch),\n byrow=T,\n dimnames = list(NULL, c(\"company\",\"funding\",\"status\",\"hq\"))))\n return(df)\n})\n\n# Add batch info to breakdown\nbatch_info_extended <- batch_info[rep(seq_len(nrow(batch_info)),\n sapply(breakdown, nrow)),]\nbreakdown_merged <- rbind.fill(breakdown)\n\n# Merge all information\ntechstars <- tbl_df(cbind(breakdown_merged, batch_info_extended)) %>%\n mutate(funding = as.numeric(gsub(\",\",\"\",gsub(\"\\\\$\",\"\",funding))))\n\nMit einer Kombination aus Base R, rvest, plyr und dplyr haben wir nun den Data Frame techstars: einen Datensatz aller TechStars-Unternehmen mit allen öffentlich verfügbaren, sauber formatierten Informationen:
techstars\n\n## Source: local data frame [535 x 7]\n##\n## company funding status hq location year season\n## 1 Accountable 110000 Active Fort Worth, TX Austin 2013 Fall\n## 2 Atlas 1180000 Active Austin, TX Austin 2013 Fall\n## 3 Embrace 110000 Failed Austin, TX Austin 2013 Fall\n## 4 Filament Labs 1490000 Active Austin, TX Austin 2013 Fall\n## 5 Fosbury 300000 Active Austin, TX Austin 2013 Fall\n## 6 Gone! 840000 Active San Francisco, CA Austin 2013 Fall\n## 7 MarketVibe 110000 Acquired Austin, TX Austin 2013 Fall\n## 8 Plum 1630000 Active Austin, TX Austin 2013 Fall\n## 9 ProtoExchange 110000 Active Austin, TX Austin 2013 Fall\n## 10 Testlio 1020000 Active Austin, TX Austin 2013 Fall\n## .. ... ... ... ... ... ... ...\n\nnames(techstars)\n\n## [1] \"company\" \"funding\" \"status\" \"hq\" \"location\" \"year\"\n## [7] \"season\"\n\nFazit
\nMit der obigen Kombination aus Tools und Code konnten wir Daten von einer Website scrapen, die JavaScript zur Datenerzeugung nutzt. Wie du siehst, ist das ein klar strukturierter Prozess, der sich leicht wiederholen lässt, sobald der initiale Code steht. Du willst R lernen und suchst Data-Science- und R-Tutorials sowie Kurse? Schau dir DataCamp an.
\n