2009-07-16 3 views

ответ

22

Вы должны использовать 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 будет следовать перенаправлениям, поэтому вы не получите никаких 3хх ответов. – sorin

+1

@sorin: Это зависит - вы вполне можете ** хотеть ** следовать переадресации. Возможно, вы хотите задать вопрос: «Если бы я посетил этот URL-адрес с браузером, показывал бы контент или выдавал бы ошибку?» В этом случае, если бы я изменил 'http: // entrian.com /' на 'http: // entrian.com/blog' в моем примере, результат 200 был бы правильным, хотя он включал перенаправление на' http:// entrian.com/blog/'(обратите внимание на конечную косую черту). – RichieHindle

63

Вот решение, которое использует 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 
+13

+1 для запроса HEAD - нет необходимости извлекать весь объект для проверки состояния. –

+7

Хотя вы действительно должны ограничить этот блок 'except' по крайней мере до' StandardError', чтобы вы не ошибочно перехватывали такие вещи, как 'KeyboardInterrupt'. –

+0

Хорошая идея, Бен. Я обновил его соответствующим образом. –

3

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

+2

Это для меня, используя Python 2.6. – RichieHindle

5

В будущем для тех, кто использует python3 и позже, вот еще один код, чтобы найти код ответа.

import urllib.request 

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

Это вызовет HTTPError для кодов статуса, таких как 404, 500 и т. Д. –

63

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

import requests 
try: 
    r = requests.head("http://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") 
+0

запросов намного лучше, чем urllib2, для такой ссылки: http://www.dianping.com/promo/208721#mod=4, urllib2 дать мне 404 и запросы дают 200, как то, что я получаю от браузера. – WKPlus

+5

httpstatusrappers.com ... awesome !! Мой код на том, что Lil Jon статус, сын! – tmthyjames

+1

Это лучшее решение. Гораздо лучше, чем любой другой. – Awn

1

Вот 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. Он использует метод HEAD HTTP. –

Смежные вопросы