Python 2에서 HEAD HTTP 요청을 어떻게 보내나요?


114

여기서 내가하려는 것은 주어진 URL의 헤더를 가져 와서 MIME 유형을 결정할 수 있도록하는 것입니다. http://somedomain/foo/예를 들어 HTML 문서 또는 JPEG 이미지를 반환 하는지 확인하고 싶습니다 . 따라서 콘텐츠를 다운로드하지 않고도 MIME 유형을 읽을 수 있도록 HEAD 요청을 보내는 방법을 알아 내야합니다. 누구든지 이것을하는 쉬운 방법을 알고 있습니까?

답변:


104

편집 :이 답변은 작동하지만 요즘에는 아래 다른 답변에서 언급 한 것처럼 요청 라이브러리를 사용해야합니다 .


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

getheader(name)특정 헤더를 가져 오는 것도 있습니다 .


2
이 응답은 응답으로 표시되었지만 요청 lib를 살펴 봐야 합니다 . 조금 아래에있는 달리 우스의 반응을보십시오.
Bahadir Cambel 2011

이것은 정말 훌륭하지만 요청의 호스트와 경로에 대해 별도의 값이 있어야합니다. urlparse낮은 순위의 응답으로 표시되는 손에있는 것이 유용합니다 .
Tomasz Gandor 2013 년

7
Python 3에 대한 참고 사항; httplib로 이름이 변경되었습니다 http.client.
Santosh Kumar

2
불행히도 requests기본적으로 Python과 함께 제공되지 않습니다.
rook

@rook하지 둘 : 당신의 프로그램입니다
Eevee

109

urllib2 는 HEAD 요청을 수행하는 데 사용할 수 있습니다. urllib2는 URL을 호스트 이름과 경로로 분할하는 대신 URL을 구문 분석하므로 httplib를 사용하는 것보다 조금 더 좋습니다.

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

헤더는 이전과 같이 response.info ()를 통해 사용할 수 있습니다. 흥미롭게도 리디렉션 된 URL을 찾을 수 있습니다.

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

1
response.info () .__ str __ ()은 얻은 결과로 무언가를 수행하려는 경우 헤더의 문자열 형식을 반환합니다.
Shane

6
리디렉션이 있다면 파이썬 2.7.1와 함께이 시도하는 (우분투 단정), 그것은 대상이 아닌 HEAD ...에 GET 않는다는 점을 제외
eichin

1
이것이 httplib.HTTPConnection자동으로 리디렉션을 처리하지 않는 의 장점입니다 .
Ehtesh Choudhury 2011 년

그러나 doshea의 대답으로. 시간 제한을 설정하는 방법? 더 이상 살아 있지 않은 URL과 같은 잘못된 URL을 처리하는 방법.
fanchyna

65

의무적 인 Requests방법 :

import requests

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

36

Requests 라이브러리도 언급되어야 한다고 생각합니다 .


5
이 답변은 더 많은 관심을 기울일 가치가 있습니다. 문제를 사소하게 만드는 꽤 좋은 라이브러리처럼 보입니다.
Nick Retallack 2011 년

3
동의합니다. 요청하는 것은 매우 간단합니다. {code} import requests r = requests.head ( ' github.com' ) {code}
Luis R.

@LuisR .: 리디렉션이 있으면 GET / POST / PUT / DELETE도 따릅니다.
jfs

@Nick Retallack : 리디렉션을 비활성화하는 쉬운 방법은 없습니다. allow_redirectsPOST / PUT / DELETE 리디렉션 만 비활성화 할 수 있습니다. 예 : head request no redirect
jfs

@JFSebastian 예제에 대한 링크가 끊어진 것 같습니다. 다음 리디렉션과 관련된 문제에 대해 자세히 설명해 주시겠습니까?
Piotr Dobrogost

17

다만:

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

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

편집 : 나는 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'
...

링크 텍스트


get_method를 바인딩하지 않고 바인딩되지 않은 함수로 남겨두고 있다는 점에서 약간 불쾌합니다 request. (당신이 사용하고자하는 경우 즉, 그것은 작동합니다하지만 나쁜 스타일이고 self그 안에 -. 힘든)
크리스 모건에게

4
이 솔루션의 장단점에 대해 좀 더 자세히 설명해 주시겠습니까? 보시다시피 저는 Python 전문가가 아니므로 언제 나빠질 수 있는지 알면 도움이 될 수 있습니다.) 제가 이해하는 것처럼 fas는 구현 변경에 따라 작동하거나 작동하지 않을 수있는 해킹이라는 것입니까?
Paweł Prażak 2010

이 코드의 두 번째 버전은 403 Forbidden이있는 URL에 대해 저를 위해 일한 유일한 버전입니다. 다른 사람들은 예외를 던졌습니다.
duality_ apr

10

완전성을 위해 httplib를 사용하여 허용되는 답변과 동등한 Python3 답변을 갖습니다 .

기본적으로 라이브러리가 더 이상 httplib가 아니라 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)

2
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

전에 달러 기호는 무엇입니까 import? +1은 urlparse-와 함께 입력 측의 URL을 다룰 때 httplib편안함을 제공합니다 urllib2.
Tomasz Gandor 2013 년

1

제쳐두고, httplib를 사용할 때 (최소한 2.5.2에서) HEAD 요청의 응답을 읽으려고 시도하면 (readline에서) 차단되고 실패합니다. 응답에서 읽기를 실행하지 않으면 연결에서 다른 요청을 보낼 수 없으므로 새 요청을 열어야합니다. 또는 요청 사이에 긴 지연을 허용하십시오.


1

httplib가 urllib2보다 약간 빠르다는 것을 발견했습니다. 하나는 httplib를 사용하고 다른 하나는 urllib2를 사용하는 두 프로그램의 시간을 측정했습니다. HEAD 요청을 10,000 개의 URL로 보냅니다. httplib는 몇 분 더 빨랐습니다. httplib 의 총 통계 : 실제 6m21.334s 사용자 0m2.124s sys 0m16.372s

그리고 urllib2 의 총 통계는 다음과 같습니다 : 실제 9m1.380s 사용자 0m16.666s sys 0m28.565s

다른 사람이 이것에 대한 의견을 가지고 있습니까?


입력? 문제는 IO 바인딩이며 차단 라이브러리를 사용하고 있습니다. 더 나은 성능을 원하면 eventlet 또는 twisted로 전환하십시오. 언급 한 urllib2의 제한 사항은 CPU 제한입니다.
Devin Jeanpierre

3
urllib2는 리디렉션을 따르므로 URL 중 일부가 리디렉션되는 경우 이것이 차이의 원인 일 수 있습니다. 그리고 httplib는 더 낮은 수준이며 urllib2는 예를 들어 URL을 구문 분석합니다.
Marian

1
urllib2는 httplib 위에있는 얇은 추상화 계층 일뿐입니다. URL이 매우 빠른 LAN에 있지 않는 한 CPU에 묶여 있었다면 매우 놀랍습니다. 일부 URL이 리디렉션되었을 수 있습니까? urllib2는 리디렉션을 따르지만 httplib는 그렇지 않습니다. 다른 가능성은 네트워크 조건 (이 실험에서 명시 적으로 제어 할 수없는 모든 항목)이 두 실행 사이에 변동했기 때문입니다. 이 가능성을 줄이려면 각각 최소 3 번의 인터리브 실행을 수행해야합니다.
John La Rooy

0

그리고 또 다른 접근 방식 (Pawel 답변과 유사) :

import urllib2
import types

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

인스턴스 수준에서 제한되지 않은 메서드를 사용하지 않기 위해서입니다.


-4

아마도 더 쉬울 것입니다 : urllib 또는 urllib2를 사용하십시오.

>>> import urllib
>>> f = urllib.urlopen('http://google.com')
>>> f.info().gettype()
'text/html'

f.info ()는 사전과 같은 객체이므로 f.info () [ 'content-type'] 등을 할 수 있습니다.

http://docs.python.org/library/urllib.html
http://docs.python.org/library/urllib2.html
http://docs.python.org/library/httplib.html

문서에 따르면 httplib는 일반적으로 직접 사용되지 않습니다.


14
그러나 urllib는 GET을 수행하고 질문은 HEAD 수행에 관한 것입니다. 포스터가 값 비싼 문서를 검색하고 싶지 않을 수도 있습니다.
Philippe F
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.