测试python中是否存在互联网连接

时间:2014-01-03 21:57:16

标签: python python-2.7 networking

我有以下代码检查是否存在互联网连接。

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

这将测试互联网连接,但效果如何?

我知道互联网的质量因人而异,所以我正在寻找对广谱来说最有效的东西,上面的代码似乎可能存在漏洞,人们可能会发现漏洞。例如,如果某人的连接速度非常慢,并且响应时间超过20秒。

19 个答案:

答案 0 :(得分:42)

我的方法是这样的:

import socket
REMOTE_SERVER = "www.google.com"
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)
    return True
  except:
     pass
  return False
%timeit is_connected(REMOTE_SERVER)
> 10 loops, best of 3: 42.2 ms per loop

如果没有连接(OSX,Python 2.7),这将在不到一秒的时间内返回。

注意:此测试可以返回误报 - 例如DNS查找可以返回本地网络中的服务器。要确定您已连接到互联网,并与有效的主机交谈,请务必使用更复杂的方法(例如SSL)。

答案 1 :(得分:14)

从Python 2.6及更新版本(包括Python 3)开始,一个更简单的解决方案也与IPv6兼容

import socket


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

它解析名称并尝试连接到每个返回地址,然后结束它离线。这还包括IPv6地址。

答案 2 :(得分:4)

一种检查互联网可用性的有效方法(修改了@andrebrait的答案)。

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

答案 3 :(得分:2)

这将起作用

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

答案 4 :(得分:2)

我已经使用了一段时间了, 效果很好

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

答案 5 :(得分:1)

我想在无限循环中测试我的互联网连接,以监控我的网络何时上下移动。我注意到以下情况:当我的网络关闭时,我启动了监控脚本,并且网络又回来了,脚本没有注意到它。网络还活着,但脚本没有看到。当我的网络开启并且我开始这样的脚本时,它注意到了这些变化。所以我提出了以下解决方案,在两种情况下都适用于我:

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

这里我们依赖于独立于我们脚本的外部程序(ping)。

答案 6 :(得分:1)

这是我在 Windows 上使用的一个脚本,用于持续监控连接。以绿色/红色打印,还可以减少连接中断时的等待时间。

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)

答案 7 :(得分:0)

我不需要在每次检查时都发帖...因此,我通常用来通知设备何时从在线状态变为离线状态,反之亦然。

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

答案 8 :(得分:0)

我们可以在一条线路内测试互联网连接,但这种方法不建议每次都使用。使用此答案了解 Python 中的一行编码;)

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

在上面的代码中,__import__ 函数将在一行中导入模块。

以正常方式:

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

用python中一行编码的❤️发布这个问题

答案 9 :(得分:0)

通过从 NTP 服务器获取当前日期可以间接知道互联网是否已连接。

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

答案 10 :(得分:0)

使用谷歌检查连接,因为它是世界上最快的网站,并且也可以处理慢速网络

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

它返回布尔值 True 表示连接可用 并返回 False 表示没有 Internet 连接

答案 11 :(得分:0)

补充miraculixx's answer;可能会发生很多情况

  1. 用户没有网络适配器,也没有网络连接。可以通过DNS解析失败(socket.gethostbyname)来检测到这一点

  2. 用户已连接到具有直接Internet访问权限的本地网络(无DNS代理,无TCP / HTTP代理)。在这种情况下,DNS解析失败(socket.gethostbyname)也将表明失去与互联网的连接

  3. 用户已连接到存在DNS代理但无需TCP / HTTP代理访问互联网的本地网络。在那种情况下,DNS解析成功不足以表明已连接到Internet,因此需要HTTP查询(或至少在HTTP(s)端口上打开TCP会话):socket.create_connection

  4. 用户已连接到需要TCP / HTTP代理访问互联网的本地网络。在这种情况下,socket.create_connection失败,因为TCP套接字需要指向代理而不是最终主机。您可以使用urllib.getproxies(python 2)或urllib.request.getproxies(python 3)获取当前的代理配置。因此,在使用urllib.parse.urlparse识别代理信息之后,您可以使用urllib的{​​{1}}-更容易-requests建立到某个已知URL的HTTP GET。

但是,如果用户尚未在urllibrequests所使用的OS环境变量中配置代理,而是配置了他的最后一个方法,则该最后一种方法可能会失败(表示实际上是没有连接)。一对一的工具(例如使用conda .condarc部分的proxy_servers)。在那种情况下,除了检查代理配置文件中您想要实际使用的工具之外,没有任何神奇的方法来检测失败是由于错误的代理配置还是由于互联网连接丢失。

因此,结论

  • dns解析失败是检测“没有互联网访问权限”的可靠方法
  • 如果您确定,该用户没有坐在代理后面(例如,移动应用),则TCP会话失败/成功是检测“是否/无法访问互联网”的好方法)
  • 否则,使用requests成功进行HTTP GET是检测“是否可以访问互联网”的好方法,但是失败不足以表明任何内容

有关代理相关的配置技巧,另请参见this page

答案 12 :(得分:0)

这是我的代码,工作正常。

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

答案 13 :(得分:0)

尽管答案已经打勾,但仍无济于事,我遇到了类似

的错误
  

urllib2未定义

所以我曾尝试使用pip安装 urllib2 库,但很无奈,于是我进行了深入研究,幸运的是得到了一个解决方案 请检查以下代码,进行共享,因为遇到我之前遇到的问题的人会得到解决方案

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

答案 14 :(得分:0)

我希望,我可以帮你解决问题。

[TestMethod]
public void FluentAssertions_Should_Validate_Collections() {
    //Arrange
    var id1 = Guid.NewGuid();
    var id2 = Guid.NewGuid();

    var list = new List<Contract>{
        new Contract() { Id = id1, Name = "A" },
        new Contract() { Id = Guid.NewGuid(), Name = "B"}
    };

    var factoryMock = new Mock<IContractFactory>();
    factoryMock.Setup(m => m.BuildContracts()).Returns(list);
    var factory = factoryMock.Object;

    //Act
    var contracts = factory.BuildContracts();

    //Assert
    contracts.Should()
        .HaveCount(list.Count)
        .And.Contain(c => c.Id == id1 && c.Name == "A")
        .And.NotContain(c => c.Id == id2 && c.Name == "B");
}

答案 15 :(得分:0)

Http似乎对于检查网络可用性来说太高了。

尽管如此,您可以创建一个定期检查连接并存储连接状态的线程,然后internet_on方法可以检查存储状态。这应该比每次测试连接更快。

答案 16 :(得分:-1)

{{1}}

答案 17 :(得分:-1)

这就是我使用的:

import subprocess

subprocess.call('ping -t 8.8.8.8')

答案 18 :(得分:-2)

将超时时间增加到30秒?多次尝试?尝试少数主机?