51 votes

Python : Obtenir les en-têtes HTTP à partir de l'appel à urllib2.urlopen ?

Fait urllib2 récupérer la page entière lorsqu'un urlopen l'appel est fait ?

J'aimerais juste lire l'en-tête de la réponse HTTP sans obtenir la page. Cela ressemble à urllib2 ouvre la connexion HTTP et obtient ensuite la page HTML proprement dite... ou bien commence-t-il simplement à mettre la page en mémoire tampon avec la balise urlopen appeler ?

import urllib2
myurl = 'http://www.kidsidebyside.org/2009/05/come-and-draw-the-circle-of-unity-with-us/'
page = urllib2.urlopen(myurl) // open connection, get headers

html = page.readlines()  // stream page

52voto

tolmeda Points 276

Utilisez le response.info() pour obtenir les en-têtes.

De la docs urllib2 :

urllib2.urlopen(url[, data][, timeout])

...

Cette fonction renvoie un objet de type fichier avec deux méthodes supplémentaires :

  • geturl() - renvoie l'URL de la ressource récupérée, généralement utilisée pour déterminer si une redirection a été suivie.
  • info() - renvoie les méta-informations de la page, comme les en-têtes, sous la forme d'une instance httplib.HTTPMessage (voir Référence rapide aux en-têtes HTTP)

Donc, pour votre exemple, essayez de parcourir le résultat de response.info().headers pour ce que vous recherchez.

Notez que la principale mise en garde concernant l'utilisation de httplib.HTTPMessage est documentée dans le document suivant problème python 4773 .

22 votes

Note sur Python 3 D'abord, il n'y a rien comme response.info().headers , faites un dict(response.info()) . Ensuite, pour le code d'état HTTP, faites response.status .

1 votes

Est-ce que ne reçoit que l'en-tête ou uniquement les impressions l'en-tête ?

3 votes

Où se trouve headers documenté ? Pensez également à utiliser response.info().items() qui renvoie un dictateur clé-valeur.

42voto

reto Points 4255

Pourquoi ne pas envoyer une requête HEAD au lieu d'une requête GET normale ? L'extrait suivant (copié à partir d'un site similaire) est un exemple de la façon dont on peut envoyer une requête HEAD. question ) fait exactement cela.

>>> import httplib
>>> conn = httplib.HTTPConnection("www.google.com")
>>> conn.request("HEAD", "/index.html")
>>> res = conn.getresponse()
>>> print res.status, res.reason
200 OK
>>> print res.getheaders()
[('content-length', '0'), ('expires', '-1'), ('server', 'gws'), ('cache-control', 'private, max-age=0'), ('date', 'Sat, 20 Sep 2008 06:43:36 GMT'), ('content-type', 'text/html; charset=ISO-8859-1')]

23voto

Simon Tewsi Points 2785

En fait, il semble que urllib2 puisse faire une requête HTTP HEAD.

Le site question que @reto a mis en lien, ci-dessus, montre comment faire en sorte que urllib2 fasse une requête HEAD.

Voici ce que j'en pense :

import urllib2

# Derive from Request class and override get_method to allow a HEAD request.
class HeadRequest(urllib2.Request):
    def get_method(self):
        return "HEAD"

myurl = 'http://bit.ly/doFeT'
request = HeadRequest(myurl)

try:
    response = urllib2.urlopen(request)
    response_headers = response.info()

    # This will just display all the dictionary key-value pairs.  Replace this
    # line with something useful.
    response_headers.dict

except urllib2.HTTPError, e:
    # Prints the HTTP Status code of the response but only if there was a 
    # problem.
    print ("Error code: %s" % e.code)

Si vous vérifiez cela avec quelque chose comme l'analyste de protocole réseau Wireshark, vous pouvez voir qu'il envoie en fait une demande HEAD, plutôt qu'une demande GET.

Voici la demande et la réponse HTTP du code ci-dessus, telles que capturées par Wireshark :

HEAD /doFeT HTTP/1.1
Accept-Encoding : identité
Hôte : bit.ly
Connexion : close
User-Agent : Python-urllib/2.7

HTTP/1.1 301 Déplacement
Serveur : nginx
Date : Sun, 19 Feb 2012 13:20:56 GMT
Content-Type : text/html ; charset=utf-8
Cache-control : private ; max-age=90
Emplacement : http://www.kidsidebyside.org/?p=445
MIME-Version : 1.0
Content-Length : 127
Connexion : close
Set-Cookie : _bit=4f40f738-00153-02ed0-421cf10a;domain=.bit.ly;expires=Fri Aug 17 13:20:56 2012;path=/ ; HttpOnly

Cependant, comme mentionné dans l'un des commentaires de l'autre question, si l'URL en question inclut une redirection, urllib2 fera une requête GET vers la destination, et non HEAD. Cela pourrait être un inconvénient majeur, si vous vouliez vraiment ne faire que des requêtes HEAD.

La demande ci-dessus implique une redirection. Voici la requête vers la destination, telle que capturée par Wireshark :

GET /2009/05/come-and-draw-the-circle-of-unity-with-us/ HTTP/1.1
Accept-Encoding : identité
Hôte : www.kidsidebyside.org
Connexion : close
User-Agent : Python-urllib/2.7

Une alternative à l'utilisation d'urllib2 est d'utiliser l'application de Joe Gregorio httplib2 bibliothèque :

import httplib2

url = "http://bit.ly/doFeT"
http_interface = httplib2.Http()

try:
    response, content = http_interface.request(url, method="HEAD")
    print ("Response status: %d - %s" % (response.status, response.reason))

    # This will just display all the dictionary key-value pairs.  Replace this
    # line with something useful.
    response.__dict__

except httplib2.ServerNotFoundError, e:
    print (e.message)

Cela présente l'avantage d'utiliser les requêtes HEAD à la fois pour la requête HTTP initiale et pour la requête redirigée vers l'URL de destination.

Voici la première demande :

HEAD /doFeT HTTP/1.1
Hôte : bit.ly
accepter-encodage : gzip, deflate
agent utilisateur : Python-httplib2/0.7.2 (gzip)

Voici la deuxième demande, vers la destination :

HEAD /2009/05/come-and-draw-the-circle-of-unity-with-us/ HTTP/1.1
Hôte : www.kidsidebyside.org
Accepter l'encodage : gzip, deflate
agent utilisateur : Python-httplib2/0.7.2 (gzip)

0 votes

Je l'ai manqué la première fois que j'ai lu la réponse, mais response.info().dict est exactement ce que je recherchais. C'est pas a expliqué dans les docs .

8voto

Alex Martelli Points 330805

Urllib2.urlopen fait un HTTP GET (ou POST si vous fournissez un argument de données), pas un HTTP HEAD (s'il faisait ce dernier, vous ne pourriez pas faire des readlines ou d'autres accès au corps de la page, bien sûr).

4voto

quanta Points 541

Un seul mot :

$ python -c "import urllib2; print urllib2.build_opener(urllib2.HTTPHandler(debuglevel=1)).open(urllib2.Request('http://google.com'))"

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X