Как лучше всего получить код ответа HTTP с URL-адреса?

82

Я ищу быстрый способ получить код ответа HTTP с URL-адреса (например, 200, 404 и т. Д.). Я не уверен, какую библиотеку использовать.

Alexwlchan
источник

Ответы:

99

Обновление с помощью замечательной библиотеки запросов . Обратите внимание, что мы используем запрос HEAD, который должен выполняться быстрее, чем полный запрос GET или POST.

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 03
1
Это лучшее решение. Намного лучше, чем любой другой.
Awn
@WKPlus для записи, теперь requestsвыдает 403ссылку, хотя в браузере все еще работает.
Денис Голомазов
2
@Gourneau Ha! Это было не то, что я имел в виду в своем комментарии, я думаю, что это было прекрасно, и в этом контексте люди должны попытаться понять, почему он "просто работает" в браузере, но возвращает 403 в коде, когда на самом деле то же самое вещь происходит в обоих местах.
seaders 08
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
+1 для запроса HEAD - нет необходимости извлекать всю сущность для проверки статуса.
Бен Бланк,
7
Хотя вам действительно следует ограничить этот exceptблок, по крайней мере, StandardErrorчтобы вы не поймали неправильно такие вещи, как KeyboardInterrupt.
Бен Бланк,
3
Мне было интересно, надежны ли запросы HEAD. Потому что веб-сайты могут (должным образом) не реализовать метод HEAD, что может приводить к кодам состояния, например, 404, 501 или 500. Или я параноик?
Blaise
2
Как сделать так, чтобы это следовало за 301-м?
Randall Hunt
2
@Blaise Если веб-сайт не разрешает запросы HEAD, выполнение запроса HEAD должно привести к ошибке 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
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
Это вызовет ошибку HTTPError для таких кодов состояния, как 404, 500 и т. Д.
Niklas R
3

urllib2.HTTPErrorИсключение не содержит getcode()метод. codeВместо этого используйте атрибут.

Мартейн Питерс
источник
2
Для меня это работает, используя Python 2.6.
RichieHindle
2

Обращаясь к комментарию @Niklas R к ответу @ nickanor:

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
EL
источник
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
Не уверен, почему это было отвергнуто без обратной связи. Он работает с URL-адресами HTTP и HTTPS. Он использует HTTP-метод HEAD.
Sam Gleske 07