Extraire des données d’une page web – 3 – Données sur plusieurs pages

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 :

  1. Données sous forme de tableau
  2. Données structurées
  3. 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 :

  1. Récupérer ou construire une liste des URL de toutes les pages où se trouvent les données.
  2. Écrire une fonction qui prend en argument une URL et qui renvoie les données extraites de la page associée à l’URL.
  3. 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"
Mais la plupart du temps, il n’existe pas de page répertoriant tous les liens, dans ce cas il faut faire preuve d’astuce et souvent d’un peu d’intuition pour deviner les URL. Supposons par exemple que la page utilisée pour avoir le lien vers le profil des participants n’existe pas.

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 :

data <- NULL
error <- NULL
for (l in liens) {
  tmp <- NULL
  try(tmp <- extracteur(l)
  if (is.null(tmp)) {
    error <- c(error, l)
  } else {
    data <- cbind(data, tmp)
  }
}
Cette entrée a été publiée dans R. Vous pouvez la mettre en favoris avec ce permalien.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

*

Vous pouvez utiliser ces balises et attributs HTML : <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>