Cours 7 : Web scraping

Introduction aux mégadonnées en sciences sociales

Laurence-Olivier M. Foisy

Université de Montréal

Retour sur le TP2 - Travail de Mi-Session

  • Le but du TP2
  • Difficile?
  • Questions?

Internet

Qu’est-ce qu’Internet?

Un réseau de réseaux

  • Interconnexion globale de réseaux informatiques
  • Échange de données via des protocoles standardisés
  • Inventé dans les années 1960s (ARPANET)
  • Devenu public dans les années 1990s

Ce n’est pas le Web

  • Internet = l’infrastructure
  • Web = un service parmi d’autres (email, FTP, etc.)

ARPANET en 1973

Architecture client-serveur

Principe fondamental

  • Client : demande des ressources
  • Serveur : fournit des ressources

Exemples

  • Client : navigateur web, application mobile
  • Serveur : ordinateur hébergeant un site web

Réalité physique d’Internet

Internet est tangible

  • Câbles sous-marins traversant les océans
  • Fibre optique, cuivre, satellites
  • Routeurs et commutateurs
  • Serveurs physiques dans des datacenters

Le “cloud” n’existe pas

  • “Le cloud, c’est juste l’ordinateur de quelqu’un d’autre”
  • Les données sont stockées physiquement quelque part

Carte physique de l’internet

Traceroute vers umontreal.ca

 tcptraceroute umontreal.ca
Selected device wlp3s0, address 192.168.2.71, port 45431 for outgoing packets
Tracing the path to umontreal.ca (132.204.8.144) on TCP port 80 (http), 30 hops max
 1  192.168.2.1  5.618 ms  1.743 ms  2.499 ms
 2  10.11.16.41  3.860 ms  4.041 ms  3.737 ms
 3  * **
 4  64.230.36.102  6.344 ms  7.423 ms  9.020 ms
 5  64.230.91.65  5.214 ms  5.570 ms  6.500 ms
 6  192.77.55.233  6.890 ms  6.169 ms  5.786 ms
 7  imtrl-rq-ic-dmtrl-rq.risq.net (192.77.55.246)  5.837 ms  9.565 ms  7.724 ms
 8  umontreal2-contenu-dmtrl-um.risq.net (132.202.51.145)  32.002 ms  6.428 ms  7.800 ms
 9  * **
10  umontreal2-contenu-membre.risq.net (206.167.253.66)  33.855 ms  8.017 ms  6.263 ms
11  * **
12  * **
13  varnish.ti.umontreal.ca (132.204.8.144) [open]  10.542 ms  9.826 ms  13.408 ms

Le chemin d’une requête web vers UdeM

  1. Votre ordinateur (192.168.2.71)
    Point de départ à Québec

  2. Routeur résidentiel (192.168.2.1) Votre passerelle vers Internet

  3. Routeur Bell Fibe (10.11.16.41)
    Entrée dans l’infrastructure de Bell Canada

  4. Dorsale Bell Canada (64.230.36.102) Infrastructure principale de Bell - câbles à haute capacité (jusqu’à 100 Tbps sur certaines lignes)

  5. Point régional Bell (64.230.91.65) Transfert vers Montréal - connexion interurbaine

  1. RISQ - Point d’entrée (192.77.55.233) Entrée dans le Réseau d’Informations Scientifiques du Québec

  2. RISQ - Interconnexion Montréal (192.77.55.246) Routage interne du réseau académique québécois

  3. RISQ - Passerelle UdeM (132.202.51.145) La porte d’entrée spécifique à l’Université de Montréal

  4. UdeM - Réseau membre (206.167.253.66) Transfert au réseau interne de l’UdeM

  5. Serveur Varnish UdeM (132.204.8.144) Destination finale: serveur de cache accélérant la livraison du site

Infrastructure physique

Essayez ceci!

Tapez dans votre navigateur: http://142.250.217.110

  • Ordinateurs: utilisent des nombres (IP)
  • Humains: préfèrent les noms (google.com)
  • DNS = l’annuaire qui fait le lien

flowchart LR
    A[Ordinateur] -->|1. Où est google.com?| B[DNS]
    B -->|2. IP: 142.250.217.110| A
    A -->|3. Connexion| C[Google]

Empreinte physique des données

Où sont stockées vos données?

  • Messages Messenger
  • Photos Instagram
  • Documents Google Drive
  • Historique Netflix

Redondance géographique

  • Mêmes données stockées dans plusieurs datacenters
  • Protection contre pannes régionales

Quand vous allez sur un site

  1. JavaScript - Le comportement du site
  2. HTML - La structure
  3. CSS - Le style
  4. API - Les données

Web scraping

C’est quoi le web scraping?

Moissonnage / Aspiration / Grattage de données sur le Web

➡️

Révolution numérique

  1. Accès exhaustif à d’immense corpus de documents médias, accords internationaux, discours et procédures parlementaires, rapports annuels d’entreprises, jurisprudences, etc.

  2. La trace digitale des réseaux sociaux permet l’étude de nombreux phénomènes sociaux

Étude de cas : Premiers ministres du Canada

Question de recherche

Est-ce que se faire élire jeune est un avantage pour rester premier ministre longtemps?

Pour répondre, nous devons recueillir:

  • Dates de naissance des premiers ministres
  • Leur âge à l’entrée en fonction
  • Leur durée au pouvoir
  • Analyser la corrélation entre ces variables

À quel âge Justin Trudeau est entré au pouvoir?

Méthode manuelle traditionnelle

  1. Navigateur: Ouvrir Google
  2. Recherche: “Justin Trudeau date naissance” + “date entrée fonction”
  3. Sélection: Choisir une source fiable
  4. Information: Extraire les dates
  5. Calcul: Déterminer l’âge

Résultats

  • Né le: 25 décembre 1971
  • Premier mandat: 4 novembre 2015
  • Âge à l’entrée: 43 ans

L’inefficacité de l’approche manuelle

Répéter pour CHAQUE premier ministre…

  • Justin Trudeau: 1. Rechercher, 2. Sélectionner, 3. Extraire, 4. Calculer, 5. Noter
  • Stephen Harper: 1. Rechercher, 2. Sélectionner, 3. Extraire, 4. Calculer, 5. Noter
  • Paul Martin: 1. Rechercher, 2. Sélectionner, 3. Extraire, 4. Calculer, 5. Noter
  • Jean Chrétien: 1. Rechercher, 2. Sélectionner, 3. Extraire, 4. Calculer, 5. Noter
  • Kim Campbell: 1. Rechercher, 2. Sélectionner, 3. Extraire, 4. Calculer, 5. Noter

…et encore 18 autres premiers ministres! 😓

Comment approcher le problème?

Identifier sources et structure des pages

2. Aspirer

Télécharger le contenu

3. Extraire

Isoler les données pertinentes

4. Nettoyer

Structurer pour l’analyse

Ces quatre étapes forment le processus standard du web scraping et peuvent être automatisées avec R

2. Aspirer

Les formats de données

  1. HTML : pour les pages web standards
  2. JSON : pour les APIs (notre cas)
  3. JavaScript : pour les pages dynamiques

2. Aspirer

# URL of the page to scrape
url <- "https://lop.parl.ca/sites/ParlInfo/default/en_CA/People/primeMinisters"

# Read the webpage
page <- xml2::read_html(url)

elem <- rvest::html_table(page, "table.dx-datagrid-table")

Ça ne fonctionne pas? Pourquoi?

➡️ Retour sur le site web!

2. Aspirer

Ctrl + U

Permet de voir que le tableau n’est pas visible dans la page

Network tab

2. Aspirer

Astuce

Dans notre cas, nous avons découvert une API du Parlement du Canada!

# Exemple de notre URL d'API pour les premiers ministres
api_url <- "https://lop.parl.ca/ParlinfoWebAPI/Person/SearchAndRefine?&refiners=5-1,&projectionId=5&callback=jQuery3600941572194102592_1741730322226&_=1741730322227"

Note

Les API sont souvent masquées mais peuvent être découvertes en inspectant les requêtes réseau!

2. Aspirer - Anatomie d’un URL

https://www.parlement.ca/premiers-ministres?periode=1950-2020&lang=fr

Protocole https:// Communication sécurisée

Domaine www.parlement.ca Localisation du site

Chemin /premiers-ministres Ressource spécifique

Paramètres ?periode=1950-2020&lang=fr Filtres et options

Comprendre ces composants permet d’identifier quelles parties de l’URL modifier pour accéder aux données souhaitées lors du web scraping

2. Aspirer

Utilisation de httr pour les requêtes API

# Envoi de la requête HTTP à l'API
response <- httr::GET(api_url)

# Extraction du contenu textuel de la réponse
content <- httr::content(response, "text", encoding = "UTF-8")

3. Extraire

JSON vs HTML

Pour le HTML : library(rvest) et library(xml2)

Pour le JSON (notre cas) :

# Nettoyage de la réponse pour extraire uniquement la partie JSON
json_data <- stringr::str_extract(content, "\\[\\{.+\\}\\]")

# Conversion du JSON en objet R
pm_data <- jsonlite::fromJSON(json_data)

3. Extraire

Structure JSON

json$premiers_ministres$details$parti$nom

{
  "premiers_ministres": [
    {
      "nom": "Justin Trudeau",
      "details": {
        "naissance": "1971-12-25",
        "parti": {
          "nom": "Libéral",
          "couleur": "rouge"
        }
      },
    },
    {
      "nom": "Stephen Harper",
      "details": {
        "naissance": "1959-04-30",
        "parti": {
          "nom": "Conservateur",
          "couleur": "bleu"
        }
      },
    }
  ],
}

3. Extraire

Traitement des données JSON

# Création d'un dataframe avec les informations principales
df_pm <- data.frame(
  name = paste(pm_data$UsedFirstName, pm_data$LastName),
  yob = pm_data$DateOfBirth,                  # Date de naissance
  Party = pm_data$PartyEn,                    # Parti politique
  occupation = pm_data$ProfessionsEn,         # Profession
  province = pm_data$ProvinceOfBirthEn,       # Province de naissance
  stringsAsFactors = FALSE
)

3. Extraire

start_date <- c()
end_date <- c()
# Parcourir chaque premier ministre pour extraire les dates de mandat
for (i in 1:nrow(pm_data)) {
  # Récupérer tous les rôles politiques de la personne
  roles <- pm_data$Roles[[i]]
  
  # Parcourir chaque rôle pour trouver "Premier ministre"
  for (j in 1:nrow(roles)) {
    # Vérifier si le titre inclut "Premier ministre"
    if ("Premier ministre" %in% roles$NameFr) {
      # Enregistrer les dates de début et fin
      start_date[i] <- roles$StartDate[j]
      end_date[i] <- roles$EndDate[j]
    }
  }
}

4. Nettoyer

Préparation pour l’analyse

# Conversion des dates en format Date de R
df_pm$start_date <- as.Date(substr(start_date, 1, 10))
df_pm$end_date <- as.Date(substr(end_date, 1, 10))
df_pm$yob <- as.Date(substr(df_pm$yob, 1, 10))

# Calcul de variables d'intérêt
df_pm$duration <- as.numeric(difftime(df_pm$end_date, 
                                     df_pm$start_date, 
                                     units = "days"))/365.25

df_pm$age_at_start <- as.numeric(difftime(df_pm$start_date, 
                                         df_pm$yob, 
                                         units = "days"))/365.25

5. Visualiser et analyser

Création d’un graphique

# Visualisation avec ggplot2
ggplot2::ggplot(df_pm, ggplot2::aes(x = age_at_start)) +
  ggplot2::geom_histogram(binwidth = 5, fill = "#CF0E20") +
  ggplot2::labs(
    title = "Âge des premiers ministres canadiens à leur entrée en fonction",
    x = "Âge au début du mandat (années)",
    y = "Fréquence"
  )

5. Visualiser et analyser

5. Visualiser et analyser

Analyse statistique

# Régression linéaire: durée ~ âge au début
model <- lm(duration ~ age_at_start, data = df_pm)
summary(model)
r$> summary(m)

Call:
lm(formula = duration ~ age_at_start, data = df_pm)

Coefficients:
             Estimate Std. Error t value Pr(>|t|)
age_at_start -0.05162    0.09679  -0.533    0.599

Residual standard error: 4.515 on 21 degrees of freedom
Multiple R-squared:  0.01336,   Adjusted R-squared:  -0.03362 
F-statistic: 0.2845 on 1 and 21 DF,  p-value: 0.5994

Important

Est-ce que les plus jeunes premiers ministres ont tendance à rester plus longtemps en poste? NON!

Exemples concrets

Agrégateur de sondages électorales

Les trois approches principales du Web Scraping

  1. Extraction des tableaux HTML/CSS (rvest)
  2. Téléchargement direct de fichiers (CSV, Excel)
  3. Connexion aux API REST (httr, jsonlite)

Notre Projet : Agrégateur de Sondages Électoraux

Trois sources de données électorales canadiennes:

  1. 338Canada: Tables HTML avec projections électorales
  2. Poliwave: Téléchargement direct de fichiers Excel
  3. The Signal: API REST (endpoints JSON)

Structure du pipeline de données:

  • Extraction → Stockage brut → Transformation → Visualisation

Agrégateur de Sondages Électoraux - Objectif

Pour chaque méthode de scraping, nous verrons:

  1. Les packages et fonctions clés
  2. Le code étape par étape
  3. Les avantages et inconvénients

1. Web Scraping avec HTML/CSS

Canada 338

Le site Canada 338

  • Présente des projections électorales par circonscription
  • Les données sont organisées dans un tableau HTML
  • Identifié par l’ID CSS #myTable

Notre approche

  1. Charger la page principale
  2. Extraire le tableau HTML des projections
  3. Nettoyer et structurer les données
  4. Sauvegarder en format RDS pour analyse ultérieure

Canada 338

# Chargement des packages nécessaires
library(rvest)     # Pour le scraping HTML
library(dplyr)     # Pour la manipulation de données
library(stringr)   # Pour la manipulation de texte

# 1. URL de la page à scraper
url <- "https://338canada.com/districts.htm"

# 2. Lecture de la page web
html_content <- read_html(url)

# 3. Extraction du tableau HTML
table_data <- html_content %>%
  html_node("#myTable") %>%     # Sélectionne le tableau par son ID CSS
  html_table(fill = TRUE)       # Convertit en dataframe

Canada 338

# 4. Extraction des informations utiles
# 4.1 Extraire l'ID de circonscription (format 12345)
table_data$riding_id <- str_extract(table_data$electoral_district, "\\d{5}")

# 4.2 Extraire le nom propre de la circonscription
table_data$district_name <- str_replace_all(table_data$electoral_district, "\\d{5} ", "")

# 4.3 Extraire le parti projeté gagnant (LPC, CPC, NDP, BQ, GPC)
table_data$projected_party <- str_extract(table_data$latest_projection, "(LPC|CPC|NDP|BQ|GPC)")

# 4.4 Extraire le statut de la projection (safe, likely, leaning)
table_data$projection_status <- str_replace_all(table_data$latest_projection, "(LPC|CPC|NDP|BQ|GPC) ", "")

# 5. Création d'un dataframe propre et sauvegarde
clean_data <- table_data %>%
  select(riding_id, district_name, projected_party, projection_status) %>%
  filter(!is.na(riding_id))  # Supprime les lignes sans ID (entêtes)

# 6. Ajout de la date du scraping et sauvegarde
clean_data$scrape_date <- Sys.Date()
saveRDS(clean_data, "data/lake/can338/338_canada_projection.rds")

338Canada - Comment trouver les bons sélecteurs CSS?

Outils du navigateur

  1. Clic droit sur l’élément → Inspecter
  2. Explorer l’arbre HTML
  3. Identifier les balises et attributs uniques

Stratégies pour les tableaux

  • Trouver l’ID du tableau: #myTable
  • Sélectionner par position: table:nth-child(2)
  • Par classe: .data-table
  • Combinaison: div.content table

La fonction html_table()

  • Convertit un tableau HTML directement en dataframe
  • Option fill = TRUE pour les tableaux irréguliers
  • Préserve la structure des colonnes

338Canada - Avantages et inconvénients

Inconvénients

  • Dépendance à la structure HTML du site
  • Sensible aux modifications de mise en page
  • Traitement supplémentaire souvent nécessaire
  • Limitations pour les tableaux dynamiques (JavaScript)

Considérations

  • Vérifier la stabilité du tableau dans le temps
  • Prévoir un plan B si la structure change
  • Ajouter la date d’extraction pour traçabilité
  • Implémenter des vérifications de validité

2. Téléchargement direct de fichiers

Poliwave - Notre objectif

Le site Poliwave

  • Publie des projections électorales pour le Canada
  • Fournit un fichier Excel avec les données par circonscription
  • URL directe: https://www.poliwave.com/Canada/Federal/Data/CAtable.xlsx

Notre approche

Simplissime: Télécharger directement le fichier Excel et le sauvegarder!

Poliwave

# Chargement du package pour Excel
library(readxl)

# 1. Création d'un fichier temporaire avec extension .xlsx
temp_file <- tempfile(fileext = ".xlsx")

# 2. Téléchargement du fichier
download.file(
  "https://www.poliwave.com/Canada/Federal/Data/CAtable.xlsx", 
  temp_file, 
  mode = "wb"  # Mode binaire important pour Excel
)

# 3. Lecture du fichier Excel
poliwave_ridings <- readxl::read_xlsx(temp_file)

# 4. Sauvegarde en format RDS
saveRDS(
  poliwave_ridings,
  "data/lake/poliwave/poliwave_table.rds"
)

Poliwave - Avantages et inconvénients

Avantages

  • Aucun parsing ou nettoyage nécessaire
  • Très robuste aux changements du site
  • Les données sont déjà structurées
  • Performance optimale (téléchargement direct)

Cas d’usage idéaux

  • Sites qui proposent des exports directs
  • Besoin des données complètes
  • Absence de filtrage nécessaire
  • Mises à jour régulières des fichiers

Inconvénients

  • Limité aux données explicitement partagées
  • Pas de personnalisation possible
  • Format imposé par la source
  • Dépendance aux modifications d’URL
  • Fichiers volumineux potentiels

Considérations

  • Vérifier régulièrement que l’URL est valide
  • S’assurer que le format de fichier reste stable
  • Prévoir une gestion des erreurs de téléchargement
  • Documenter la structure attendue du fichier

3. API REST avec httr & jsonlite

API REST - Les Packages

Package Fonction Description
httr GET() Effectue une requête HTTP GET à une URL
httr content() Extrait le contenu d’une réponse HTTP
jsonlite fromJSON() Parse une chaîne JSON en objet R

The Signal - Notre objectif

Le site The Signal

  • Publie des projections électorales développées par CBC/Radio-Canada
  • API cachée pour accéder aux données
  • Structure des données en format JSON

Notre approche

  1. Définir l’URL de l’API
  2. Effectuer une requête GET à l’endpoint
  3. Parser la réponse JSON en dataframe
  4. Sauvegarder les résultats

The Signal

# Chargement des packages
library(dplyr)    # Pour la manipulation de données
library(httr)     # Pour les requêtes HTTP
library(jsonlite) # Pour le parsing JSON

# 1. Configuration de base
# URL de l'API pour les projections électorales
api <- "https://thesignal-api.voxpoplabs.com/api/en/canada2025/riding_projections"

# 4. Exécution de la requête API
response <- httr::GET(api)

The Signal

# 5. Extraction du texte JSON
json_text <- httr::content(response, as = "text", encoding = "UTF-8")

# 6. Conversion du JSON en dataframe
riding_data <- jsonlite::fromJSON(json_text)

# 9. Sauvegarde des résultats
saveRDS(riding_data, "data/lake/signal_riding_projections.rds")

Structure de réponse JSON

{
  "ridings": [
    {
      "riding_name": "Beauce",
      "region": "QC",
      "confidence": "Likely",
      "prediction": "CON",
      "date_updated": "2023-11-15"
    },
    {
      "riding_name": "Toronto Centre",
      "region": "ON",
      "confidence": "Safe",
      "prediction": "LIB",
      "date_updated": "2023-11-15"
    },
    {
      "riding_name": "Vancouver Centre",
      "region": "BC",
      "confidence": "Likely",
      "prediction": "LIB",
      "date_updated": "2023-11-15"
    }
  ],
  "meta": {
    "last_updated": "2023-11-15T12:00:00Z",
    "version": "1.0"
  }
}

The Signal - Avantages et inconvénients

Avantages

  • Facile à extraire

Cas d’usage idéaux

  • Sites avec API publique
  • Besoins de données spécifiques

Inconvénients

  • Quotas de requêtes possibles
  • Dépendance aux changements d’API

Considérations

  • Vérifier les conditions d’utilisation
  • Respecter les limites de taux

Quand utiliser quelle approche?

On fait avec ce qu’on a!

Robots.txt - Qu’est-ce que c’est?

  • Fichier texte placé à la racine d’un site web
  • Indique aux robots d’indexation et scrapers quelles parties du site:
    • Peuvent être visitées et indexées
    • Ne doivent pas être visitées
  • Standard de facto depuis 1994
  • Respecté par les moteurs de recherche et autres robots “éthiques”
User-agent: *
Disallow: /private/
Disallow: /admin/
Allow: /public/

User-agent: Googlebot
Allow: /

Un guide pour les robots, mais pas une barrière de sécurité

Pourquoi respecter robots.txt?

Éthique du web scraping

  • Respect des ressources du serveur
  • Politesse numérique envers les propriétaires du site
  • Conformité légale (selon les juridictions)

Conséquences possibles

  • Bannissement de votre adresse IP
  • Surcharge des serveurs
  • Problèmes légaux potentiels

Alternatives légitimes

  • Utiliser les API officielles quand disponibles
  • Limiter la fréquence des requêtes
  • Contacter le propriétaire du site

Vérifier robots.txt en R

La règle générale: toujours vérifier avant de scraper!

# Installer le package si nécessaire
# install.packages("robotstxt")
library(robotstxt)

# Vérifier si le scraping est autorisé
paths_allowed("https://lop.parl.ca/sites/ParlInfo/default/en_CA/People/primeMinisters")
#> [1] TRUE

paths_allowed("https://lop.parl.ca/ParlinfoWebAPI/Person/SearchAndRefine?&refiners=5-1,&projectionId=5&callback=jQuery360032980273762339296_1741814357460&_=1741814357461")
#> [1] TRUE

# Examiner le fichier robots.txt complet
robotstxt::get_robotstxt("https://lop.parl.ca")

Le package robotstxt facilite la vérification avant le web scraping

robots.txt

r$> robotstxt::get_robotstxt("https://lop.parl.ca")
[robots.txt]
--------------------------------------

User-agent: *
Disallow: /staticfiles/PublicWebsite/Home/About/CoporateDocuments/PDFExc
ludedInRobotsTXT
Disallow: /content/lop/Quorum
Disallow: /Content/LOP/Quorum
Disallow: /Content/LOP/quorum
Disallow: /Content/lop/quorum
Disallow: /content/lop/quorum
Disallow: /content/LOP/Quorum
Disallow: /sites/PublicWebsite/default/en_CA/NotFound
Disallow: /sites/PublicWebsite/default/fr_CA/NotFound
Disallow: /sites/ParlInfo/default/en_CA/SiteInformation/parlinfoMoved
Disallow: /sites/ParlInfo/default/fr_CA/InformationSite/parlinfoDemenage
Allow: /sites/ParlInfo/default/en_CA/People/Profile?*
Disallow: /sites/ParlInfo/default/en_CA/People/Profile
Allow: /sites/ParlInfo/default/fr_CA/Personnes/Profil?*
Allow: /sites/ParlInfo/default/fr_CA/Personnes/Profile?*
Disallow: /sites/ParlInfo/default/fr_CA/Personnes/Profil
Disallow: /sites/ParlInfo/default/fr_CA/Personnes/Profile
Allow: /sites/ParlInfo/default/en_CA/Federal/areasResponsibility/profile
?*
Disallow: /sites/ParlInfo/default/en_CA/Federal/areasResponsibility/prof
ile
Allow: /sites/ParlInfo/default/fr_CA/Federal/domainesResponsabilites/pro
fil?*
Disallow: /sites/ParlInfo/default/fr_CA/Federal/domainesResponsabilites/
profil
Allow: /sites/ParlInfo/default/en_CA/Parties/Profile?*
Disallow: /sites/ParlInfo/default/en_CA/Parties/Profile
Allow: /sites/ParlInfo/default/fr_CA/Partis/Profil?*
Disallow: /sites/ParlInfo/default/fr_CA/Partis/Profil
Allow: /sites/ParlInfo/default/en_CA/ElectionsRidings/Ridings/Profile?*
Disallow: /sites/ParlInfo/default/en_CA/ElectionsRidings/Ridings/Profile
Allow: /sites/ParlInfo/default/fr_CA/ElectionsCirconscriptions/Circonscr
iptions/Profil?*
Disallow: /sites/ParlInfo/default/fr_CA/ElectionsCirconscriptions/Circon
scriptions/Profil
Allow: /sites/ParlInfo/default/en_CA/ElectionsRidings/Elections/Profile?
*
Disallow: /sites/ParlInfo/default/en_CA/ElectionsRidings/Elections/Profi
le
Allow: /sites/ParlInfo/default/fr_CA/ElectionsCirconscriptions/Elections
/Profil?*
Disallow: /sites/ParlInfo/default/fr_CA/ElectionsCirconscriptions/Electi
ons/Profil
Disallow: /sites/PublicWebsite/default/fr_CA/Staging
Disallow: /sites/PublicWebsite/default/en_CA/Staging
Disallow: /sites/PublicWebsite/default/fr_CA/merc
Disallow: /sites/PublicWebsite/default/en_CA/merc
Sitemap: https://bdp.parl.ca/rss/public/fr/sitemapxml
Sitemap: https://lop.parl.ca/rss/public/en/sitemapxml

Lire et interpréter robots.txt

Syntaxe courante

  • User-agent: * - S’applique à tous les robots
  • User-agent: Googlebot - Spécifique à Google
  • Disallow: /dossier/ - Interdit l’accès
  • Allow: /dossier/ - Autorise explicitement l’accès
  • Crawl-delay: 10 - Attendre 10 secondes entre requêtes

Limitations

  • Basé sur la confiance, pas une protection technique
  • Interprétation parfois ambiguë
  • Certains sites utilisent des règles complexes
  • Pas de norme officielle pour “User-agent: R-Scraper”

Toujours associer la vérification de robots.txt à d’autres bonnes pratiques de scraping (délais, user-agent explicite, etc.)

Bonnes pratiques au-delà de robots.txt

Identifiez-vous

session <- polite::bow(
  url = "https://example.com",
  user_agent = "FAS1001 Educational Scraper"
)

Respectez les délais

# Attendre entre les requêtes
Sys.sleep(2)  

# Ou utilisez polite
polite::scrape(session)

Astuce

Le package polite intègre la vérification de robots.txt et d’autres bonnes pratiques comme les délais entre requêtes.

Pour aller plus loin

  • RSelenium: Pour sites dynamiques (JavaScript)

Trucs et astuces

  1. Utiliser les outils de développement de votre navigateur
  2. Soyez conscient des implications éthiques
  • robots.txt
  • Sys.sleep(1)
  1. Les tables HTML peuvent être importées directement dans R
  2. Utiliser les regex
  3. Peaufiner vos compétences en CSS
  4. Utiliser les API officielles si possible
  5. Des sites peuvent être visités avec la wayback machine
  6. Révélez les API cachées dans les sites webs
  7. Utiliser Selenium : Pour les utilisateurs avancés