Cours
Lorsque vous devez faire du web scraping, vous utiliserez généralement le package rvest de Hadley Wickham. Ce package offre une solution simple et prête à l'emploi pour récupérer le code HTML d'une page web. Cependant, lorsque le site ou la page s'appuie sur JavaScript pour afficher les données qui vous intéressent, le package rvest n'intègre pas la fonctionnalité requise. Une solution consiste à utiliser PhantomJS.
(Vous voulez pratiquer l'import de données dans R ? Essayez ce tutoriel.)
Charger les packages nécessaires
Première étape : chargez dans l'espace de travail tous les packages utiles à cette analyse (si vous ne les avez pas encore installés localement, utilisez install.packages() pour les rendre disponibles) :
library(rvest)
library(stringr)
library(plyr)
library(dplyr)
library(ggvis)
library(knitr)
options(digits = 4)
Extraire des données générées en JavaScript avec R
L'étape suivante consiste à collecter les données TechStars avec PhantomJS. Voici un fichier .js basique :
// 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();
});
Ce script rend la page HTML après l'exécution du code JavaScript sous-jacent, ce qui vous permet de récupérer la page avec tous ses tableaux. Pour rester dans R pour le reste de l'analyse, nous vous suggérons d'utiliser la fonction system() pour invoquer PhantomJS (vous devrez télécharger et installer PhantomJS et le placer dans votre répertoire de travail) :
# Laisser phantomJS aspirer techstars, la sortie est écrite dans techstars.html
system("./phantomjs scrape_techstars.js")
Après ce court détour, vous disposez enfin en local d'un fichier HTML, techstars.html, que vous pouvez aspirer avec rvest. L'inspection de la page Techstars révèle que les tableaux qui nous intéressent se trouvent dans des divs portant la classe CSS batch :
batches <- html("techstars.html") %>%
html_nodes(".batch")
class(batches)
[1] "XMLNodeSet"
Vous avez maintenant une liste d'objets XMLNodeSet : chaque objet contient les données d'une promotion TechStars. On y trouve des informations sur le lieu, l'année et la saison, ainsi que sur les entreprises, leur siège actuel, leur statut et le montant total des financements levés. Nous ne détaillons pas ci-dessous toutes les étapes de collecte et de nettoyage ; exécutez le code et observez le résultat. Vous verrez quelques nettoyages sur mesure pour garantir un formatage homogène de chaque information :
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})")
# location info is everything in the batch title that is not year info or season info
batch_location <- sub("\\s+$", "",
sub("([[:digit:]]{4})", "",
sub("(Fall|Spring|Winter|Summer)","",batch_titles)))
# create data frame with batch info.
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)
})
# Add batch info to breakdown
batch_info_extended <- batch_info[rep(seq_len(nrow(batch_info)),
sapply(breakdown, nrow)),]
breakdown_merged <- rbind.fill(breakdown)
# Merge all information
techstars <- tbl_df(cbind(breakdown_merged, batch_info_extended)) %>%
mutate(funding = as.numeric(gsub(",","",gsub("\\$","",funding))))
Avec une combinaison de fonctions R de base, rvest, plyr et dplyr, nous disposons maintenant du data frame techstars : un jeu de données sur toutes les entreprises TechStars, avec les informations publiques proprement formatées :
techstars
## Source: local data frame [535 x 7]
##
## company funding status hq location year season
## 1 Accountable 110000 Active Fort Worth, TX Austin 2013 Fall
## 2 Atlas 1180000 Active Austin, TX Austin 2013 Fall
## 3 Embrace 110000 Failed Austin, TX Austin 2013 Fall
## 4 Filament Labs 1490000 Active Austin, TX Austin 2013 Fall
## 5 Fosbury 300000 Active Austin, TX Austin 2013 Fall
## 6 Gone! 840000 Active San Francisco, CA Austin 2013 Fall
## 7 MarketVibe 110000 Acquired Austin, TX Austin 2013 Fall
## 8 Plum 1630000 Active Austin, TX Austin 2013 Fall
## 9 ProtoExchange 110000 Active Austin, TX Austin 2013 Fall
## 10 Testlio 1020000 Active Austin, TX Austin 2013 Fall
## .. ... ... ... ... ... ... ...
names(techstars)
## [1] "company" "funding" "status" "hq" "location" "year"
## [7] "season"
Conclusion
Avec cette combinaison d'outils et de code, nous avons réussi à extraire des données depuis un site qui utilise JavaScript pour les générer. Comme vous pouvez le voir, le processus est très structuré et devient simple une fois le code initial en place. Vous souhaitez apprendre R et cherchez des tutos et cours en data science et R ? Découvrez DataCamp