wget en python 3 avec gestion des cookies et du post


 lun. 25 février 2013    Python

Un petit exemple avec le site ameli, qui permet d'illustrer la gestion des cookies et du post data à la fois avec la commande wget et son équivalent en Python 3

La commande Wget dans un petit script :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
#!/bin/bash
login=$login
pass=$password

#Récupération des premiers cookies
wget -dO /dev/null --cookies=on --keep-session-cookies --save-cookies=cookies.txt "https://assure.ameli.fr/PortailAS/appmanager/PortailAS/assure"

#Deuxième passage pour récupérer les cookies sécurisés
wget -dO /dev/null --cookies=on --keep-session-cookies --save-cookies=cookies.txt --load-cookies=cookies.txt --post-data "connexioncompte_2numSecuriteSociale=$login&connexioncompte_2codeConfidentiel=$pass&connexioncompte_2actionEvt=connecter&submit=validerFormulaire(this)" "https://assure.ameli.fr/PortailAS/appmanager/PortailAS/assure"

#Troisième passage pour se connecter
wget -dO index.html --cookies=on --keep-session-cookies --save-cookies=cookies.txt --load-cookies=cookies.txt --post-data  "connexioncompte_2numSecuriteSociale=$login&connexioncompte_2codeConfidentiel=$pass&connexioncompte_2actionEvt=connecter&submit=validerFormulaire(this)" "https://assure.ameli.fr/PortailAS/appmanager/PortailAS/assure"

Nous allons être obligé de faire plusieurs passages pour récupérer les cookies. Sur les deux premiers passages, je ne conserve pas de fichiers de sortie en envoyant le résultat de la requête vers /dev/null. En revanche, mes cookies seront bien conservés dans le fichiers cookies.txt grâce à l'option --save-cookies.

Pour le post, un petit coup d'extension web developer de firefox fera l'affaire. Cela permet d'identifier les zones de formulaires à remplir.

La même chose en Python 3

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#!/usr/bin/python3.2
import urllib.request, urllib.parse, urllib.error
import http.cookiejar

#Le fichier qui va stocker les cookies
cj = http.cookiejar.LWPCookieJar

#Des raccourcis pour lancer les requêtes
urlopen = urllib.request.urlopen
Request = urllib.request.Request
urlencode = urllib.parse.urlencode

#Modification de l'opener pour gérer les cookies
opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cj))
urllib.request.install_opener(opener)

#Notre fonction pour ouvrir les pages html avec gestion des cookies et de l'encodage
#avec gestion du retour du code erreur
def requete(url, values):
   data = urlencode(values)
   data = data.encode('utf-8')
   req = Request(url, data)
   try:
       handle = urlopen(req)
   except IOError as err:
       if hasattr(err,'reason'):
           print(url)
           print('Reason:',err.reason)          
       elif hasattr(err,'code'):
           print(url)
           print('Code erreur',err.code)
   else:
       return handle

login = $login
password = $password

url = "https://assure.ameli.fr/PortailAS/appmanager/PortailAS/assure"
values = {'connexioncompte_2numSecuriteSociale' : login,
         'connexioncompte_2codeConfidentiel' : password,
         'connexioncompte_2actionEvt' : 'connecter',
         "submit" : "validerFormulaire(this)"}

#Deux passages pour récupérer les cookies puis le cookie sécurisé
handle = requete(url, values)
handle = requete(url, values)
print('These are the cookies we have received so far :')
for index, cookie in enumerate(cj):
   print(index, '  :  ', cookie)

the_page = open("the_page.html", "wb")
the_page.write(handle.read())
the_page.close()

Dans values, nous allons trouver l'équivalent du post de wget. Il faut l'encoder en binaire en Python 3 d'où le urlencode.

Pourquoi écrire en plusieurs lignes Python quelquechose qui tient en 3 lignes en bash :

  • Je vais pouvoir réutiliser le code pour d'autres connexions
  • Je vais pouvoir mutualiser du code (gestion de l'opener, de la requête, ...)
  • Je vais pouvoir l'insérer dans un programme plus large

Si certains sont intéressés, j'ai le même en Python 2.