URL에서 HTTP 응답 코드를 얻는 가장 좋은 방법은 무엇입니까?


82

URL (예 : 200, 404 등)에서 HTTP 응답 코드를 얻는 빠른 방법을 찾고 있습니다. 어떤 라이브러리를 사용할지 잘 모르겠습니다.

답변:


99

멋진 요청 라이브러리를 사용하여 업데이트 합니다 . 전체 GET 또는 POST 요청보다 더 빨리 발생해야하는 HEAD 요청을 사용하고 있습니다.

import requests
try:
    r = requests.head("https://stackoverflow.com")
    print(r.status_code)
    # prints the int of the status code. Find more at httpstatusrappers.com :)
except requests.ConnectionError:
    print("failed to connect")

요청은 urllib2보다 훨씬 낫습니다. dianping.com/promo/208721#mod=4 , urllib2는 나에게 404를 제공하고 요청은 브라우저에서 얻은 것과 마찬가지로 200을 제공합니다.
WKPlus

5
httpstatusrappers.com ... 굉장합니다 !! 내 코드는 Lil Jon 상태에 있습니다.
tmthyjames

1
이것이 최상의 솔루션입니다. 다른 어떤 것보다 훨씬 낫습니다.
AWN

기록을 위해 @WKPlus 는 브라우저에서 여전히 작동하지만 이제 링크를 requests제공 403합니다.
Dennis Golomazov

2
@Gourneau 하! 그것은 내가 내 의견에서 의도 한 것이 아니었고, 완벽하게 괜찮 았다고 생각합니다. 그리고이 맥락에서 사람들은 브라우저에서 "그냥 작동"하는 이유를 이해하려고 노력해야하지만 실제로는 동일한 코드에서 403을 반환합니다. 두 곳에서 일이 일어나고 있습니다.
seaders

65

httplib대신 사용하는 솔루션이 있습니다.

import httplib

def get_status_code(host, path="/"):
    """ This function retreives the status code of a website by requesting
        HEAD data from the host. This means that it only requests the headers.
        If the host cannot be reached or something else goes wrong, it returns
        None instead.
    """
    try:
        conn = httplib.HTTPConnection(host)
        conn.request("HEAD", path)
        return conn.getresponse().status
    except StandardError:
        return None


print get_status_code("stackoverflow.com") # prints 200
print get_status_code("stackoverflow.com", "/nonexistant") # prints 404

14
HEAD 요청에 대한 +1 — 상태 확인을 위해 전체 엔티티를 검색 할 필요가 없습니다.
Ben Blank

7
당신은 정말 제한해야하지만 except적어도에 블록 StandardError잘못 같은 것들을 잡을하지 않는 것이 정도 KeyboardInterrupt.
Ben Blank

3
HEAD 요청이 신뢰할 수 있는지 궁금합니다. 웹 사이트가 HEAD 메소드를 (올바르게) 구현하지 않았기 때문에 404, 501 또는 500과 같은 상태 코드가 발생할 수 있습니다. 아니면 편집증입니까?
Blaise

2
301을 따르는 방법은 무엇입니까?
Randall Hunt

2
웹 사이트가 HEAD 요청 후 HEAD 요청을 수행 할 수없는 경우 @Blaise 해야 405 오류가 발생합니다. 이에 대한 예를 들어 curl -I http://www.amazon.com/.
Nick

24

다음과 같이 urllib2를 사용해야합니다.

import urllib2
for url in ["http://entrian.com/", "http://entrian.com/does-not-exist/"]:
    try:
        connection = urllib2.urlopen(url)
        print connection.getcode()
        connection.close()
    except urllib2.HTTPError, e:
        print e.getcode()

# Prints:
# 200 [from the try block]
# 404 [from the except block]

3
urllib2가 리디렉션을 따르므로 3xx 응답을받지 못하므로 유효한 솔루션이 아닙니다.
sorin 2013-01-31

1
@sorin : 상황에 따라 다릅니다 . 리디렉션을 따르고 싶을 수도 있습니다 . "브라우저로이 URL을 방문하면 콘텐츠가 표시되거나 오류가 발생합니까?"라는 질문을 할 수 있습니다. 내가 변경 한 경우이 경우 http://entrian.com/http://entrian.com/blog내 예제가에 대한 리디렉션을 포함하더라도, 그 결과 (200)는 올바른 것 http://entrian.com/blog/(후행 슬래시를 참고).
RichieHindle

8

앞으로 python3 이상을 사용하는 사람들을 위해 응답 코드를 찾는 또 다른 코드가 있습니다.

import urllib.request

def getResponseCode(url):
    conn = urllib.request.urlopen(url)
    return conn.getcode()

2
이렇게하면 404, 500 등과 같은 상태 코드에 대해 HTTPError가 발생합니다.
Niklas R


2

@nickanor의 답변에 대한 @Niklas R의 의견을 처리합니다.

from urllib.error import HTTPError
import urllib.request

def getResponseCode(url):
    try:
        conn = urllib.request.urlopen(url)
        return conn.getcode()
    except HTTPError as e:
        return e.code

0

다음 httplib은 urllib2처럼 동작 하는 솔루션입니다. URL 만 제공하면 작동합니다. URL을 호스트 이름과 경로로 나눌 필요가 없습니다. 이 함수는 이미 그렇게하고 있습니다.

import httplib
import socket
def get_link_status(url):
  """
    Gets the HTTP status of the url or returns an error associated with it.  Always returns a string.
  """
  https=False
  url=re.sub(r'(.*)#.*$',r'\1',url)
  url=url.split('/',3)
  if len(url) > 3:
    path='/'+url[3]
  else:
    path='/'
  if url[0] == 'http:':
    port=80
  elif url[0] == 'https:':
    port=443
    https=True
  if ':' in url[2]:
    host=url[2].split(':')[0]
    port=url[2].split(':')[1]
  else:
    host=url[2]
  try:
    headers={'User-Agent':'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:26.0) Gecko/20100101 Firefox/26.0',
             'Host':host
             }
    if https:
      conn=httplib.HTTPSConnection(host=host,port=port,timeout=10)
    else:
      conn=httplib.HTTPConnection(host=host,port=port,timeout=10)
    conn.request(method="HEAD",url=path,headers=headers)
    response=str(conn.getresponse().status)
    conn.close()
  except socket.gaierror,e:
    response="Socket Error (%d): %s" % (e[0],e[1])
  except StandardError,e:
    if hasattr(e,'getcode') and len(e.getcode()) > 0:
      response=str(e.getcode())
    if hasattr(e, 'message') and len(e.message) > 0:
      response=str(e.message)
    elif hasattr(e, 'msg') and len(e.msg) > 0:
      response=str(e.msg)
    elif type('') == type(e):
      response=e
    else:
      response="Exception occurred without a good error message.  Manually check the URL to see the status.  If it is believed this URL is 100% good then file a issue for a potential bug."
  return response

1
피드백없이 왜 이것이 반대 투표인지 확실하지 않습니다. HTTP 및 HTTPS URL에서 작동합니다. HTTP의 HEAD 메소드를 사용합니다.
샘 Gleske
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.