unu*_*tbu 121
也许你可以使用这样的东西:
import urllib2
def internet_on():
try:
urllib2.urlopen('http://216.58.192.142', timeout=1)
return True
except urllib2.URLError as err:
return False
Run Code Online (Sandbox Code Playgroud)
目前,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的当前IP地址(在unix上)
% dig google.com +trace
...
google.com. 300 IN A 216.58.192.142
Run Code Online (Sandbox Code Playgroud)
7h3*_*rAm 94
如果我们可以连接到某个Internet服务器,那么我们确实有连接.但是,对于最快和最可靠的方法,所有解决方案至少应符合以下要求:
为了符合这些,一种方法可以是,检查是否可以访问Google的一个公共DNS服务器.这些服务器的IPv4地址是8.8.8.8和8.8.4.4.我们可以尝试连接到它们中的任何一个.
主机的快速Nmap 8.8.8.8给出了以下结果:
$ 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
Run Code Online (Sandbox Code Playgroud)
我们可以看到,TCP/53是开放的,未经过滤.如果您是非root用户,请记住使用sudo或-PnNmap 的参数发送精心设计的探测数据包并确定主机是否已启动.
在我们尝试使用Python之前,让我们使用外部工具Netcat测试连接:
$ nc 8.8.8.8 53 -zv
Connection to 8.8.8.8 53 port [tcp/domain] succeeded!
Run Code Online (Sandbox Code Playgroud)
Netcat确认我们可以8.8.8.8通过TCP/53 达到目标.现在我们可以在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()
Run Code Online (Sandbox Code Playgroud)
另一种方法是将手动制作的DNS探测发送到其中一个服务器并等待响应.但是,我认为,由于数据包丢失,DNS解析失败等原因,它可能会比较慢.如果您不这么认为,请发表评论.
更新#1:感谢@ theamk的评论,超时现在是一个参数,默认情况下初始化为3秒.
更新#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
Run Code Online (Sandbox Code Playgroud)
再一次:
$ 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
Run Code Online (Sandbox Code Playgroud)
True在上面的输出中表示来自各个作者的所有这些实现都正确地识别了到Internet的连接.时间以毫秒分辨率显示.
更新#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
Run Code Online (Sandbox Code Playgroud)
Ive*_*lin 54
只发出一个HEAD请求会更快,因此不会获取任何HTML.
此外,我相信谷歌会更喜欢这样:)
try:
import httplib
except:
import http.client as httplib
def have_internet():
conn = httplib.HTTPConnection("www.google.com", timeout=5)
try:
conn.request("HEAD", "/")
conn.close()
return True
except:
conn.close()
return False
Run Code Online (Sandbox Code Playgroud)
Def*_*_Os 19
作为ubutnu/Kevin C答案的替代方案,我使用这样的requests包:
import requests
def connected_to_internet(url='http://www.google.com/', timeout=5):
try:
_ = requests.get(url, timeout=timeout)
return True
except requests.ConnectionError:
print("No internet connection available.")
return False
Run Code Online (Sandbox Code Playgroud)
奖励:这可以扩展到ping这个网站的功能.
def web_site_online(url='http://www.google.com/', timeout=5):
try:
req = requests.get(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
Run Code Online (Sandbox Code Playgroud)
Kev*_*n C 16
只是为了更新unutbu在Python 3.2中为新代码所说的内容
def check_connectivity(reference):
try:
urllib.request.urlopen(reference, timeout=1)
return True
except urllib.request.URLError:
return False
Run Code Online (Sandbox Code Playgroud)
而且,请注意,这里的输入(参考)是你要检查的网址:我建议选择一些快速连接的东西 - 即我住在韩国,所以我可能会设置参考http:/ /www.naver.com.
您可以尝试下载数据,如果连接失败,您将知道连接的某些事情并不正常.
基本上你无法检查计算机是否连接到互联网.失败可能有很多原因,例如错误的DNS配置,防火墙,NAT.因此,即使您进行了一些测试,也无法确保在尝试之前与API建立连接.
import urllib
def connected(host='http://google.com'):
try:
urllib.urlopen(host)
return True
except:
return False
# test
print( 'connected' if connected() else 'no internet!' )
Run Code Online (Sandbox Code Playgroud)
对于python 3,请使用 urllib.request.urlopen(host)
无论如何都要尝试您尝试执行的操作。如果失败,python 应该抛出一个异常让你知道。
首先尝试一些微不足道的操作来检测连接将引入竞争条件。如果互联网连接在您测试时有效,但在您需要进行实际工作之前就断开了怎么办?
这是我的版本
import requests
try:
if requests.get('https://google.com').ok:
print("You're Online")
except:
print("You're Offline")
Run Code Online (Sandbox Code Playgroud)