Comment envoyer une requête HTTP HEAD en Python 2?
ce que j'essaie de faire ici, c'est d'obtenir les en-têtes d'une URL donnée pour que je puisse déterminer le type MIME. Je veux voir si http://somedomain/foo/
renvoie un document HTML ou une image JPEG par exemple. Ainsi, je dois comprendre comment envoyer une demande HEAD afin que je puisse lire le type MIME sans avoir à télécharger le contenu. Quelqu'un sait-il d'un moyen facile de faire cela?
11 réponses
edit : cette réponse fonctionne, mais de nos jours, vous devez simplement utiliser la bibliothèque requests comme mentionné par d'autres réponses ci-dessous.
Utiliser 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 un getheader(name)
pour obtenir un en-tête spécifique.
urllib2 peut être utilisé pour effectuer une requête HEAD. C'est un peu plus agréable que d'utiliser httplib puisque urllib2 parse L'URL pour vous au lieu de vous demander de diviser L'URL en nom d'hôte et chemin.
>>> 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 avant. Fait intéressant, vous pouvez trouver L'URL que vous avez été redirigé vers:
>>> print response.geturl()
http://www.google.com.au/index.html
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'
...
pour être complet, avoir une réponse Python3 équivalente à la réponse acceptée en utilisant httplib .
c'est essentiellement le même code que la bibliothèque n'est plus appelée 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)
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
comme une mise à part, en utilisant le httplib (au moins sur 2.5.2), essayer de lire la réponse d'une requête en tête bloquera (sur readline) et échouera par la suite. Si vous n'avez pas de problème de lecture sur la réponse, vous ne pouvez pas envoyer une autre demande sur la connexion, vous devrez ouvrir un nouveau. Ou accepter un long délai entre les demandes.
j'ai trouvé que httplib est légèrement plus rapide que urllib2. J'ai chronométré deux programmes - l'un en utilisant httplib et l'autre en utilisant urllib2 - en envoyant des requêtes HEAD à 10 000 URL. La httplib one était plus rapide de plusieurs minutes. Les statistiques totales de httplib" 151920920 sont les suivantes:334s l'utilisateur 0m2.124s sys 0m16.372s
Et urllib2 's au total statistiques ont été: real 9m1.380 l'utilisateur 0m16.666s sys 0m28.565
Quelqu'un d'autre a son mot à dire?
Et encore une autre approche (similaire à Pawel réponse):
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.
probablement plus facile: utilisez urllib ou urllib2.
>>> import urllib
>>> f = urllib.urlopen('http://google.com')
>>> f.info().gettype()
'text/html'
f.info () est un dictionnaire-comme objet, de sorte que vous pouvez faire f.info () ['content-type'], etc.
http://docs.python.org/library/urllib.html
http://docs.python.org/library/urllib2.html
http://docs.python.org/library/httplib.html
le docs noter que httplib n'est normalement pas utilisé directement.