2009-07-23 11 views
19

J'écris une application Web qui utilise plusieurs API Web tierces, et je veux garder une trace de la requête de bas niveau et des réponses pour l'analyse du jarret. Je suis donc à la recherche d'une recette qui permettra à urllib2 de Python de consigner tous les octets transférés via HTTP. Peut-être un Handler sous-classé?Comment obtenir urllib2 pour consigner TOUS les octets transférés

+0

+1 Très belle question de python posée il y a presque 2 ans sans les upvotes. C'est vraiment bizarre. Je cherche une réponse moi-même. Dans mon cas, je ne suis concerné que par les en-têtes HTTP. –

Répondre

12

Eh bien, je l'ai trouvé comment configurer le mécanisme de débogage intégré de la bibliothèque:

import logging, urllib2, sys 

hh = urllib2.HTTPHandler() 
hsh = urllib2.HTTPSHandler() 
hh.set_http_debuglevel(1) 
hsh.set_http_debuglevel(1) 
opener = urllib2.build_opener(hh, hsh) 
logger = logging.getLogger() 
logger.addHandler(logging.StreamHandler(sys.stdout)) 
logger.setLevel(logging.NOTSET) 

Mais je suis toujours à la recherche d'un moyen de vider toutes les informations transférées.

2

Cela semble assez difficile à faire. Il n'y a pas de hook dans urllib2, urllib, ou httplib (sur lequel cela se base) pour intercepter les données d'entrée ou de sortie. La seule chose qui me vient à l'esprit, hormis le fait de changer de tactique pour utiliser un outil externe (dont beaucoup utilisent la plupart des gens), serait d'écrire une sous-classe de socket.socket dans votre propre nouveau module (par exemple, "capture_socket"), puis insérez-le dans httplib en utilisant "importer capture_socket, importer httplib; httplib.socket = capture_socket". Vous devrez copier toutes les références nécessaires (quelque chose de la forme "socket.foo" qui est utilisée dans httplib) dans votre propre module, mais alors vous pourriez surcharger des choses comme recv() et sendall() dans votre sous-classe pour faire ce que vous aimez avec les données.

Des complications se produiraient probablement si vous utilisiez SSL, et je ne sais pas si cela serait suffisant ou si vous deviez aussi créer votre propre fichier socket._fileobject. Cela semble réalisable, et lire la source dans httplib.py et socket.py dans la bibliothèque standard vous en dira plus.