web-dev-qa-db-fra.com

Comment envoyer une requête HTTP HEAD dans Python 2?

Ce que j'essaie de faire ici, c'est d'obtenir les en-têtes d'une URL donnée afin que je puisse déterminer le type MIME. Je veux pouvoir voir si http://somedomain/foo/ renverra un document HTML ou une image JPEG par exemple. Ainsi, j'ai besoin de comprendre comment envoyer une demande HEAD afin que je puisse lire le type MIME sans avoir à télécharger le contenu. Quelqu'un connaît-il un moyen facile de le faire?

108
fuentesjr

edit : Cette réponse fonctionne, mais de nos jours vous devez simplement utiliser la bibliothèque requêtes comme mentionné par les autres réponses ci-dessous.


Utilisez httplib .

>>> 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')]

Il y a aussi une getheader(name) pour obtenir un en-tête spécifique.

104
Eevee

rllib2 peut être utilisé pour effectuer une demande HEAD. C'est un peu plus agréable que d'utiliser httplib car urllib2 analyse l'URL pour vous au lieu de vous obliger à diviser l'URL en Nom d'hôte et chemin d'accès.

>>> import urllib2
>>> class HeadRequest(urllib2.Request):
...     def get_method(self):
...         return "HEAD"
... 
>>> response = urllib2.urlopen(HeadRequest("http://google.com/index.html"))

Les en-têtes sont disponibles via response.info () comme auparavant. Fait intéressant, vous pouvez trouver l'URL vers laquelle vous avez été redirigé:

>>> print response.geturl()
http://www.google.com.au/index.html
107
doshea

Obligatoire Requests façon:

import requests

resp = requests.head("http://www.google.com")
print resp.status_code, resp.text, resp.headers
61
K Z

Je pense que la bibliothèque Requests doit également être mentionnée.

36
daliusd

Juste:

import urllib2
request = urllib2.Request('http://localhost:8080')
request.get_method = lambda : 'HEAD'

response = urllib2.urlopen(request)
response.info().gettype()

Edit: Je viens de réaliser qu'il y a httplib2: D

import httplib2
h = httplib2.Http()
resp = h.request("http://www.google.com", 'HEAD')
assert resp[0]['status'] == 200
assert resp[0]['content-type'] == 'text/html'
...

texte du lien

16
Paweł Prażak

Pour être complet, avoir une réponse Python3 équivalente à la réponse acceptée en utilisant httplib.

C'est fondamentalement le même code juste que la bibliothèque ne s'appelle plus httplib mais http.client

from http.client import HTTPConnection

conn = HTTPConnection('www.google.com')
conn.request('HEAD', '/index.html')
res = conn.getresponse()

print(res.status, res.reason)
8
Octavian Damiean
import httplib
import urlparse

def unshorten_url(url):
    parsed = urlparse.urlparse(url)
    h = httplib.HTTPConnection(parsed.netloc)
    h.request('HEAD', parsed.path)
    response = h.getresponse()
    if response.status/100 == 3 and response.getheader('Location'):
        return response.getheader('Location')
    else:
        return url
2
Pranay Agarwal

J'ai trouvé que httplib est légèrement plus rapide que urllib2. J'ai chronométré deux programmes - l'un utilisant httplib et l'autre utilisant urllib2 - envoyant HEAD requêtes à 10 000 URL. Le httplib était plus rapide de plusieurs minutes. httplib total les statistiques étaient: réel 6m21.334s utilisateur 0m2.124s sys 0m16.372s

Et rllib2 les statistiques totales de étaient: réel 9m1.380s utilisateur 0m16.666s sys 0m28.565s

Quelqu'un d'autre a-t-il son mot à dire à ce sujet?

1
IgorGanapolsky

En passant, lors de l'utilisation de httplib (au moins sur 2.5.2), essayer de lire la réponse d'une demande HEAD bloquera (sur readline) et échouera par la suite. Si vous ne lancez pas lire la réponse, vous ne pouvez pas envoyer une autre demande sur la connexion, vous devrez en ouvrir une nouvelle ou accepter un long délai entre les demandes.

1
Nope

Et encore une autre approche (similaire à la réponse de Pawel):

import urllib2
import types

request = urllib2.Request('http://localhost:8080')
request.get_method = types.MethodType(lambda self: 'HEAD', request, request.__class__)

Juste pour éviter d'avoir des méthodes illimitées au niveau de l'instance.

0
estani