97

By using python, how can I check if a website is up? From what I read, I need to check the "HTTP HEAD" and see status code "200 OK", but how to do so ?

Cheers

Related

1

16 Answers 16

144

You could try to do this with getcode() from urllib

import urllib.request

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

For Python 2, use

print urllib.urlopen("http://www.stackoverflow.com").getcode()
200
Sign up to request clarification or add additional context in comments.

9 Comments

Following question, using urlopen.getcode does fetch the entire page or not?
As far as i know, getcode retreives the status from the response that is sent back
@Oscar, there's nothing in urllib to indicate it uses HEAD instead of GET, but the duplicate question referenced by Daniel above shows how to do the former.
it seems there is no method urlopen in python 3.x any more. all i keep getting is ImportError: cannot import name 'urlopen' how can i work around this?
@l1zard like so: req = urllib.request.Request(url, headers = headers) resp = urllib.request.urlopen(req)
|
37

I think the easiest way to do it is by using Requests module.

import requests

def url_ok(url):
    r = requests.head(url)
    return r.status_code == 200

6 Comments

this does not work here for url = "http://foo.example.org/" I would expect 404, but get a crash.
This returns False for any other response code than 200 (OK). So you wouldn't know if it's a 404. It only checks if the site is up and available for public.
@caisah, did you test it? Jonas is right; I get an exception; raise ConnectionError(e) requests.exceptions.ConnectionError: HTTPConnectionPool(host='nosuch.org2', port=80): Max retries exceeded with url: / (Caused by <class 'socket.gaierror'>: [Errno 8] nodename nor servname provided, or not known)
I've test it before posting it. The thing is, that this checks if a site is up and doesn't handle the situtation when host name is invalid or other thing that go wrong. You should think of those exceptions and catch them.
In my view, this does not test if a website is up, as it crashes (as the commenters before have said). This is my try at a short, pythonic implementation: stackoverflow.com/a/57999194/5712053
|
11

You can use httplib

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

prints

200 OK

Of course, only if www.python.org is up.

1 Comment

This only checks domains, need something efficient like this for webpages.
10
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')

Works on Python 3

Comments

8
import httplib
import socket
import re

def is_website_online(host):
    """ This function checks to see if a host name has a DNS entry by checking
        for socket info. If the website gets something in return, 
        we know it's available to DNS.
    """
    try:
        socket.gethostbyname(host)
    except socket.gaierror:
        return False
    else:
        return True


def is_page_available(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
        False.
    """
    try:
        conn = httplib.HTTPConnection(host)
        conn.request("HEAD", path)
        if re.match("^[23]\d\d$", str(conn.getresponse().status)):
            return True
    except StandardError:
        return None

1 Comment

is_website_online just tells you if a host name has a DNS entry, not whether a website is online.
8

I use requests for this, then it is easy and clean. Instead of print function you can define and call new function (notify via email etc.). Try-except block is essential, because if host is unreachable then it will rise a lot of exceptions so you need to catch them all.

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}")

Comments

5

You may use requests library to find if website is up i.e. status code as 200

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

>> 200

Comments

4

The HTTPConnection object from the httplib module in the standard library will probably do the trick for you. BTW, if you start doing anything advanced with HTTP in Python, be sure to check out httplib2; it's a great library.

Comments

4

If server if down, on python 2.7 x86 windows urllib have no timeout and program go to dead lock. So use 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     

Comments

3

In my opinion, caisah's answer misses an important part of your question, namely dealing with the server being offline.

Still, using requests is my favorite option, albeit as such:

import requests

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

Comments

1

If by up, you simply mean "the server is serving", then you could use cURL, and if you get a response than it's up.

I can't give you specific advice because I'm not a python programmer, however here is a link to pycurl http://pycurl.sourceforge.net/.

Comments

1

Hi this class can do speed and up test for your web page with this class:

 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)

Comments

1

Requests and httplib2 are great options:

# 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

If using Ansible, you can use the fetch_url function:

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

Comments

1

my 2 cents

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

if getResponseCode(url) != 200:
    print('Wrong URL')
else:
    print('Good URL')

Comments

0

Here's my solution using PycURL and validators

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

Comments

0

sometimes some sites are forbidden in some countries (like Iran) and you can't access them directly with your ip. So I found better solution in this link that checks your domain with https://www.isitdownrightnow.com that requests your domain with several distributed servers in the world. So you can use this code:

import re
import requests

domain = 'your domain ex:a.com'
print(f"checking '{domain}' is up?")
isitdown_url = f'https://www.isitdownrightnow.com/check.php?domain={domain}'
r = requests.get(isitdown_url)
r_text = (r.text.lower().replace('</div>', ' '))
status = (re.compile(f'{domain} is (.*) (?:it is not|and reachable)').search(r_text).group(1).split(' ')[0])
if status == 'down':
    raise ValueError(f"'{domain}' is down in all the world!please request later!")

2 Comments

I am wondering, is there any reason to hit the isitdownrightnow.com service instead of the actual website you are trying to check?
Yes my bro. for ex: I am using Caltech electro vehicle API to use it's charging station sessions dataset in my thesis and it has about 20Gigabytes data in separated files about 1257 files but on downloading dataset ev.caltech.edu became down and I didn't now why my program fault. Some sites are banned some nations from their sites like Iranians. So sometimes we need Vpn to test but this sites has distributed servers in world countries that not need to Vpn.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.