cookielib et ClientCookie

Comment gérer les Cookies en Python

Note

This translation was done by Gerard Labadie.

There is an English version of this article - cookielib et ClientCookie.

 

 

Introduction

Certains sites webs imposent la validation des cookies pour autoriser la navigation. Les cookies sont utilisés pour stocker une information sur la session ou pour confirmer l'identité d'un utilisateur. Parfois ils sont utilisés comme une alternative à une authentification basique. Le module correct pour récupérer des pages web ou d'autres ressources sur Internet est en général ''urllib2''. Il offre une interface simple pour récupérer des ressources en utilisant différents protocoles.Pour une bonne introduction à urllib2, consultez le tutoriel urllib2.

Cependant il ne gère pas les cookies par défaut.Vous aurez besoin d'une librairie supplémentaire pour faire cela.. Dans Python 2.4 c'est cookielib qui est inclus dans la distribution standard.. Avant Python 2.4 il existait ClientCookie, mais ce n'est pas exactement l'équivalent. Dans Python 2.4 certaines fonctions de ClientCookie ont été incluses dans urllib2. Il est possible d'écrire du code qui fonctionnera de la même manière dans ces situations. Cet article montre comment utiliser cookielib/ClientCookie et démontre du code pour récupérer des URIs qui fonctionnera de la même manière :

  • avec une machine avec Python 2.4 (et cookielib)
  • avec une machine avec ClientCookie
  • avec une machine qui n'a aucun des précédents

Si cookielib ou ClientCookie est disponible alors les cookies seront écrits dans un fichier. Sur une machine sans cookielib/ClientCookie, les URLs seront cherchés - mais les cookies envoyés ne seront pas gérés ou sauvés.

Cookies

Quand un site web envoie une page à un client, il envoie d'abord un jeu de headers qui décrit la transaction http . L'un de ces headers peut contenir une ligne de texte qui est le cookie. Si vous récupérez une autre page du même serveur, alors le cookie devrait être renvoyé au serveur dans l'un des request headers. Cela permet au cookie de stocker l'information que le serveur peut utiliser pour vous identifier, or pour identifier la session sur laquelle vous êtes connecté. Evidemment dans certains cas, cette information est essentielle.

Le navigateur Netscape a été le premier à supporter cela, en conséquence la première spécification s'est appelée Netscape cookie protocol. Elle est décrite dans RFC 2109, et ensuite il y a eu une tentative de l'étendre dans le RFC:2965 - qui n'a jamais été adopté largement.

En fait, le protocole implémenté par les principaux navigateurs est toujours basé sur le Netscape protocol. Aujourd'hui il n'a qu'une vague ressemblance avec ce qu'il était au départ.

Conditional Imports

Une version de ce code a été imprimée dans la deuxième édition du Python Cookbook. Il a été inclus dans ce livre car il illustre un intéressant idiome de programmation appelé conditional import. Cela est particulièrement important dans ce tutoriel car nous avons besoin que le comportement de ce code soit légèrement différent en fonction de la librairie qui est présente. L' interface que nous presentons au programmeur est le même dans les trois cas..

Soyez attentifs à la première partie de code qui tente d'importer les cookie libraries. Il faut mettre en place un comportement différent en fonction de la librairie importée. Le motif qu'il utilise est :

library = None

try:
    import library
except ImportError:
    # library pas disponible
    setup alternate behaviour
     ....

else:
    # library est disponible
    establish normal behaviour
     ....

Nous utilisons le nom de la librairie importée comme un marqueur, en le déclarant à None au début. Plus tard dans le code nous savons si la librairie est disponible avec du code comme ce qui suit :

if library is None:
    # nous savons que la librairie n'est pas disponible
    provide different or reduced function
     ....
else:
    # librarie est disponible
     .....

Le Code

Le code montré dans cet article peut être téléchargé à partir de Voidspace Recipebook.

Dans la première section nous essayons d'importer une librairie pour gérer les cookies. Nous essayons cookielib, puis ClientCookie. Si aucun n'est disponible, alors nous prenons urllib2.

import os.path
import urllib2

COOKIEFILE = 'cookies.lwp'
# le chemin et fichier pour sauvegarder vos cookies

cj = None
ClientCookie = None
cookielib = None

# Voyons si cookielib est disponible
try:
    import cookielib
except ImportError:
    # si l'import cookielib échoue
    # essayons ClientCookie
    try:
        import ClientCookie
    except ImportError:
        # ClientCookie n'est pas disponible non plus
        urlopen = urllib2.urlopen
        Request = urllib2.Request
    else:
        # imported ClientCookie
        urlopen = ClientCookie.urlopen
        Request = ClientCookie.Request
        cj = ClientCookie.LWPCookieJar()

else:
    # l'import de cookielib a fonctionné
    urlopen = urllib2.urlopen
    Request = urllib2.Request
    cj = cookielib.LWPCookieJar()
    # cela est une subclass de FileCookieJar
    # qui a des méthodes load et save  utiles

Nous avons maintenant importé la bonne librarie. Quelle que soit la librairie utilisée, le nom urlopen est lié à la bonne fonction pour récupérer des URLs. Le nom Request est lié à la bonne classe pour créer des Request objects. Si nous parvenons à importer une librairie pour gérer les cookies alors le nom cj est lié à l'instance CookieJar.

Installation du CookieJar

Maintenant nous avons besoin d'avoir notre CookieJar installé dans l' opener par défaut pour récupérer des URLs. Cela signifie que tous les appels à urlopen vont avoir les cookies gérés. La gestion est faite par un objet appelé HTTPCookieProcessor. Si les termes opener et handler sont nouveaux pour vous, alors lisez soit la doc urllib2 ou mon urllib2 tutorial.

Tout cela est fait dans ClientCookie ou dans urllib2, en fonction du module importé avec succès.

if cj is not None:
# import réussi
# d'un des 2 modules de gestion des cookies

    if os.path.isfile(COOKIEFILE):
        # si nous avons un fichier cookie déjà sauvegardé
        #  alors charger les cookies dans le Cookie Jar
         cj.load(COOKIEFILE)

    # Maintenant nous avons besoin d'avoir notre Cookie Jar
    # installé dans l'opener;
    # pour chercher des URLs
    if cookielib is not None:
        # si nous utilisons cookielib
        # alors nous appelons HTTPCookieProcessor
        # et installons l'opener dans urllib2
        opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
        urllib2.install_opener(opener)

    else:
        # si nous utilisons ClientCookie
        # alors nous appelons HTTPCookieProcessor
        # et installons l'opener dans ClientCookie
        opener = ClientCookie.build_opener(ClientCookie.HTTPCookieProcessor(cj))
        ClientCookie.install_opener (opener)

Si une librairie de gestion des cookies est disponible, n'importe quel appel à urlopen va maintenant gérer les cookies en utilisant l'instance CookieJar que nous avons créée.

Récupérer des pages Web

Après avoir fait tout le sale boulot, nous sommes prêts à aller récupérer des pages web. N'importe quel cookie envoyé sera maintenant géré. Cela signifie que les cookies seront stockés dans le CookieJar, renvoyé au serveur si besoin, et expireront également au moment voulu. Comme il se peut que nous redémarrions la même session une autre fois, nous sauvons les cookies quannd nous avons fini.

theurl = ' http://www.google.co.uk/search?hl=en&ie=UTF-8&q=voidspace&meta= '
# un exemple d'url qui définit un cookie,
# essayez différents urls ici et voyez la collection de cookies obtenus !

txdata = None
# si nous étions en train de faire un requête de type POST
# nous encoderions a dictionary de valeurs ici,
# avec urllib.urlencode(somedict)

txheaders =  {'User-agent' : 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'}
# singeant un faux user agent, certains websites (comme google) n'aiment pas les robots

try:
    req = Request(theurl, txdata, txheaders)
    # création d'un objet request

    handle = urlopen(req)
    # on l'ouvre pour renvoyer un handle sur l'url

except IOError, e:
    print 'We failed to open "%s".' % theurl
    if hasattr(e, 'code'):
        print 'We failed with error code - %s.' % e.code
    elif hasattr(e, 'reason'):
        print "The error object has the following 'reason' attribute :"
        print e.reason
        print "This usually means the server doesn't exist,',
        print "is down, or we don't have an internet connection."
    sys.exit()

else:
    print 'Here are the headers of the page :'
    print handle.info()
    # handle.read() renvoie la page
    # handle.geturl() renvoie la véritable url de la page demandée
    # (au cas où urlopen a été redirigé, ce qui arrive parfois)

print
if cj is None:
    print "We don't have a cookie library available - sorry."
    print "I can't show you any cookies."
else:
    print 'These are the cookies we have received so far :'
    for index, cookie in enumerate(cj):
        print index, '  :  ', cookie
    # save the cookies again
    cj.save(COOKIEFILE)

Si vous voulez adapter ce code pour vous, il faut noter que :

Nous pouvons toujours savoir quel import a réussi :

  • si on utilisait cookielib alors cookielib n'est pas None.
  • si on utilisait ClientCookie alors ClientCookie is not None.
  • si on utilisait aucun des 2 cj is None.

Request est le nom lié à la fonction pour créer l'objet Request et urlopen est le nom lié à la fonction pour ouvrir des URLs quelque soit la librairie utilisée !!

[1]Ou le chemin défini dans le cookie.
[2]Voyez ce document par David Kristol` et la the cookie FAQ pour plus d' information sur les cookies que vous en avez jamais rêvé..

For buying techie books, science fiction, computer hardware or the latest gadgets: visit The Voidspace Amazon Store.

Hosted by Webfaction

Return to Top

Page rendered with rest2web the Site Builder

Last edited Tue Aug 2 00:51:34 2011.

Counter...