You are on page 1of 6

Des dputs fdraux et du web scraping

naelshiab.com /des-deputes-federaux-et-du-web-scraping/

Nael Shiab 03/02/2015


a faisait un moment que je me cherchais un petit projet personnel sur les dputs fdraux.
Rien de bien srieux. Juste de quoi coder pour mamuser un peu.

Le rsultat: une ligne du temps interactive sur les emplois dclars par les dputs au fil des annes!

Surprenant limplication des agriculteurs en politique avant les annes 70, nest-ce pas? Et la professionnalisation
du rle de dput par la suite? Cliquez sur le graphique ci-dessous pour tous les dtail!

Comment ai-je ralis cette amusante infographie? Jai cod mon propre programme pour extraire les donnes du
site web du Parlement du Canada ! Je vous explique ma dmarche en dtails dans cet article.

Learn About Tableau

#1 Trouver linformation

En cherchant des informations sur les dputs fdraux, je suis tomb sur cette intressante page web. Lorsque
vous choisissez une lection gnrale (de la premire en 1867 jusqu la plus rcente en 2011), plusieurs
dtails sont prsents sur chacun des candidats de lpoque.

Voici quoi le tout ressemble par exemple pour Calgary-Centre et Calgary-Centre-Nord, lors de llection gnrale
de 2011. Comme vous pouvez le constatez, le mtier des candidats est indiqu.

videmment, nous pourrions demander aux administrateurs du site web de nous envoyer leur base de donnes
directement, mais cest beaucoup plus amusant dextraire les donnes nous-mme! Et nul besoin dattendre aprs
qui que ce soit.

Premier rflexe: jeter un coup doeil au code source de la page:

1/6
Avez-vous remarqu la balise

la ligne 123? Et les balises et qui suivent?

Elles crent un tableau HTML sur la page web. Cest parfait pour nous! La structure est redondante. Un programme
pourra facilement passer au travers et rcuprer ce quon lui demandera.

Analysons lurl de la page web maintenant:

http://www.parl.gc.ca/About/Parliament/FederalRidingsHistory/hfer.asp?
Language=F&Search=Gres&genElection=41&ridProvince=0&submit1=Recherche

Elle est assez simple. Il sagit en fait dune requte pour le serveur qui hberge la base de donnes o se trouve
toutes les informations sur les candidats.

Voyez-vous le 41 ? Cest lui qui indique au serveur que vous souhaitez voir les informations relatives la 41me
lection gnrale, qui sest droule en 2011.

Que se passe-t-il si vous remplacez le 41 par 40? La page web qui souvre vous donne les informations pour
llection de 2008, la 40me lection gnrale!

Avec une url aussi simple, ce sera du gteau pour notre programme. Il pourra ouvrir la page web de chaque lection
sans problme!

#II Rcolter linformation

Puisquil y a eu 41 lections entre 1867 et 2011, linformation que lon cherche obtenir se trouve sur 41 pages web
diffrentes.

Par consquent, nous allons commencer par crer un petit programme qui va enregistrer toutes les pages web sur
notre disque dur.

Jai ouvert mon diteur de texte et jai cod un script tout simple en Python pour ce faire. Jai utilis le module
urllib2 pour ouvrir les pages et le module time pour crer un petit dlai.

Tout dabord, on charge les modules, puis on cre une boucle qui va rouler 41 fois. Ce faisant, on a cr une
variable n qui va passer de 1 41, au fur et mesure que la boucle roulera. On peut donc insrer n dans lurl de la
page web!

2/6
1 import urllib2
2 import time
3
4 for n in range(1,42):
5
6 url_webpage = 'http://www.parl.gc.ca/About/Parliament/FederalRidingsHistory/hfer.asp?
Language=E&Search=Gres&genElection=' + str(n) +'&ridProvince=0&submit1=Search'

Par la suite, on choisit o lon souhaite enregistrer la page web. Encore une fois, on peut utiliser la variable n pour le
nom mme du fichier HTML, qui se retrouvera sur notre disque dur.

1 file_path = 'THE_PATH_YOU_WANT/General_Election_' + str(n) + '.html'

Et maintenant, on ouvre la page web, on cr le fichier HTML sur notre ordinateur, et on copie le contenu de la page
web dans le fichier HTML avant de le fermer!

1 response = urllib2.urlopen(url_webpage)
2
3 html_file = open(file_path, "w")
4
5 html_file.write(response.read())
6
7 html_file.close()

la fin de la boucle, jai ajout un print statement pour que vous puissiez voir le programme en action dans la
fentre du terminal. Et aussi un dlai dune seconde, pour ne pas surcharger le serveur du Parlement avec trop de
requtes en mme temps!

1 print "I'm done with " + file_path + '!'


2
3 time.sleep(1)

Une fois arriv la fin, le programme retourne au dbut de la boucle, tlcharge la page suivante, et ainsi de suite,
41 fois pour les 41 lections gnrales. Voici ce que a donne en action:

Tadam! En deux minutes, on vient denregistrer 41 pages web!

#III Trier linformation

On a dsormais toutes les donnes sur notre ordinateur. Petit problme: les informations sont parses et
inutilisables pour linstant.

On doit donc rdiger un deuxime script en Python, qui va passer au travers du code HTML des 41 fichiers que lon
vient denregistrer. Ce second programme va extraire les donnes qui nous intresse et les placer dans un
fichier tout propre, semblable un fichier csv!

Pour ce faire, jai utilis le module BeautifulSoup pour traiter le HTML et le module Unicodecsv pour crer le fichier
final.

Pour commencer, on lance les modules et on cr un fichier texte, qui sera dlimit par des tabulations. On en
profite aussi tout de suite pour crire la premire ligne, qui sera le nom des diffrentes colonnes.
3/6
1 from bs4 import BeautifulSoup
2 import unicodecsv
3
4 output = open('THE_PATH_YOU_WANT/Elected_general_elections.txt', "w")
5
6 final_file = unicodecsv.writer(output, delimiter = '\t', encoding = 'utf-8')
7
8 final_file.writerow(['Parliament', 'Year', 'Candidate', 'Party', 'Occupation', 'Votes', 'Votes (%)'])

Par la suite, on cr une boucle qui passera au travers des 41 fichiers HTML enregistrs sur notre disque dur. Et on
les passe un par un dans le module BeautifulSoup, avant de commencer travailler avec. (La variable counter va
nous servir suivre le processus en action plus tard.)

1 counter = 1
2
3 for n in range(1,42):
4
5 parliament = str(n)
6
7 file_path = 'THE_PATH_YOU_WANT/General_Election_' + str(n) + '.html'
8
9 soup = BeautifulSoup(open(file_path))

Cest parti! Maintenant, on peut commencer extraire les donnes. Tout dabord, on isole tout ce qui se trouve entre
les balises (cette balise code les lignes du tableau HTML). Dans le code source de chacune des pages, on peut voir
que la deuxime ligne du tableau HTML contient toujours le nom dune circonscription puis la date de llection
gnrale. Vu que la date a toujours le mme format, on peut extraire lanne trs facilement, en comptant les
caractres depuis la droite.

1 all_rows = soup.find_all('tr')
2
3 year = all_rows[1].getText()
4 year = year[-11:-7]

Avez-vous remarqu le petit symbole que lon retrouve sur la ligne des candidats lus? Un coup doeil au code
source nous indique quil sagit dune image code ainsi: . Cest parfait pour nous! Tel quindiqu dans le code ci-
dessous, cela permet de slectionner directement les candidats lus, donc les dputs! On peut dsormais isoler
chaque cellule du tableau, uniquement pour ceux qui ont gagn les lections.

1 for row in all_rows:


2 if 'check' in str(row):
3 all_cell = row.find_all('td')
4
5

Tout est en place pour extraire les donnes! Sur chaque ligne, le nom du candidat se trouve dans la premire
cellule, lindex zro. Par la suite, cest le parti politique, loccupation, le nombre de votes et le pourcentage de
votes obtenus pour finir. On place chaque information dans une variable.

4/6
1 candidate = all_cell[0].getText('a').strip()
2
3 party = all_cell[1].getText('a').strip()
4
5 occupation = all_cell[2].getText().strip()
6
7 votes = all_cell[3].getText().strip()
8
9 votes_percentage = all_cell[4].getText().strip()

Parfois, les dputs sont lus par acclamation. Dans ce cas l, le check est remplac par accl. Nous devons donc
ajouter une condition notre script, pour tre sr que lon aura tout le monde!

1 elif 'accl' in str(row):


2
3 all_cell = row.find_all('td')
4
5 candidate = all_cell[0].getText('a').strip()
6
7 party = all_cell[1].getText('a').strip()
8
9 occupation = all_cell[2].getText().strip()
10
11 votes = all_cell[3].getText().strip()
12
13 votes_percentage = all_cell[4].getText().strip()

Et maintenant, la finale! On affiche lcran toutes les variables pour vrifier ce quelles contiennent et on crit les
lignes une une dans notre fichier texte! Jai ajout un print statement avec la variable counter pour que lon puisse
voir le script travailler dans le terminal.

1 print parliament, year, candidate, party, occupation, votes, votes_percentage


2
3 final_file.writerow([parliament, year, candidate, party, occupation, votes, votes_percentage])
4
5 print "Row number " + str(counter) + " added!"
6
7 counter += 1

Notre programme va donc ouvrir chaque page web, passer au travers de chaque ligne dans les tableaux HTML,
extraire les donnes qui nous intressent et finalement les copier dans notre fichier texte. Voici ce que a donne
quand on lance le script:

Et voil! En moins de quatre minutes, on vient dextraire les donnes de 41 fichiers HTML, tout en copiant plus de 10
000 lignes dinformation dans un fichier texte! Nest-ce pas fantastique?

Et voici le rsultat quand on ouvre le fichier dans un tableur. Un beau fichier tout propre! Il ne reste plus qu louvrir
dans Tableau pour crer la ligne du temps, et le tour est jou!

5/6
Tutoriel: Comment envoyer De lOntario au Qubec
un courriel avec Python

6/6