Als je webscraping wilt doen, maak je normaal gesproken gebruik van Hadley Wickham’s rvest-pakket. Dit pakket biedt een gebruiksklare, eenvoudige oplossing om de html-code op te halen die een webpagina genereert. Maar wanneer de website of webpagina JavaScript gebruikt om de data te tonen waarin je geïnteresseerd bent, mist het rvest-pakket de benodigde functionaliteit. Een oplossing is het gebruik van PhantomJS.
(Wil je meer oefenen met het importeren van data in R? Probeer deze tutorial.)
Laad de benodigde pakketten
Als eerste stap moet je alle pakketten die we voor deze analyse nodig hebben in de workspace laden (als je deze pakketten nog niet lokaal hebt geïnstalleerd, gebruik dan install.packages() om ze beschikbaar te maken):
library(rvest)
library(stringr)
library(plyr)
library(dplyr)
library(ggvis)
library(knitr)
options(digits =4)Mogelijk gemaakt door
JavaScript-gegenereerde data scrapen met R
De volgende stap is het verzamelen van de TechStars-data met PhantomJS. Bekijk het volgende basis-.js-bestand:
// scrape_techstars.js
var webPage = require('webpage');
var page = webPage.create();
var fs = require('fs');
var path ='techstars.html'
page.open('http://www.techstars.com/companies/stats/',function(status){
var content = page.content;
fs.write(path,content,'w')
phantom.exit();});Mogelijk gemaakt door
Het script rendert in feite de HTML-pagina nadat de onderliggende JavaScript-code zijn werk heeft gedaan, zodat je de HTML-pagina kunt ophalen met alle tabellen erin. Om voor de rest van deze analyse in R te blijven, raden we aan de functie system() te gebruiken om PhantomJS aan te roepen (je moet PhantomJS downloaden en installeren en in je werkmap zetten):
# Laat phantomJS techstars scrapen, uitvoer wordt weggeschreven naar techstars.html
system("./phantomjs scrape_techstars.js")Mogelijk gemaakt door
Na deze kleine omweg heb je eindelijk een HTML-bestand, techstars.html, op ons lokale systeem, dat gescrapet kan worden met rvest. Inspectie van de Techstars-webpagina laat zien dat de tabellen waarin we geïnteresseerd zijn zich bevinden in divs met de css-klasse batch:
batches <- html("techstars.html")%>%
html_nodes(".batch")
class(batches)Mogelijk gemaakt door
Je hebt nu een lijst met XMLNodeSet-objecten: elk object bevat de data voor één TechStars-batch. Daarin vinden we informatie over de locatie van de batch, het jaar, het seizoen, maar ook over de bedrijven, hun huidige hoofdkantoor, hun huidige status en het totale bedrag aan opgehaald kapitaal. We gaan hieronder niet in op de details van de dataverzamelings- en opschoonstappen; je kunt de code zelf uitvoeren en bekijken wat deze doet. Je zult zien dat er wat maatwerkopschoning plaatsvindt om ervoor te zorgen dat elk beetje informatie netjes is opgemaakt:
batch_titles <- batches %>%
html_nodes(".batch_class")%>%
html_text()
batch_season <- str_extract(batch_titles,"(Fall|Spring|Winter|Summer)")
batch_year <- str_extract(batch_titles,"([[:digit:]]{4})")# locatie-informatie is alles in de batchtitel dat geen jaar- of seizoensinfo is
batch_location <- sub("\\s+$","",
sub("([[:digit:]]{4})","",
sub("(Fall|Spring|Winter|Summer)","",batch_titles)))# maak een data frame met batchinfo
batch_info <- data.frame(location = batch_location,
year = batch_year,
season = batch_season)
breakdown <- lapply(batches,function(x){
company_info <- x %>% html_nodes(".parent")
companies_single_batch <- lapply(company_info,function(y){
as.list(gsub("\\[\\+\\]\\[\\-\\]\\s","", y %>%
html_nodes("td")%>%
html_text()))})
df <- data.frame(matrix(unlist(companies_single_batch),
nrow=length(companies_single_batch),
byrow=T,
dimnames = list(NULL, c("company","funding","status","hq"))))
return(df)})# Voeg batchinfo toe aan breakdown
batch_info_extended <- batch_info[rep(seq_len(nrow(batch_info)),
sapply(breakdown, nrow)),]
breakdown_merged <- rbind.fill(breakdown)# Voeg alle informatie samen
techstars <- tbl_df(cbind(breakdown_merged, batch_info_extended))%>%
mutate(funding = as.numeric(gsub(",","",gsub("\\$","",funding))))Mogelijk gemaakt door
Met een combinatie van core R-, rvest-, plyr- en dplyr-functies hebben we nu het techstars-dataframe: een dataset van alle TechStars-bedrijven, met alle publiek beschikbare informatie die netjes is opgemaakt:
## [1] "company" "funding" "status" "hq" "location" "year"## [7] "season"Mogelijk gemaakt door
Conclusie
Met de bovenstaande combinatie van tools en code is het gelukt om data te scrapen van een website die een JavaScript-script gebruikt om zijn data te genereren. Zoals je ziet is dit een zeer gestructureerd proces dat eenvoudig uit te voeren is zodra de initiële code beschikbaar is. Wil je R leren en ben je op zoek naar data science- en R-tutorials en -cursussen? Kijk dan eens bij DataCamp
Als je webscraping wilt doen, maak je normaal gesproken gebruik van Hadley Wickham’s
rvest-pakket. Dit pakket biedt een gebruiksklare, eenvoudige oplossing om de html-code op te halen die een webpagina genereert. Maar wanneer de website of webpagina JavaScript gebruikt om de data te tonen waarin je geïnteresseerd bent, mist hetrvest-pakket de benodigde functionaliteit. Een oplossing is het gebruik van PhantomJS.(Wil je meer oefenen met het importeren van data in R? Probeer deze tutorial.)
Laad de benodigde pakketten
Als eerste stap moet je alle pakketten die we voor deze analyse nodig hebben in de workspace laden (als je deze pakketten nog niet lokaal hebt geïnstalleerd, gebruik dan
install.packages()om ze beschikbaar te maken):JavaScript-gegenereerde data scrapen met R
De volgende stap is het verzamelen van de TechStars-data met PhantomJS. Bekijk het volgende basis-.js-bestand:
Het script rendert in feite de HTML-pagina nadat de onderliggende JavaScript-code zijn werk heeft gedaan, zodat je de HTML-pagina kunt ophalen met alle tabellen erin. Om voor de rest van deze analyse in R te blijven, raden we aan de functie
system()te gebruiken om PhantomJS aan te roepen (je moet PhantomJS downloaden en installeren en in je werkmap zetten):Na deze kleine omweg heb je eindelijk een HTML-bestand,
techstars.html, op ons lokale systeem, dat gescrapet kan worden metrvest. Inspectie van de Techstars-webpagina laat zien dat de tabellen waarin we geïnteresseerd zijn zich bevinden in divs met de css-klassebatch:Je hebt nu een lijst met
XMLNodeSet-objecten: elk object bevat de data voor één TechStars-batch. Daarin vinden we informatie over de locatie van de batch, het jaar, het seizoen, maar ook over de bedrijven, hun huidige hoofdkantoor, hun huidige status en het totale bedrag aan opgehaald kapitaal. We gaan hieronder niet in op de details van de dataverzamelings- en opschoonstappen; je kunt de code zelf uitvoeren en bekijken wat deze doet. Je zult zien dat er wat maatwerkopschoning plaatsvindt om ervoor te zorgen dat elk beetje informatie netjes is opgemaakt:Met een combinatie van core R-,
rvest-,plyr- endplyr-functies hebben we nu hettechstars-dataframe: een dataset van alle TechStars-bedrijven, met alle publiek beschikbare informatie die netjes is opgemaakt:Conclusie
Met de bovenstaande combinatie van tools en code is het gelukt om data te scrapen van een website die een JavaScript-script gebruikt om zijn data te genereren. Zoals je ziet is dit een zeer gestructureerd proces dat eenvoudig uit te voeren is zodra de initiële code beschikbaar is. Wil je R leren en ben je op zoek naar data science- en R-tutorials en -cursussen? Kijk dan eens bij DataCamp