Python 检查网络连接
我想看看我是否可以访问在线API,但为此我需要访问InternetPython 检查网络连接,python,networking,Python,Networking,我想看看我是否可以访问在线API,但为此我需要访问Internet 如何使用Python查看是否存在可用且处于活动状态的连接?您可以尝试下载数据,如果连接失败,您将知道连接有问题 基本上你们不能检查电脑是否连接到互联网。失败的原因可能有很多,比如错误的DNS配置、防火墙、NAT。因此,即使您进行了一些测试,您也无法保证在尝试之前与API保持连接。也许您可以使用以下内容: import urllib2 def internet_on(): try: urllib2.url
如何使用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或其他选择的语言调用外部实用程序(我们需要提出一种不依赖于第三方解决方案的语言无关解决方案)
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