Python 检查网络连接

Python 检查网络连接,python,networking,Python,Networking,我想看看我是否可以访问在线API,但为此我需要访问Internet 如何使用Python查看是否存在可用且处于活动状态的连接?您可以尝试下载数据,如果连接失败,您将知道连接有问题 基本上你们不能检查电脑是否连接到互联网。失败的原因可能有很多,比如错误的DNS配置、防火墙、NAT。因此,即使您进行了一些测试,您也无法保证在尝试之前与API保持连接。也许您可以使用以下内容: import urllib2 def internet_on(): try: urllib2.url

我想看看我是否可以访问在线API,但为此我需要访问Internet


如何使用Python查看是否存在可用且处于活动状态的连接?

您可以尝试下载数据,如果连接失败,您将知道连接有问题


基本上你们不能检查电脑是否连接到互联网。失败的原因可能有很多,比如错误的DNS配置、防火墙、NAT。因此,即使您进行了一些测试,您也无法保证在尝试之前与API保持连接。

也许您可以使用以下内容:

import urllib2

def internet_on():
    try:
        urllib2.urlopen('http://216.58.192.142', timeout=1)
        return True
    except urllib2.URLError as err: 
        return False
import requests

def connected_to_internet(url='http://www.google.com/', timeout=5):
    try:
        _ = requests.head(url, timeout=timeout)
        return True
    except requests.ConnectionError:
        print("No internet connection available.")
    return False
目前,216.58.192.142是google.com的IP地址之一。更改<代码>http://216.58.192.142任何可以快速响应的站点

这个固定IP不会永远映射到google.com。所以这个代码是 不坚固——它需要不断的维护才能保持工作

上面的代码使用固定IP地址而不是完全限定域名(FQDN)的原因是FQDN需要DNS查找。当计算机没有工作的internet连接时,DNS查找本身可能会阻止对
urllib_request.urlopen
的调用超过一秒钟。感谢@rzetterberg指出这一点


如果上面的固定IP地址不起作用,您可以通过运行

% dig google.com  +trace 
...
google.com.     300 IN  A   216.58.192.142

请尝试您尝试执行的操作。如果失败,python应该抛出一个异常让您知道


首先尝试一些简单的操作来检测连接将引入竞争条件。如果在测试时internet连接有效,但在需要进行实际工作之前中断了,该怎么办?

只是为了更新unutbu在Python 3.2中对新代码所说的内容

def check_connectivity(reference):
    try:
        urllib.request.urlopen(reference, timeout=1)
        return True
    except urllib.request.URLError:
        return False

而且,需要注意的是,这里的输入(参考)是您要检查的url:我建议选择与您居住的地方快速连接的东西——例如,我住在韩国,所以我可能会将参考设置为。

作为ubutnu的/Kevin C answers的替代,我使用如下
请求
包:

import urllib2

def internet_on():
    try:
        urllib2.urlopen('http://216.58.192.142', timeout=1)
        return True
    except urllib2.URLError as err: 
        return False
import requests

def connected_to_internet(url='http://www.google.com/', timeout=5):
    try:
        _ = requests.head(url, timeout=timeout)
        return True
    except requests.ConnectionError:
        print("No internet connection available.")
    return False
奖励:这可以扩展到ping网站的功能

def web_site_online(url='http://www.google.com/', timeout=5):
    try:
        req = requests.head(url, timeout=timeout)
        # HTTP errors are not raised by default, this statement does that
        req.raise_for_status()
        return True
    except requests.HTTPError as e:
        print("Checking internet connection failed, status code {0}.".format(
        e.response.status_code))
    except requests.ConnectionError:
        print("No internet connection available.")
    return False

只发出HEAD请求会更快,因此不会提取HTML。
而且我相信谷歌会更喜欢这种方式:)

对于Python3,使用
urllib.request.urlopen(host)

作为起点,并且在过去由于“静态”IP地址更改而被烧坏,我创建了一个简单的类,该类使用DNS查找(即使用URL“”)检查一次,然后存储响应服务器的IP地址以供后续检查使用。这样,IP地址总是最新的(假设类至少每隔几年重新初始化一次)。我还感谢gawry for,它向我展示了如何获取服务器的IP地址(在任何重定向等之后)。请忽略此解决方案的明显缺陷,我这里只举一个最简单的工作示例。:)

以下是我所拥有的:

import socket

try:
    from urllib2 import urlopen, URLError
    from urlparse import urlparse
except ImportError:  # Python 3
    from urllib.parse import urlparse
    from urllib.request import urlopen, URLError

class InternetChecker(object):
    conn_url = 'https://www.google.com/'

    def __init__(self):
        pass

    def test_internet(self):
        try:
            data = urlopen(self.conn_url, timeout=5)
        except URLError:
            return False

        try:
            host = data.fp._sock.fp._sock.getpeername()
        except AttributeError:  # Python 3
            host = data.fp.raw._sock.getpeername()

        # Ensure conn_url is an IPv4 address otherwise future queries will fail
        self.conn_url = 'http://' + (host[0] if len(host) == 2 else
                                     socket.gethostbyname(urlparse(data.geturl()).hostname))

        return True

# Usage example
checker = InternetChecker()
checker.test_internet()

如果我们可以连接到某个Internet服务器,那么我们确实可以连接。但是,对于最快和最可靠的方法,所有解决方案至少应符合以下要求:

  • 避免DNS解析(我们将需要一个众所周知的IP,并保证在大部分时间内可用)
  • 避免应用层连接(连接到HTTP/FTP/IMAP服务)
  • 避免从Python或其他选择的语言调用外部实用程序(我们需要提出一种不依赖于第三方解决方案的语言无关解决方案)
为了符合这些要求,一种方法是,检查是否可以访问其中一个。这些服务器的IPv4地址是
8.8.8.8
8.8.4.4
。我们可以尝试连接到其中任何一个

主机
8.8.8.8
的快速Nmap给出了以下结果:

$ sudo nmap 8.8.8.8

Starting Nmap 6.40 ( http://nmap.org ) at 2015-10-14 10:17 IST
Nmap scan report for google-public-dns-a.google.com (8.8.8.8)
Host is up (0.0048s latency).
Not shown: 999 filtered ports
PORT   STATE SERVICE
53/tcp open  domain

Nmap done: 1 IP address (1 host up) scanned in 23.81 seconds
正如我们所看到的,
53/tcp
是开放的、未经过滤的。如果您是非root用户,请记住使用Nmap的
sudo
-Pn
参数发送精心编制的探测数据包并确定主机是否启动

在尝试使用Python之前,让我们使用外部工具Netcat测试连接性:

$ nc 8.8.8.8 53 -zv
Connection to 8.8.8.8 53 port [tcp/domain] succeeded!
Netcat确认我们可以通过
53/tcp
达到
8.8.8
。现在我们可以在Python中设置到
8.8.8.8:53/tcp
的套接字连接,以检查连接:

导入套接字
def互联网(主机=“8.8.8.8”,端口=53,超时=3):
"""
主机:8.8.8.8(google-public-dns-a.google.com)
OpenPort:53/tcp
服务:域(DNS/TCP)
"""
尝试:
socket.setdefaulttimeout(超时)
socket.socket(socket.AF_INET,socket.SOCK_STREAM).connect((主机,端口))
返回真值
除socket.error外,其他为ex:
印刷品(ex)
返回错误
互联网(
另一种方法是向其中一台服务器发送一个手工制作的DNS探测,然后等待响应。但是,我认为,由于数据包丢失、DNS解析失败等原因,相比之下,它可能会慢一些。如果您不这么认为,请发表评论

更新#1:感谢@theamk的评论,timeout现在是一个参数,默认情况下初始化为
3s

更新#2:我做了快速测试,以确定这个问题所有有效答案的最快和最通用的实现。总结如下:

$ ls *.py | sort -n | xargs -I % sh -c 'echo %; ./timeit.sh %; echo'
defos.py
True
00:00:00:00.487

iamaziz.py
True
00:00:00:00.335

ivelin.py
True
00:00:00:00.105

jaredb.py
True
00:00:00:00.533

kevinc.py
True
00:00:00:00.295

unutbu.py
True
00:00:00:00.546

7h3rAm.py
True
00:00:00:00.032
再一次:

$ ls *.py | sort -n | xargs -I % sh -c 'echo %; ./timeit.sh %; echo'
defos.py
True
00:00:00:00.450

iamaziz.py
True
00:00:00:00.358

ivelin.py
True
00:00:00:00.099

jaredb.py
True
00:00:00:00.585

kevinc.py
True
00:00:00:00.492

unutbu.py
True
00:00:00:00.485

7h3rAm.py
True
00:00:00:00.035
上述输出中的
True
表示来自各自作者的所有这些实现都正确识别到互联网的连接。时间以毫秒分辨率显示

更新#3:在异常处理更改后再次测试:

defos.py
True
00:00:00:00.410

iamaziz.py
True
00:00:00:00.240

ivelin.py
True
00:00:00:00.109

jaredb.py
True
00:00:00:00.520

kevinc.py
True
00:00:00:00.317

unutbu.py
True
00:00:00:00.436

7h3rAm.py
True
00:00:00:00.030

如果本地主机已从
127.0.0.1
试一试

除非经过编辑,否则未连接到internet时,您的计算机IP将为127.0.0.1。 这段代码基本上得到了IP地址
import socket
ipaddress=socket.gethostbyname(socket.gethostname())
if ipaddress=="127.0.0.1":
    print("You are not connected to the internet!")
else:
    print("You are connected to the internet with the IP address of "+ ipaddress )
import subprocess

def online(timeout):
    try:
        return subprocess.run(
            ['wget', '-q', '--spider', 'google.com'],
            timeout=timeout
        ).returncode == 0
    except subprocess.TimeoutExpired:
        return False
from urllib.request import urlopen
from time import sleep
urltotest=http://www.lsdx.eu             # my own web page
nboftrials=0
answer='NO'
while answer=='NO' and nboftrials<10:
    try:
        urlopen(urltotest)
        answer='YES'
    except:
        essai='NO'
        nboftrials+=1
        sleep(30)       
import socket

print("website connection checker")
while True:
    website = input("please input website: ")
    print("")
    print(socket.gethostbyname(website))
    if socket.gethostbyname(website) == "92.242.140.2":
        print("Website could be experiencing an issue/Doesn't exist")
    else:
        socket.gethostbyname(website)
        print("Website is operational!")
        print("")
import socket

def haveInternet():
    try:
        # first check if we get the correct IP-Address or just the router's IP-Address
        info = socket.getaddrinfo("www.google.com", None)[0]
        ipAddr = info[4][0]
        if ipAddr == "192.168.0.1" :
            return False
    except:
        return False

    conn = httplib.HTTPConnection("www.google.com", timeout=5)
    try:
        conn.request("HEAD", "/")
        conn.close()
        return True
    except:
        conn.close()
        return False
import requests

try:
    if requests.get('https://google.com').ok:
        print("You're Online")
except:
    print("You're Offline")
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")
import struct
import socket
import select


def send_one_ping(to='8.8.8.8'):
   ping_socket = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.getprotobyname('icmp'))
   checksum = 49410
   header = struct.pack('!BBHHH', 8, 0, checksum, 0x123, 1)
   data = b'BCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwx'
   header = struct.pack(
      '!BBHHH', 8, 0, checksum, 0x123, 1
   )
   packet = header + data
   ping_socket.sendto(packet, (to, 1))
   inputready, _, _ = select.select([ping_socket], [], [], 1.0)
   if inputready == []:
      raise Exception('No internet') ## or return False
   _, address = ping_socket.recvfrom(2048)
   print(address) ## or return True


send_one_ping()
def check_internet():
    url = 'http://www.google.com/'
    timeout = 5
    try:
        _ = requests.get(url, timeout=timeout)
        return True
    except requests.ConnectionError:
        return False