11.5. Changer la chaîne User-Agent

La première chose à faire pour améliorer notre client de services Web HTTP est de faire en sorte qu'il s'identifie correctement avec une chaîne User-Agent. Pour cela, nous devons aller plus loin qu'urllib et plonger dans urllib2.

Exemple 11.4. Présentation de urllib2

>>> import httplib
>>> httplib.HTTPConnection.debuglevel = 1                             1
>>> import urllib2
>>> request = urllib2.Request('http://diveintomark.org/xml/atom.xml') 2
>>> opener = urllib2.build_opener()                                   3
>>> feeddata = opener.open(request).read()                            4
connect: (diveintomark.org, 80)
send: '
GET /xml/atom.xml HTTP/1.0
Host: diveintomark.org
User-agent: Python-urllib/2.1
'
reply: 'HTTP/1.1 200 OK\r\n'
header: Date: Wed, 14 Apr 2004 23:23:12 GMT
header: Server: Apache/2.0.49 (Debian GNU/Linux)
header: Content-Type: application/atom+xml
header: Last-Modified: Wed, 14 Apr 2004 22:14:38 GMT
header: ETag: "e8284-68e0-4de30f80"
header: Accept-Ranges: bytes
header: Content-Length: 26848
header: Connection: close
1 Si vous avez gardé votre IDE Python ouverte avec l'exemple de la section précédente, vous pouvez sauter cette étape, cette instruction active le débogage HTTP pour que nous puissions voir ce qui est exactement envoyé et ce qui est reçu.
2 Obtenir une ressource HTTP avec urllib2 se fait en trois étape, pour des raisons qui seront bientôt claires. La première étape est la création d'un objet Request, qui prend en paramètre l'URL de la ressource que nous voulons obtenir. Notez que cette étape n'effectue encore aucune requête.
3 La seconde étape est de construire un opener d'URL. Celui-ci peut prendre en paramètre un nombre quelconque de gestionnaires (handlers) qui contrôleront la gestion des réponses. Nous pouvons aussi construire un opener sans gestionnaire particulier, ce que nous faisons ici. Nous verrons comment définir et utiliser des gestionnaires spécialisés plus loin dans ce ce chapitre lorsque nous traiterons des redirections.
4 La dernière étape est de dire à l'opener d'ouvrir l'URL avec l'objet Request que nous avons créé. Comme vous pouvez le voir à l'affichage des informations de débogage, cette étape effectue véritablement la requête et stocke les données obtenues dans feeddata.

Exemple 11.5. Ajout d'en-têtes avec l'objet Request

>>> request                                                1
<urllib2.Request instance at 0x00250AA8>
>>> request.get_full_url()
http://diveintomark.org/xml/atom.xml
>>> request.add_header('User-Agent',
...     'OpenAnything/1.0 +http://diveintopython.org/')    2
>>> feeddata = opener.open(request).read()                 3
connect: (diveintomark.org, 80)
send: '
GET /xml/atom.xml HTTP/1.0
Host: diveintomark.org
User-agent: OpenAnything/1.0 +http://diveintopython.org/   4
'
reply: 'HTTP/1.1 200 OK\r\n'
header: Date: Wed, 14 Apr 2004 23:45:17 GMT
header: Server: Apache/2.0.49 (Debian GNU/Linux)
header: Content-Type: application/atom+xml
header: Last-Modified: Wed, 14 Apr 2004 22:14:38 GMT
header: ETag: "e8284-68e0-4de30f80"
header: Accept-Ranges: bytes
header: Content-Length: 26848
header: Connection: close
1 C'est la suite de l'exemple précédent, nous avons déjà créé un objet Request avec l'URL à laquelle nous voulons accéder.
2 En utilisant la méthode add_header de l'objet Request, nous pouvons ajouter les en-têtes HTTP de notre choix à la requête. Le premier paramètre est l'en-tête, le deuxième est la valeur fournie pour cet en-tête. Par convention, une chaîne User-Agent a le format suivant : un nom d'application, suivi d'une barre oblique, suivi d'un numéro de version. Le reste est de forme libre, on en voit de nombreuses variations, mais il doit contenir l'URL de l'application. La chaîne User-Agent est en général enregistrée par le serveur dans son journal avec d'autres détails de la requête, inclure une URL de l'application permet aux administrateurs de serveurs de contacter l'auteur en cas de problème.
3 L'objet opener que nous avons créé précédemment peut être réutilisé lui aussi, il ouvrira à nouveau le même fil, mais avec l'en-tête User-Agent que nous avons défini.
4 Voici la chaîne User-Agent spécialisée que nous avons définie à la place de la chaîne générique envoyée par défaut par Python. Si vous regardez attentivement, vous verrez que nous avons défini un en-tête User-Agent, mais que ce qui a été envoyé est un en-tête User-agent. Vous voyez la différence ? urllib2 a modifié la casse de manière à ce que seule la première lettre soit en majuscule. Cela n'a aucune importance, le protocole HTTP spécifie que les noms de champs d'en-têtes sont insensibles à la casse.