[PageD'Accueil] [IndexDesTitres] [IndexDesTermes

Pour Python

Pyro

Twisted Python

Exemples de code

FTP

Rien de plus facile que d'envoyer un fichier par FTP:

import ftplib                                              # On importe le module FTP de Python
session = ftplib.FTP('212.12.34.56','sebsauvage','batman') # On se connecte au serveur (serveur, login, mot de passe)
monfichier = open('toto.txt','rb')                         # On ouvre le fichier à envoyer
session.storbinary('STOR toto.txt', monfichier)            # On envoie le fichier
monfichier.close()                                         # On ferme le fichier
session.quit()                                             # On se déconnecte

Vous avez bien entendu à votre disposition toutes les autres commandes FTP (lister un répertoire, changer de répertoire, reprendre un téléchargement interrompu, renommer un fichier...) dans le module ftplib. (Voir http://python.org/doc/current/lib/ftp-objects.html)

un mini serveur HTTP

from BaseHTTPServer import HTTPServer
from SimpleHTTPServer import SimpleHTTPRequestHandler
import os

os.chdir('/home/oli/dev/python/httpserver') # le répertoire où les pages html seront stockées.

serv = HTTPServer( ("", 10080), SimpleHTTPRequestHandler)
serv.serve_forever()

Dans ce répertoire, vous placer un fichier index.html, ainsi que toutes les autres pages.

Avant dernière ligne: 10080 est le port réseau utilisé. Les ports inférieurs ou égaux à 1024 ne sont utilisables que par root.

PS: très pratique pour échanger des fichiers de machines à machines lorsque FTP n'est pas disponible.

Une article plus complet est disponible a cette adresse:

http://etudiant.epita.fr/~duponc_j/articles/webinterface.html

récupérer un forum Usenet (newsgroups, NNTP)

Voici un petit programme qui permet de récupérer tous les messages d'un forum. Chaque message est sauvegardé dans un fichier individuel. Vous pouvez à tout moment interrompre le script et le relancer: il reprendra là où il en était.

http://sebsauvage.net/python/newsarchiver.py

En lançant ce script tous les jours, vous pouvez ainsi archiver tous les messages d'un forum.

Sockets

Un exemple simple

Vous trouverez dans la documentation de Python un exemple de serveur et client socket très simple: http://docs.python.org/lib/socket-example.html

Le serveur se met en écoute sur le port 50007, et le client vient s'y connecter pour écrire "Hello, world". Le serveur renvoie cette chaîne au client.

Sockets non bloquants

Par défaut, l'utilisation de sockets est bloquant (lors d'un .recv() par exemple).

Pour travailler avec des sockets non bloquants, vous avez 2 solutions:

Chaque solution a ses avantages.

Les sockets asynchrones sont intéressants quand votre goulot d'étranglement est le débit réseau.
Les threads sont intéressants quand votre goulot d'étranglement est le traitement CPU.

Voici un article en anglais avec des exemples pour chacune de ces méthodes: http://www.onlamp.com/pub/a/python/2004/02/12/advanced_nio.html

Pour faire des sockets asynchrone, vous pouvez utiliser les module asyncore et asynchat de Python. Notez qu'il existe des frameworks qui simplifient l'utilisation des sockets asynchrone, tels que Twisted http://www.twistedmatrix.com/.

Pour les threads, le module thread de Python est à votre disposition. Le module threading vous offre même une interface de plus haut niveau, plus simple à manipuler.

Les proxy

Les modules urllib et urllib2 vous permettent de faire des requêtes HTTP.

urllib2 s'utilise de la même façon qu'urllib, mais il supporte également les proxy, avec ou sans mot de passe.

Voici comment l'utiliser. (Code inspiré de http://groups.google.com/groups?selm=mailman.983901970.11969.python-list%40python.org)

Passer par un proxy

   1 proxy_info = { 'host' : 'netcache.monentreprise.com',
   2                'port' : 3128
   3              }
   4 # On créé un handler pour le proxy:
   5 proxy_support = urllib2.ProxyHandler({"http" : "http://%(host)s:%(port)d" % proxy_info})
   6 # On créé un opener utilisant ce handler:
   7 opener = urllib2.build_opener(proxy_support)
   8 # Puis on installe cet opener comme opener par défaut du module urllib2.
   9 urllib2.install_opener(opener)
  10 
  11 # Et on peut alors lancer nos requêtes HTTP:
  12 pagehtml = urllib2.urlopen("http://wikipython.flibuste.net/").read()

Passer par un proxy avec mot de passe

C'est presque la même chose, mais on ajoute login et mot de passe:

   1 proxy_info = { 'host' : 'netcache.monentreprise.com',
   2                'port' : 3128,
   3                'user' : 'gaston lagaffe',
   4                'pass' : 'jeanne55'
   5              }
   6 proxy_support = urllib2.ProxyHandler({"http" : "http://%(user)s:%(pass)s@%(host)s:%(port)d" % proxy_info})
   7 opener = urllib2.build_opener(proxy_support)
   8 urllib2.install_opener(opener)
   9 
  10 # Et on peut alors lancer nos requêtes HTTP:
  11 pagehtml = urllib2.urlopen("http://wikipython.flibuste.net/").read()

Modification : urllib2 ne semble pas fonctionner avec l'authentification proxy. Ceci est apparemment un bug connu. La librairie pycurl est la plus avancée sur ce sujet

Note de sebsauvage: Si si ça marche, j'utilise urllib2 avec proxy (et login/mot de passe) sans problème dans webGobbler (http://sebsauvage.net/webgobbler). Notez qu'il existe plusieurs méthodes d'authentification pour les proxy HTTP: Basic, Digest, NTLM... En Python 2.4.1, urllib2 supporte 2 authentifications: Basic et Digest. Si votre proxy ne supporte que NTLM (protocole Microsoft, supporté par Internet Explorer), vous n'avez pas de chance.

Passer par un proxy avec mot de passe vi Authentification Proxy

La methode precedente ne fonctionne pas sur mon proxy: (authentification via un serveur de domaine NT), j'ai donc implementé un Handler Basic d'Authentification (Proxy compatible heureusement) au lieu du Handler de Proxy standard. Pour ceux dont le proxy est compatible Digest choisir ProxyDigestAuthHandler.

   1 import urllib2
   2 
   3 passwdMgr = urllib2.HTTPPasswordMgrWithDefaultRealm()
   4 passwdMgr.add_password(None, "proxy:8080", r"DOMAINE\jvacher", "monpassamoi")
   5 opener = urllib2.build_opener(urllib2.ProxyBasicAuthHandler(passwdMgr))
   6 urllib2.install_opener(opener)
   7 
   8 pagehtml = urllib2.urlopen("http://wikipython.flibuste.net/").read()
   9 print pagehtml

Voilà j'éspère que cela en aidera certains. Jérôme Vacher alias jerrykhan

urllib/urllib2

User-agent

En principe, si vous avez créé une application qui envoie des requêtes HTTP, la netiquette dit qu'elle devrait s'identifier proprement dans le champ "User-Agent" des requêtes HTTP.

Par défaut, Python utilise le User-Agent Python-urllib/1.16

Voici comment mettre votre propre User-Agent:

   1 request_headers = { 'User-Agent': 'PeekABoo/1.3.7' }
   2 request = urllib2.Request('http://sebsauvage.net', None, request_headers)
   3 urlfile = urllib2.urlopen(request)

En règle générale:

Gestion d'erreur

Voici comment gérer les codes d'erreur HTTP (404 et autres) avec urllib2:

   1 try:
   2     urlfile = urllib2.urlopen('http://sebsauvage.net/nonexistingpage.html')
   3 except urllib2.HTTPError, exc:
   4     if exc.code == 404:
   5         print "Page non trouvée !"
   6     else:           
   7         print "La requête HTTP a échoué avec le code %d (%s)" % (exc.code, exc.msg)
   8 except urllib2.URLError, exc:
   9     print "Echec. Cause:", exc.reason

De cette manière, vous pouvez tester les 404 et autres codes d'erreur HTTP. Notez que urllib2 ne lèvera pas d'exception pour les codes 2xx et 3xx. L'exception urllib2.HTTPError sera levée pour les codes 4xx et 5xx (ce qui est le comportement attendu).

Notez également que les codes de redirection 30x sont gérés automatiquement et de manière transparente par urllib2.

Content-type

Quand vous envoyez une requête HTTP, elle peut retourner du HTML, des images, des fichiers zip... Par exemple, une requête comme http: //toto.com/image.gif peut très bien retourner du HTML ! Il est nécessaire de contrôller le type des données que vous recevez.

Il suffit de regarder dans le champ "Content-type" des entêtes HTTP de réponse. Par exemple:

   1 urlfile = urllib2.urlopen('http://www.commentcamarche.net/')
   2 print "Le type de document est", urlfile.info().getheader("Content-Type","")

Ce qui donne par exemple:

Le type de document est text/html

Mais attention, il arrive qu'il y ait des informations supplémentaires, telles que:

Le type de document est text/html; charset=iso-8859-1

Donc je vous recommande d'utiliser systématiquement:

   1 print "Document type is", urlfile.info().getheader("Content-Type","").split(';')[0].strip()

pour être sûr de bien récupérer le Content-type seul.

Notez que .info() vous donnera les autres entêtes réponse HTTP:

   1 print "HTTP Response headers:"
   2 print urlfile.info()

ce qui donne des choses telles que:

Document type is Date: Thu, 23 Mar 2006 15:13:29 GMT
Content-Type: text/html; charset=iso-8859-1
Server: Apache
X-Powered-By: PHP/5.1.2-1.dotdeb.2
Connection: close

Gérer les cookies

Depuis la version 2.4, Python contient le module cookielib qui peut gérer automatiquement les cookies.
(Notez qu'il est possible d'avoir une gestion des cookies dans les versions précédentes de Python avec des modules séparés tels que ClientCookie).

Les cookies sont utile pour parcourir les sites qui nécessite un login/password: Ces sites gèrent habituellement les sessions avec un cookie.

Voici un exemple: Se loguer sur le site imdb.com:

   1 import cookielib, urllib, urllib2
   2 
   3 login = 'ismellbacon123@yahoo.com'
   4 password = 'login'
   5 
   6 # On active le support des cookies pour urllib2
   7 cookiejar = cookielib.CookieJar()
   8 urlOpener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookiejar))
   9 
  10 # On envoie login/password au site qui nous renvoie un cookie de session
  11 values = {'login':login, 'password':password }
  12 data = urllib.urlencode(values)
  13 request = urllib2.Request("http://www.imdb.com/register/login", data)
  14 url = urlOpener.open(request)  # Notre cookiejar reçoit automatiquement les cookies
  15 page = url.read(500000)
  16 
  17 # On s'assure qu'on est bien logué en vérifiant la présence du cookie "id"
  18 # (qui est - sur le site imdb.com - le cookie contenant l'identifiant de session.)
  19 if not 'id' in [cookie.name for cookie in cookiejar]:
  20     raise ValueError, "Echec connexion avec login=%s, mot de passe=%s" % (login,password)
  21 
  22 print "Nous sommes connecte !"
  23 
  24 # Maintenant on fait une autre requête sur le site avec notre cookie de session.
  25 # (Notre urlOpener utilise automatiquement les cookies de notre cookiejar)
  26 url = urlOpener.open('http://imdb.com/find?s=all&q=grave')
  27 page = url.read(200000)

Il n'est généralement pas utile de vous déloguer.


2016-06-05 21:42