我想看看我是否可以访问在线API,但为了实现这一点,我需要有Internet访问权限。
如何使用Python查看是否有可用的活动连接?
发布于 2010-09-22 05:31:52
也许你可以使用这样的东西:
import urllib2
def internet_on():
    try:
        urllib2.urlopen('http://216.58.192.142', timeout=1)
        return True
    except urllib2.URLError as err: 
        return False目前,216.58.192.142是google.com的IP地址之一。将http://216.58.192.142更改为任何可以快速响应的站点。
此固定IP不会永远映射到google.com。所以这段代码并不健壮--它需要不断的维护才能使其正常工作。
上面代码使用固定IP地址而不是完全限定域名( FQDN )的原因是因为FQDN需要DNS查找。当机器没有工作的互联网连接时,DNS查找本身可能会阻止对urllib_request.urlopen的调用超过一秒钟。感谢@rzetterberg指出这一点。
如果上面的固定IP地址不起作用,您可以通过运行以下命令查找google.com (在unix上)的当前IP地址
% dig google.com  +trace 
...
google.com.     300 IN  A   216.58.192.142发布于 2015-10-14 13:51:53
如果我们可以连接到某个Internet服务器,那么我们就确实有了连接。但是,为了实现最快、最可靠的方法,所有解决方案至少应符合以下要求:
要符合这些要求,一种方法可能是检查其中一个Google's public DNS servers是否可达。这些服务器的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是开放的和非过滤的。如果您是非根用户,请记住使用sudo或Nmap的-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.8。现在,我们可以在Python中设置到8.8.8.8:53/tcp的套接字连接,以检查连接:
import socket
def internet(host="8.8.8.8", port=53, timeout=3):
    """
    Host: 8.8.8.8 (google-public-dns-a.google.com)
    OpenPort: 53/tcp
    Service: domain (DNS/TCP)
    """
    try:
        socket.setdefaulttimeout(timeout)
        socket.socket(socket.AF_INET, socket.SOCK_STREAM).connect((host, port))
        return True
    except socket.error as ex:
        print(ex)
        return False
internet()另一种方法是向其中一台服务器发送手动创建的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发布于 2015-04-25 01:52:02
只做一个HEAD请求会更快,这样就不会获取HTML。
此外,我相信google会更喜欢这种方式:)
try:
    import httplib  # python < 3.0
except:
    import http.client as httplib
def have_internet():
    conn = httplib.HTTPSConnection("8.8.8.8", timeout=5)
    try:
        conn.request("HEAD", "/")
        return True
    except Exception:
        return False
    finally:
        conn.close()https://stackoverflow.com/questions/3764291
复制相似问题