Ce tutoriel a pour ambition d’expliquer comment extraire des données d’une page web à l’aide du logiciel R et de montrer quelques opérations courantes de traitement des données pour les rendre exploitables.
Le tutoriel est composé de trois parties :
- Données sous forme de tableau
- Données structurées
- Données sur plusieurs pages
Données sur plusieurs pages
Très souvent, les données que l’on désire extraire se trouvent sur plusieurs pages. Lorsqu’il n’y a que quelques pages, il est possible d’extraire les données de chaque page individuellement. Mais si le nombre de pages est conséquent, alors il est préférable d’automatiser l’extraction des données
Imaginons par exemple que l’on souhaite récupérer des informations sur tous les participants de la compétition dont j’ai parlé dans la première partie du tutoriel. Pour chaque participant, les informations nécessaires sont contenues dans la page de son profil. Pour récolter les données nécessaires, il faut donc visiter autant de pages qu’il y a de participants.
Un autre cas de figure fréquent est la présence de « pagers». Souvent, lorsqu’une liste d’éléments est trop longue pour être affichée sur une seule page web, elle est découpée en morceaux de taille égale et chaque morceau de la liste est visible sur une page différente.
Dans tous les cas de figure, la méthodologie est la même :
- Récupérer ou construire une liste des URL de toutes les pages où se trouvent les données.
- Écrire une fonction qui prend en argument une URL et qui renvoie les données extraites de la page associée à l’URL.
- Appliquer la fonction de l’étape 2 à la liste des URL de l’étape 1, en prenant soin d’enregistrer les URL qui ont posé problème.
Récupération des URL
Il y a deux méthodes pour récupérer la liste des URL d’où les données doivent être extraites. Dans le cas de figure le plus simple, il existe une page web qui répertorie toutes les pages dont on a besoin. Il suffit alors d’extraire les URL comme expliqué dans la deuxième partie du tutoriel. Dans le cas de la compétition Kaggle, on trouve à l’aide de l’explorateur web que les liens vers les profils des participants sont des éléments « a » contenus dans des « li » contenus dans des « ul » de classe « team-members ».

A l'aide de l'inspecteur web, on repère où se trouvent les liens à récupérer dans la structure de la page web. Ici, ils sont dans un "a" contenu dans un "li" contenu dans un "ul" de classe "team-members".
L’extraction des liens se fait donc à l’aide de la commande suivante :
library(XML) doc <- htmlParse("http://www.kaggle.com/c/RTA/Leaderboard") lien <- xpathSApply(doc, "//ul[@class='team-members']/li/a", xmlGetAttr, name="href") head(lien) [1] "/users/4410/jose-p-gonzalez-brenes" "/users/4426/guido-matias-cortes" [3] "/users/4398/sergey-yurgenson" "/users/5596/alisson-azzolini" [5] "/users/4737/zico-kolter" "/users/6016/andre-ricardo-goncalves"
On peut remarquer que toutes les URL de profils sont construites de la même manière : on a d’abord l’adresse du site, puis un slash, puis « users », puis un slash, puis un numéro probablement unique pour chaque utilisateur, encore un slash et enfin le nom de l’utilisateur avec des tirets à la place des espaces.
Bon, ça ne nous aide pas, car on a le nom des participants, mais on ne connaît pas le numéro qui leur est associé. Comme le site est relativement jeune, le nombre d’utilisateurs est relativement faible. On pourrait donc à l’aide d’une boucle tester tous les numéros jusqu’à tomber sur celui qui correspond à l’utilisateur.
Heureusement, dans la plupart des situations, on n’a pas besoin de faire des choses aussi biscornues pour deviner les URL. Il faut savoir qu’une URL n’est pas seulement utilisée pour trouver un document, elle sert aussi à passer des paramètres à des scripts. Il est facile de les repérer : ils se trouvent après un point d’interrogation et sont séparés par le symbole “&”. Très souvent, pour passer d’une page à l’autre, il suffit de changer la valeur d’un des paramètres. Regardons par exemple le forum de la compétition. Comme le nombre de sujets est important, la liste des sujets se trouve sur trois pages dont les URL sont les suivantes :
http://www.kaggle.com/c/RTA/forums http://www.kaggle.com/c/RTA/forums?page=2 http://www.kaggle.com/c/RTA/forums?page=3
Par défaut, l’argument “page” est sans doute égal à 1 ; c’est pour ça qu’il n’apparait pas dans la première adresse. Il apparait clairement que pour passer à la page suivante du forum, il suffit d’incrémenter la variable “page” de 1. Dans R, on pourrait construire la liste des URL à l’aide de la fonction sprintf par exemple :
sprintf("http://www.kaggle.com/c/RTA/forums?page=%s", 1:3)
Fonction d’extraction
Une fois la liste des URL récupérées, il faut écrire une fonction qui extrait les informations qui nous intéressent de la page qu’on lui spécifie. Elle ressemble donc à quelque chose comme ça :
extracteur <- function(url) { doc <- htmlParse(url) v1 <- xpathSApply(doc, …) v2 <- xpathSApply(doc, ...) return(data.frame(v1, v2) }
Reportez-vous aux deux premières parties du tutoriel pour savoir quoi mettre à l’intérieur de cette fonction. Par ailleurs, faites bien attention au fait que les différentes pages peuvent différer d’une manière telle que votre fonction peut marcher sur une page et pas sur une autre. Essayez d’écrire une fonction aussi générale que possible.
Extraction des données
Pour extraire les données, il suffit d’appliquer la fonction extracteur à toutes les adresses qu’on a collectées ou construites, à l’aide d’une boucle “for”. Ensuite, on concatène les données collectées à l’aide de la fonction “rbind” pour les “data.frame” et les matrices ou “c” pour les listes et les vecteurs. Mais il faut faire attention à une chose : il est très fréquent que la fonction “extracteur” ne fonctionne pas sur certaines pages, car on a oublié de considérer quelques cas particuliers. Dans ce cas, l’exécution de la boucle est stoppée et il est souvent nécessaire de tout recommencer.
Pour éviter cela, il est prudent d’utiliser la fonction “try”. Cette fonction empêche l’arrêt du programme suite à une erreur quelconque. Il est également prudent de créer une variable où l’on stocke toutes les adresses qui ont posé problème. On peut ainsi comprendre d’où vient le problème, voir si ça vaut la peine de le corriger (parfois, le problème concerne un nombre trop limité de données pour qu’il mérite notre attention), puis exécuter une fonction corrigée uniquement sur les pages qui ont posé problème.
Au final, le code doit ressembler à ça :


Ping : Tuto : Extraire des données d'une page web avec R - 2 - Données structurées | Le blog de François Guillem
Ping : Tuto : Extraire des données d'une page web avec R - 1 - Les tableaux | Le blog de François Guillem
Merci pour toute cette documentation détaillée sur l’extraction de données depuis le web ! C’est une mine d’or, à qui on aimerait faire des câlins si elle n’était pas virtuelle.
Du reste, quand relanceras-tu ce blog?