Проверка работы веб-сайта через Python

Как я могу проверить, работает ли веб-сайт с помощью Python? Из того, что я прочитал, мне нужно проверить HTTP HEAD и увидеть код состояния 200 OK, но как это сделать?

Ваше здоровье

Связанный


person Hellnar    schedule 22.12.2009    source источник
comment
Дубликат: stackoverflow.com/questions/107405/   -  person Daniel Roseman    schedule 23.12.2009


Ответы (15)


Вы можете попробовать сделать это с помощью getcode() из urllib

import urllib.request

print(urllib.request.urlopen("https://www.stackoverflow.com").getcode())
200

Для Python 2 используйте

print urllib.urlopen("http://www.stackoverflow.com").getcode()
200
person Anthony Forloney    schedule 22.12.2009
comment
Следующий вопрос: при использовании urlopen.getcode выполняется выборка всей страницы или нет? - person OscarRyz; 23.12.2009
comment
Насколько мне известно, getcode получает статус из ответа, который был отправлен обратно - person Anthony Forloney; 23.12.2009
comment
@Oscar, в urllib нет ничего, что указывало бы на то, что он использует HEAD вместо GET, но дублирующийся вопрос, на который ссылается Даниэль выше, показывает, как сделать первое. - person Peter Hansen; 23.12.2009
comment
похоже, что в python 3.x больше нет метода urlopen. все, что я получаю, это ImportError: невозможно импортировать имя urlopen, как я могу обойти это? - person l1zard; 16.11.2015
comment
@ l1zard вот так: req = urllib.request.Request(url, headers = headers) resp = urllib.request.urlopen(req) - person jamescampbell; 14.01.2016
comment
Для меня это фактически возвращает 403 вместо кода 200 - person David Okwii; 26.02.2016

Я думаю, что самый простой способ сделать это - использовать модуль Requests.

import requests

def url_ok(url):
    r = requests.head(url)
    return r.status_code == 200
person caisah    schedule 01.04.2013
comment
здесь это не работает для url = "http://foo.example.org/", я ожидал бы 404, но получаю сбой. - person Jonas Stein; 02.06.2013
comment
Это возвращает False для любого другого кода ответа, кроме 200 (ОК). Таким образом, вы не узнаете, 404 ли это. Он только проверяет, работает ли сайт и доступен ли он для всех. - person caisah; 04.06.2013
comment
@caisah, ты это тестировал? Йонас прав; У меня исключение; поднять ConnectionError (e) requests.exceptions.ConnectionError: HTTPConnectionPool (host = 'nosuch.org2', port = 80): Превышено максимальное количество повторных попыток с url: / (Вызвано ‹class 'socket.gaierror'›: [Errno 8] nodename ни имя сервера не указано или не известно) - person AnneTheAgile; 14.11.2013
comment
Я протестировал это перед публикацией. Дело в том, что это проверяет, работает ли сайт, и не обрабатывает ситуацию, когда имя хоста недействительно или что-то идет не так. Вам следует подумать об этих исключениях и отловить их. - person caisah; 17.11.2013
comment
На мой взгляд, это не проверяет, работает ли веб-сайт, поскольку он дает сбой (как уже говорили ранее комментаторы). Это моя попытка короткой питонической реализации: stackoverflow.com/a/57999194/5712053 - person vauhochzett; 09.06.2020

Вы можете использовать http://docs.python.org/library/httplib.html

import httplib
conn = httplib.HTTPConnection("www.python.org")
conn.request("HEAD", "/")
r1 = conn.getresponse()
print r1.status, r1.reason

отпечатки

200 OK

Конечно, только если www.python.org встал.

person OscarRyz    schedule 22.12.2009
comment
Это проверяет только домены, нужно что-то вроде этого для веб-страниц. - person User; 10.01.2014

from urllib.request import Request, urlopen
from urllib.error import URLError, HTTPError
req = Request("http://stackoverflow.com")
try:
    response = urlopen(req)
except HTTPError as e:
    print('The server couldn\'t fulfill the request.')
    print('Error code: ', e.code)
except URLError as e:
    print('We failed to reach a server.')
    print('Reason: ', e.reason)
else:
    print ('Website is working fine')

Работает на Python 3

person Christopher Punton    schedule 01.07.2016

Вероятно, подойдет объект HTTPConnection из модуля httplib в стандартной библиотеке уловка для вас. Кстати, если вы начнете делать что-то продвинутое с HTTP в Python, обязательно ознакомьтесь с httplib2 ; это отличная библиотека.

person Hank Gay    schedule 22.12.2009

Если сервер не работает, на python 2.7 x86 windows urllib не имеет тайм-аута, и программа переходит в мертвую блокировку. Так что используйте urllib2

import urllib2
import socket

def check_url( url, timeout=5 ):
    try:
        return urllib2.urlopen(url,timeout=timeout).getcode() == 200
    except urllib2.URLError as e:
        return False
    except socket.timeout as e:
        print False


print check_url("http://google.fr")  #True 
print check_url("http://notexist.kc") #False     
person themadmax    schedule 06.10.2017

Вы можете использовать requests библиотеку, чтобы узнать, работает ли веб-сайт, т.е. status code как 200

import requests
url = "https://www.google.com"
page = requests.get(url)
print (page.status_code) 

>> 200
person Harry_pb    schedule 12.08.2018

Если под словом «вверх» вы просто имеете в виду «сервер обслуживает», тогда вы можете использовать cURL, и если вы получите ответ, то он работает.

Я не могу дать вам конкретный совет, потому что я не программист на Python, но вот ссылка на pycurl http://pycurl.sourceforge.net/.

person Tyler Smith    schedule 22.12.2009

Привет, этот класс может выполнить тест на скорость и скорость вашей веб-страницы с помощью этого класса:

 from urllib.request import urlopen
 from socket import socket
 import time


 def tcp_test(server_info):
     cpos = server_info.find(':')
     try:
         sock = socket()
         sock.connect((server_info[:cpos], int(server_info[cpos+1:])))
         sock.close
         return True
     except Exception as e:
         return False


 def http_test(server_info):
     try:
         # TODO : we can use this data after to find sub urls up or down    results
         startTime = time.time()
         data = urlopen(server_info).read()
         endTime = time.time()
         speed = endTime - startTime
         return {'status' : 'up', 'speed' : str(speed)}
     except Exception as e:
         return {'status' : 'down', 'speed' : str(-1)}


 def server_test(test_type, server_info):
     if test_type.lower() == 'tcp':
         return tcp_test(server_info)
     elif test_type.lower() == 'http':
         return http_test(server_info)
person Manouchehr Rasouli    schedule 21.08.2017

На мой взгляд, ответ caisah упускает из виду важную часть вашего вопроса, а именно работу с сервером, находящимся в автономном режиме.

Тем не менее, использование requests - мой любимый вариант, хотя и как таковой:

import requests

try:
    requests.get(url)
except requests.exceptions.ConnectionError:
    print(f"URL {url} not reachable")
person vauhochzett    schedule 18.09.2019

мои 2 цента

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

if getResponseCode(url) != 200:
    print('Wrong URL')
else:
    print('Good URL')
person EVE Milano    schedule 19.11.2019

Я использую для этого запросы, тогда это просто и понятно. Вместо функции print вы можете определить и вызвать новую функцию (уведомление по электронной почте и т. Д.). Блокировка Try-except очень важна, потому что, если хост недоступен, возникает множество исключений, поэтому вам нужно перехватить их все.

import requests

URL = "https://api.github.com"

try:
    response = requests.head(URL)
except Exception as e:
    print(f"NOT OK: {str(e)}")
else:
    if response.status_code == 200:
        print("OK")
    else:
        print(f"NOT OK: HTTP response code {response.status_code}")
person mkonstanty    schedule 08.01.2021

Вот мое решение с использованием PycURL и валидаторы

import pycurl, validators


def url_exists(url):
    """
    Check if the given URL really exists
    :param url: str
    :return: bool
    """
    if validators.url(url):
        c = pycurl.Curl()
        c.setopt(pycurl.NOBODY, True)
        c.setopt(pycurl.FOLLOWLOCATION, False)
        c.setopt(pycurl.CONNECTTIMEOUT, 10)
        c.setopt(pycurl.TIMEOUT, 10)
        c.setopt(pycurl.COOKIEFILE, '')
        c.setopt(pycurl.URL, url)
        try:
            c.perform()
            response_code = c.getinfo(pycurl.RESPONSE_CODE)
            c.close()
            return True if response_code < 400 else False
        except pycurl.error as err:
            errno, errstr = err
            raise OSError('An error occurred: {}'.format(errstr))
    else:
        raise ValueError('"{}" is not a valid url'.format(url))
person Klemen Tusar    schedule 06.12.2016

Запросы и https://pypi.org/project/httplib2/ - отличные варианты:

# Using requests.
import requests
request = requests.get(value)
if request.status_code == 200:
    return True
return False

# Using httplib2.
import httplib2

try:
    http = httplib2.Http()
    response = http.request(value, 'HEAD')

    if int(response[0]['status']) == 200:
        return True
except:
    pass
return False

Если вы используете Ansible, вы можете использовать функцию fetch_url:

from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.urls import fetch_url

module = AnsibleModule(
    dict(),
    supports_check_mode=True)

try:
    response, info = fetch_url(module, url)
    if info['status'] == 200:
        return True

except Exception:
    pass

return False
person constrict0r    schedule 25.07.2019

person    schedule
comment
is_website_online просто сообщает вам, есть ли в имени хоста запись DNS, а не находится ли веб-сайт в сети. - person Craig McQueen; 23.12.2009