'Test if an internet connection is present in python

I have the following code that checks if an internet connection is present.

import urllib2

def internet_on():
    try:
        response=urllib2.urlopen('http://74.125.228.100',timeout=20)
        return True
    except urllib2.URLError as err: pass
    return False

This will test for an internet connection, but how effective is it?

I know internet varies in quality from person to person, so I'm looking for something that is most effective for the broad spectrum, and the above code seems like there might be loopholes where people could find bugs. For instance if someone just had a really slow connection, and took longer than 20 seconds to respond.



Solution 1:[1]

My approach would be something like this:

import socket
REMOTE_SERVER = "one.one.one.one"
def is_connected(hostname):
  try:
    # see if we can resolve the host name -- tells us if there is
    # a DNS listening
    host = socket.gethostbyname(hostname)
    # connect to the host -- tells us if the host is actually reachable
    s = socket.create_connection((host, 80), 2)
    s.close()
    return True
  except Exception:
     pass # we ignore any errors, returning False
  return False
%timeit is_connected(REMOTE_SERVER)
> 31.9 ms ± 627 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

This will return within less than a second if there is no connection (Linux, Python 3.8).

Note: This test can return false positives -- e.g. the DNS lookup may return a server within the local network. To be really sure you are connected to the internet, and talking to a valid host, be sure to use more sophisticated methods (e.g. SSL).

Solution 2:[2]

As of Python 2.6 and newer (including Python 3), a more straightforward solution which is also compatible with IPv6 would be

import socket


def is_connected():
    try:
        # connect to the host -- tells us if the host is actually
        # reachable
        socket.create_connection(("1.1.1.1", 53))
        return True
    except OSError:
        pass
    return False

It resolves the name and tries to connect to each return addres before concluding it is offline. This also includes IPv6 addresses.

Solution 3:[3]

Efficient way to check internet availability (modified @andrebrait's answer).

import socket

def isConnected():
    try:
        # connect to the host -- tells us if the host is actually
        # reachable
        sock = socket.create_connection(("www.google.com", 80))
        if sock is not None:
            print('Clossing socket')
            sock.close
        return True
    except OSError:
        pass
    return False

Solution 4:[4]

I have been using this for a while now, works fine

import requests 
while True:
    try:
        requests.get('https://www.google.com/').status_code
        break
    except:
        time.sleep(5)
        pass

Solution 5:[5]

Here's a script that I use on Windows to continuously monitors the connectivity. Prints in green/red and also reduces wait time when there is loss of connectivity.

from datetime import datetime
import time, os, requests
from termcolor import colored

os.system('color')
url = 'https://www.google.com/'
timeout = 2
sleep_time = 10
op = None

while True:
    now = datetime.now()
    try:
        op = requests.get(url, timeout=timeout).status_code
        if op == 200:
            print(now, colored("Connected", "green"))
            sleep_time = 10
        else:
            print(now, colored("Status Code is not 200", "red"))
            print("status Code", op)
    except:
        print(now, colored("Not Connected", "red"))
        print("status Code", op)
        sleep_time = 5
    time.sleep(sleep_time)

Solution 6:[6]

this will work

import urllib
try :
    stri = "https://www.google.co.in"
    data = urllib.urlopen(stri)
    print "Connected"
except e:
    print "not connected" ,e 

Solution 7:[7]

To complement miraculixx's answer ; Many situations can happen

  1. The user has no network adapter or no connection to a network. This can be detected with DNS resolution failing (socket.gethostbyname)

  2. The user is connected to a local network with direct internet access (no DNS proxy, no TCP/HTTP proxy). In that case the DNS resolution failing (socket.gethostbyname) will also indicate loss of connection to internet

  3. The user is connected to a local network where a DNS proxy is present but no TCP/HTTP(s) proxy is needed to access the internet. In that case DNS resolution success is not enough to indicate connection to the internet, an HTTP query (or at least opening a TCP session on the HTTP(s) port) is needed: socket.create_connection

  4. The user is connected to a local network where a TCP/HTTP(s) proxy is needed to access the internet. In that case socket.create_connection will fail as the TCP socket needs to point to the proxy, not to the end host. You can get the current proxy configuration using urllib.getproxies (python 2) or urllib.request.getproxies (python 3). So after identifying the proxy info using urllib.parse.urlparse you can use urllib of - much easier - requests to establish an HTTP GET to some known url.

However, this last method can fail (indicate no connection while there is actually one) if the user has not configured the proxy in the OS environment variables used by urllib or requests and rather configures his tools one by one (for example conda using the .condarc proxy_servers section). In that case there is no magic way to detect if the failure comes from a wrong proxy configuration or a loss of internet connection - except inspecting the proxy configuration files for the tool you wish to actually work for.

So as a conclusion,

  • a dns resolution failure is a reliable way to detect "has no internet access"
  • If you are sure that the user is not sitting behind a proxy (for example mobile apps), a failed/successful TCP session is a good way to detect "hasn't/has internet access)
  • Otherwise, a successful HTTP GET using requests is a good way to detect "has internet access" but failure is not sufficient to indicate anything.

See also this page for proxy-related configuration tricks.

Solution 8:[8]

Http seems a too high level for checking network availability.

Nevertheless you can create a thread that check periodically the connectivity and store the connectivity state, next the internet_on method could just check the stored state. This will should be quicker than testing connectivity each time.

Solution 9:[9]

Though the answer has been ticked, it couldn't help me, I had getting an error like

urllib2 is undefined

so I had tried to install urllib2 library using pip but was helpless then I dig up around and luckily I got a solution please check following code, sharing because someone who will face problem that I had before, will get the solution

from urllib.request import urlopen

def is_internet_available():
    try:
        urlopen('http://216.58.192.142', timeout=1)
        return True
    except:
        return False


print(is_internet_available())

Solution 10:[10]

Whether internet is connected or not can be indirectly known by fetching the present date from NTP server .

import ntplib
import datetime, time
    

try:

    client = ntplib.NTPClient()
    response = client.request('pool.ntp.org')
    Internet_date_and_time = datetime.datetime.fromtimestamp(response.tx_time)  
    print('\n')
    print('Internet date and time as reported by server: ',Internet_date_and_time)


except OSError:

    print('\n')
    print('Internet date and time could not be reported by server.')
    print('There is not internet connection.')
    

Solution 11:[11]

We can test internet connectivity within one line but, this method is inadvisable to use every time. Use this answer to learn about one line coding in python ;)

print((lambda a: 'Internet connected and working' if 0 == a.system('ping google.com -w 4 > clear') else 'Internet not connected.')(__import__('os')))

In the above code, the __import__ function will import the module in one line.

In the normal way:

import os
def check_internet():
    cmd = os.system('ping google.com -w 4 > clear')
    if cmd == 0:
        print('Internet is connected')
    else:
        print('Internet is not connected')

if __name__ == '__main__':
    check_internet()

Posting this question with the ?? of one line coding in python

Solution 12:[12]

I wanted to test my internet connection in an infinite loop to monitor when my network goes up and down. I noticed the following: when my network was down and I started the monitoring script like that and the network came back, the script didn't notice it. The network was alive but the script didn't see that. When my network was on and I started the script like that, it noticed the changes. So I came up with the following solution that worked for me in both cases:

import shlex
from subprocess import call, PIPE, STDOUT

def get_return_code_of_simple_cmd(cmd, stderr=STDOUT):
    """Execute a simple external command and return its exit status."""
    args = shlex.split(cmd)
    return call(args, stdout=PIPE, stderr=stderr)

def is_network_alive():
    cmd = "ping -c 1 www.google.com"
    return get_return_code_of_simple_cmd(cmd) == 0

Here we rely on an external program (ping) that is independent from our script.

Solution 13:[13]

I hope ,I can help problem with you.

import urllib
try :
    url = "https://www.google.com"
    urllib.urlopen(url)
    status = "Connected"
except :
    status = "Not connect"
print status

Solution 14:[14]

I don't need the post on every time check...So I use to notify when device goes from online to offline and vice versa.

import socket
import time

mem1 = 0
while True:
    try:
        host = socket.gethostbyname(
            "www.google.com"
        )  # Change to personal choice of site
        s = socket.create_connection((host, 80), 2)
        s.close()
        mem2 = 1
        if mem2 == mem1:
            pass  # Add commands to be executed on every check
        else:
            mem1 = mem2
            print("Internet is working")  # Will be executed on state change

    except Exception as e:
        mem2 = 0
        if mem2 == mem1:
            pass
        else:
            mem1 = mem2
            print("Internet is down")
    time.sleep(10)  # timeInterval for checking

Solution 15:[15]

Here is my code, it's working fine.

 import requests
 try:
    requests.get('https://www.google.com/').status_code
    print("Connected")
 except:
    print("Not Connected")
    exit()

Solution 16:[16]

Use google to check connection since its the fastest website in the world and also work with slow networks as well

import urllib.request
    def connect():
        host='http://google.com'
        try:
            urllib.request.urlopen(host) #Python 3.x
            return True
        except:
            return False

it returns boolean True means Connection is Available and returns False means there is no Internet Connection

Solution 17:[17]

check internet using Python Request

import urllib
from urllib.request import urlopen


def is_internet():
    """
    Query internet using python
    :return:
    """
try:
    urlopen('https://www.google.com', timeout=1)
    return True
except urllib.error.URLError as Error:
    print(Error)
    return False


if is_internet():
    print("Internet is active")
else:
    print("Internet disconnected")

Solution 18:[18]

This is how we do it in our production:

import socket, sys

def ValidateConnection(host: str):
    try:
        DnsLookup: tuple = socket.gethostbyname_ex(host.strip())
        if DnsLookup[-1]:
            ipaddress: str = DnsLookup[-1][0]
            with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
                sock.settimeout(1.0)
                result: int = sock.connect_ex((ipaddress,53))
                if result == 0:
                    return(True)
    except Exception as e:
        if "[Errno 11001] getaddrinfo failed" in str(e):
            print("Unable to lookup host: "+host)
        else:
            print("Unexpected error: "+str(e), sys.exc_info()[0])
    return(False)

Results:

print(ValidateConnection("this.does.not.exist"))
Unable to lookup host: this.does.not.exist
False

print(ValidateConnection("one.one.one.one"))
True

Python 3.9.9

Solution 19:[19]

I have another solution. We have cmd command for checking connection: For example "netsh wlan show interface " this command in cmd gives us connection in and out speed. So you can use that in python:

from subprocess import check_output

output=check_output(['netsh','wlan','show','interface'])

output=str(output) #to convert byte to string

and then you can see the state of internet in the line started as Result:

... \r\n State : connected\r\n

then we can split it by '\r\n' character to extract the information we need or we can use Regular expression.

Solution 20:[20]

This is what I use:

import subprocess

subprocess.call('ping -t 8.8.8.8')

Solution 21:[21]

import socket
IPaddress=socket.gethostbyname(socket.gethostname())
if IPaddress=="127.0.0.1":
    print("No internet, your localhost is "+ IPaddress)
else:
    print("Connected, with the IP address: "+ IPaddress )