En dépit de critiques récurrentes, on trouve des informations très utiles sur l’encyclopédie en ligne Wikipédia. Et, à condition de savoir les lire (i.e. de pratiquer la critique des sources), elle peut constituer une mine d’or pour les chercheurs. D’aileurs, vous pourriez y contribuer, ou contribuer.
Comment faire pour collecter automatiquement ces informations ? De la même manière qu’on l’a déjà fait, mais le site impose de respecter certaines règles. Examinon-les en repartant de l’exemple des édifices religieux à Paris, traité dans un précédent billet. Cette fois, on s’intéresse au culte musulman.
L’exemple des lieux de culte musulman à Paris
Parmi les différents sites qui répertorient lieux du culte musulman à Paris, Wikipédia semble bien renseigné. Une rapide consultation montre une liste d’environ 75 sites, qu’on va récupérer afin de pouvoir la traiter (statistiques, visualisation), ou la sauvegarder. Assurément, on n’est pas en mesure de dire si elles sont fréquentées, toujours actives, ou si la liste est complète (mais des gens ici ou là ont sûrement une idée – ainsi que l’administration française, comme le montrait la thèse de S. Jouanneau).
Et on peut remarquer au passage une distinction qu’on ne retrouve pas chez d’autres groupes religieux plus établis : plus de la moitié des endroits recensés sont des “simples” salles de prières, et pas des édifices spécifiquement religieux (ce qui a sûrement trait à la croissance différentielle des groupes religieux, comme à leur histoire).
Sur Wikipédia, les données sont souvent présentées sous forme de tableaux. Ceux-ci sont décrits par une balise <table>
dans le code source. Dans ce cas, leur extraction est très simple, grâce à la fonction readHTMLTable
(présentée ici également), que l’on va utiliser.
Le premier “tableau” de la page est la table des matières de l’article, donc on s’intéresse au deuxième (mosquées), et au troisième (salles de prière). La fonction readHTMLTable
peut s’utiliser directement avec l’URL (l’adresse) de la page, dans ce cas on extrait les tableaux comme ceci :
# Modules
library(RCurl)
library(XML)
# Adresse de la page Wikipédia
lieux.islam.url <-
"http://fr.wikipedia.org/wiki/Liste_des_mosqu%C3%A9es_de_Paris"
# Récupération directe des tableaux
lieux.islam.tableaux <- readHTMLTable(lieux.islam.url)
mosquees <- lieux.islam.tableaux[[2]]
salles.priere <- lieux.islam.tableaux[[3]]
Si on vérifie le contenu de salles.priere
, on peut vérifier que ça fonctionne. Reste un problème d’accents, qui se traduit par des choses comme \u0080
(Mac OS) ou des caractères bizarres (Windows) et des avertissements ésotériques comme “it is not known that wchar_t is Unicode on this platform
”. Il s’agit d’un malentendu d’encodage, c’est-à-dire d’interprétation des caractères accentués – qu’on traitera en détail prochainement [1].
Pour y remédier, on va adopter une procédure légèrement plus longue. Cela va nous permettre également de se conformer aux conditions d’utilisation de Wikipédia, et plus généralement aux bonnes pratiques de collecte automatique de données.
Collecter, à quelles conditions ?
Collecter automatiquement des données peut être grisant, mais il ne faut pas oublier que l’opération peut être coûteuse pour l’hébergeur (en termes de bande passante, donc d’infrastructures matérielles), et que le droit protège la propriété des données : ce n’est pas parce que vous pouvez les consulter qu’elles sont à vous. Les sites peuvent, au-delà du droit, se protéger par divers outils techniques. Certains vous bloqueront l’accès en cas de non-respect des conditions d’utilisation ; il est donc vivement conseillé de lire celles-ci pour savoir ce que vous êtes autorisé à faire, et comment.
Chez Wikipédia, les données sont librement accessibles, aux conditions des licences Creative Commons et GNU Free Documentation License : en gros, citer vos sources, ne pas en faire un usage commercial, etc. (un peu comme pour ce blog). Concernant la collecte automatisée de données, la règle veut qu’on se présente, qu’on donne les moyens au webmaster de vous contacter par email, et qu’on évite de revenir trop régulièrement. À défaut, l’accès vous sera bloqué après quelques requêtes. On va donc utiliser des fonctions qui permettent de charger des pages web tout en envoyant nos coordonnées au serveur.
Pour cela, et toujours avec R, on prend un chemin découpé en plusieurs étapes. Les fonctions de très “haut niveau”, c’est-à-dire qui font beaucuop d’opérations complexes en une seule fois, ne permettent en effet pas toujours de contrôler assez finement la communication avec le serveur. Notre programme commence donc par la préparation d’une ligne, appellée User-Agent, qu’on envoie au serveur pour lui signaler notre identité (personnelle et logicielle) lorsqu’on lui demande une page [2].
Ici, cette ligne est de la forme “RCurl (mon.adresse@moi.net)
”, RCurl étant le “navigateur” qu’on utilise. On la communique comme ceci :
# Modules utilisés ici
library(RCurl)
library(XML)
# Adresse (URL) de la page
lieux.islam.url <-
"http://fr.wikipedia.org/wiki/Liste_des_mosqu%C3%A9es_de_Paris"
# Identifiant que l'on envoie à Wikipedia pour se présenter
# À remplacer par votre email !
mon.adresse.mail <- "mon.adresse@moi.net"
# Assemblage du message qui va être envoyé
identifiant <- paste("RCurl", " (",
mon.adresse.mail, ")",
sep="")
# Requête
page.brute <- getURL(url = lieux.islam.url,
useragent = identifiant)
# On traite ensuite cet objet, pour en analyser la structure
page.lignes <- readLines(tc <- textConnection(page.brute))
close(tc)
page.parsed <- htmlTreeParse(page.lignes,
useInternalNodes=TRUE,
asText=TRUE)
La variable page.brute
est le contenu de la page web chargée, en HTML. On la transforme en lignes (page.lignes
), puis on analyse sa structure (parse). On pourra ensuite appliquer la fonction de lecture simplifiée des tableaux vue précédemment. Mais avant cela on va enlever les accents du texte.
Enlever les accents
L’intérêt de cette procédure est d’avoir un contrôle fin sur les opérations de téléchargement et de transformation de la page web. En particulier, on va pouvoir enlever les accents du texte, ce qui évitera toute confusion d’encodage [3].
On utilise ici une fonction que l’on a détaillée ailleurs, et que l’on appelle Unaccent()
.
Le moment le plus propice pour appliquer cette fonction, dans les opérations traitement de la page, est lorsqu’elle est sous forme de lignes, à l’étape page.lignes
. Les accents (ou plutôt l’encodage) sont à ce moment correctement traités.
Le programme intégral
On reprend ainsi les morceaux présentés plus haut. Au passage, on englobe les opérations dont le résultat ne nous intéresse pas dans une fonction, ce qui évite de les garder en mémoire.
# Modules utiles
library(RCurl)
library(XML)
# Adresse (URL) de la page
lieux.islam.url <-
"http://fr.wikipedia.org/wiki/Liste_des_mosqu%C3%A9es_de_Paris"
# Identifiant que l'on enverra à Wikipedia pour se présenter
# À remplacer par votre email !
mon.adresse.email <- "mon.adresse@moi.net"
# Définition d'une fonction d'enlèvement des accents (et des '`^")
Unaccent <- function(text) {
text <- gsub("['`^\"]", " ", text)
text.unac <- iconv(text, to="ASCII//TRANSLIT")
text.unac <- gsub("['`^\"]", "", text.unac)
return(text.unac)
}
# Fonction de téléchargement, enlèvement des accents,
# et analyse (parsing) de la structure HTML
GetUnaccentURL <- function(url.page, email='') {
identifiant <- paste("RCurl", " (",
email, ")",
sep="")
page.brute <- getURL(url = url.page,
useragent = identifiant)
page.lignes <- readLines(tc <- textConnection(page.brute))
close(tc)
page.lignes.unac <- Unaccent(page.lignes)
page.parsed <- htmlTreeParse(page.lignes.unac,
useInternalNodes=TRUE,
asText=TRUE)
return(page.parsed)
}
# Téléchargement de la page sur les lieux de culte musulman
lieux.islam <- GetUnaccentURL(url.page = lieux.islam.url,
email = mon.adresse.email)
# Extraction des tableaux
mosquees <- readHTMLTable(lieux.islam, which=2)
salles.priere <- readHTMLTable(lieux.islam, which=3)
Et voilà [4] !
On peut maintenant cartographier ces résultats : il suffit de géocoder les adresses obtenues.
La distribution géographique apparaît clairement localisée dans l’Est parisien, soit les quartiers les moins bourgeois de la capitale ; plus le quinzième arrondissement. Les salles de prière sont globalement situées dans les mêmes quartiers que les mosquées, mais avec de fortes variations.
-
En deux mots, le problème est le suivant : les fichiers informatiques sont constitués d’octets, des blocs élémentaires de mémoire qui peuvent prendre chacun 256 valeurs. Pour communiquer un texte, il faut transformer la suite des caractères en une série d’octets, donc de valeurs entières entre 0 et 255, et pour cela utiliser un code. Si le code employé pour déchiffrer la suite de ces valeurs numériques n’est pas le même que celui employé la créer, alors cela déforme le texte initial. Les “encodages” désignent, dans le sens usuel (qui est assez imprécis), les différents codes utilisés, dont les plus généraux se nomment ASCII, iso–8859–1 (ou Latin–1), ou encore Unicode / UTF–8. ↩
-
Cette méthode n’est pas vraiment un outil de sécurisation : il est possible de déclarer une fausse identité sans difficulté, et le serveur n’a aucun moyen de le contrôler. En réalité, elle est utilisée sur le web avec une visée surtout pratique : en déclarant quel est votre navigateur et sa version (par exemple, “
Mozilla/5.0 (X11; Ubuntu; Linux i686; rv : 15.0) Gecko/20100101
” désigne Firefox 15.0 pour Ubuntu), le serveur peut savoir comment vous envoyer une page adaptée aux capacités techniques du navigateur, ou au format d’écran de votre machine (ordinateur, téléphone mobile, tablette, etc.). ↩ -
Plus précisément, les caractères latins non-accentuées, disons le clavier américain, sont transcrits de la même manière par les différents encodages occidentaux standards. On peut donc se tromper d’encodage dans l’interprétation de tels textes, le résultat est toujours correct. Désaccentuer un texte permet ainsi de ne (presque) plus se soucier des questions. ↩
-
On aurait pu, en réalité, éviter d’enlever les accents, en appliquant la transformation suivante à la fin (et avec un équivalent pour
salles.priere
) :for(i in 1:length(mosquees)) {mosquees[[i]] <- iconv(from="UTF-8", to="LATIN1", mosquees[[i]])}
. Celle-ci est applicable au résultat de l’extraction directe des tableaux, mais ne permet pas de se conformer à la politique d’identification de Wikipédia. ↩