Я хочу посмотреть, могу ли я получить доступ к онлайн-API, но для этого мне нужен доступ в Интернет.Проверка сетевого подключения
Как я могу узнать, есть ли доступ к подключению и активен с помощью Python?
Я хочу посмотреть, могу ли я получить доступ к онлайн-API, но для этого мне нужен доступ в Интернет.Проверка сетевого подключения
Как я могу узнать, есть ли доступ к подключению и активен с помощью Python?
Может быть, вы могли бы использовать что-то вроде этого:
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 является один из IP-адресов для google.com. Изменить http://216.58.192.142
на любой сайт можно быстро ответить.
Этот фиксированный IP-адрес не будет отображаться на google.com навсегда. Таким образом, этот код не является надежным - для его работы потребуется постоянное обслуживание.
Причина, по которой указанный выше код использует фиксированный IP-адрес вместо полного доменного имени (FQDN), заключается в том, что для полного доменного имени потребуется поиск DNS. Когда у компьютера нет рабочего интернет-соединения, сам поиск DNS может заблокировать вызов до urllib_request.urlopen
более чем на секунду. Спасибо @rzetterberg за это.
Если фиксированный IP-адрес выше не работает, вы можете найти текущий IP-адрес google.com (на Unix), запустив
% dig google.com +trace
...
google.com. 300 IN A 216.58.192.142
спасибо m8, просто, как и он работает очень сильно! :) –
Просто примечание о «вызове' urlopen' займет не больше 1 секунды, даже если интернет не включен ». Это неверно, если указанный URL недействителен, тогда поиск DNS блокируется. Это верно только для фактического подключения к веб-серверу. Самый простой способ избежать этого блока поиска DNS - использовать вместо этого IP-адрес, тогда он гарантированно займет всего 1 секунду :) – rzetterberg
ЭТО НЕ ДОЛЖНО РАБОТАТЬ. По состоянию на сентябрь 2013 года, после долгого времени, http://74.125.113.99 раза, поэтому эта функция всегда будет возвращать False. Я полагаю, что Google изменил свою сеть. – theamk
Вы можете просто попытаться загрузить данные, и если соединение не удастся, вы узнаете, что что-то с подключением не очень хорошо.
В принципе, вы не можете проверить, подключен ли компьютер к Интернету. Могут быть много причин для отказа, например неправильная настройка DNS, брандмауэры, NAT. Поэтому, даже если вы сделаете некоторые тесты, вы не можете гарантировать, что у вас будет соединение с вашим API, пока вы не попробуете.
«Легче просить прощения, чем разрешение» – cobbal
Это не должно быть так хорошо. Мне просто нужно попытаться подключиться к сайту или пинговать что-то, и если он даст таймаут voilá. Как я могу это сделать? –
Есть ли причина, по которой вы не можете просто попытаться подключиться к API? Почему вы должны проверить его до реального подключения? –
Попробуйте операцию, которую вы пытались сделать в любом случае , Если это не удается, python должен бросить вам исключение, чтобы вы знали.
Чтобы попытаться выполнить некоторую тривиальную операцию, чтобы обнаружить соединение, будет введено условие гонки. Что делать, если интернет-соединение действительно, когда вы проверяете, но уходит, прежде чем вам нужно будет выполнить фактическую работу?
Просто обновить то, что unutbu сказал для нового кода в Python 3.2
def check_connectivity(reference):
try:
urllib.request.urlopen(reference, timeout=1)
return True
except urllib.request.URLError:
return False
И только отметить, вход здесь (ссылка) является URL, который вы хотите проверить: я предлагаю выбрать что-то, что соединяет быстро, где вы живете, то есть я живу в Южной Корее, поэтому я, вероятно, установил бы ссылку на http://www.naver.com.
В качестве альтернативы 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
Bonus: это может быть продлен до этой функции, которая пингует сайт.
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
Запрос - отличная библиотека. Однако в отличие от многих примеров здесь я бы использовал [IANA's example.com] (https://www.iana.org/domains/reserved) или example.org как более надежный долгосрочный выбор, поскольку он полностью контролируется [ICANN] (https://en.wikipedia.org/wiki/ICANN). – chirale
Будет быстрее просто сделать запрос HEAD, поэтому HTML-код не будет извлечен.
Кроме того, я уверен, что Google хотел бы это лучше так :)
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
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!')
Для Python 3, использовать urllib.request.urlopen(host)
Принимая unutbu's answer в качестве отправной точки, и, были сожжены в прошлом путем «статического» изменения IP-адреса я сделал простой класс, который проверяет один раз с помощью поиска DNS (т. е. используя URL-адрес «https://www.google.com»), а затем сохраняет IP-адрес отвечающего сервера для использования при последующих проверках. Таким образом, IP-адрес всегда обновляется (предполагается, что класс повторно инициализируется не реже одного раза в несколько лет или около того). Я также отдает должное gawry за this answer, который показал мне, как получить 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()
Если мы можем подключиться к какой-то интернет-сервер, то мы действительно имеем связи. Тем не менее, самый быстрый и самый надежный подход, все решения должны соответствовать следующим требованиям, по крайней мере:
разрешение DNSЧтобы соответствовать этим требованиям, можно сделать один подход, проверить, доступен ли один из Google's public DNS servers. Адреса 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
Как мы можем видеть, TCP/53 открыт и нефильтрованное. Если вы являетесь пользователем, не являющимся пользователем root, не забудьте использовать sudo
или аргумент -Pn
для Nmap для отправки обработанных пробных пакетов и определения наличия хоста.
Прежде чем мы попытаемся с Python, давайте тест соединения с помощью внешнего инструмента, Netcat:
$ nc 8.8.8.8 53 -zv
Connection to 8.8.8.8 53 port [tcp/domain] succeeded!
Netcat подтверждает, что мы можем достичь 8.8.8.8
через TCP/53. Теперь мы можем установить соединение через сокет к 8.8.8.8:53/TCP в Python, чтобы проверить подключение:
>>> 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 Exception as ex:
... print ex.message
... return False
...
>>> internet()
True
>>>
Другой подход мог бы отправить вручную умыслом DNS зонд к одному из этих серверов и ждать ответа. Но, я полагаю, это может оказаться более медленным по сравнению с падением пакетов, сбой разрешения DNS и т. Д. Прокомментируйте, если вы думаете иначе.
UPDATE # 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
И еще раз:
$ 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
в выводе выше означает, что все эти реализации от соответствующих авторов правильно определить возможность подключения к Интернету. Время отображается с разрешением в миллисекундах.
UPDATE # 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
Это лучший ответ, избегая разрешения DNS и, по иронии судьбы, консультируясь с DNS-службой Google на порту 53. – erm3nda
kudos для ответа. Brilliant. Просто быстрый вопрос, изменяет ли DNS-сервер google IP? или его фиксированный? –
@AviMehenwal Google предоставляет этот IP-адрес в качестве части бесплатного использования службы разрешения имен DNS. IP-адрес не должен изменяться, если Google не примет иного решения. Я использую его как альтернативный DNS-сервер уже несколько лет без каких-либо проблем. – 7h3rAm
Это может не работать, если локальный был изменен с 127.0.0.1
Попробуйте
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)
Если не редактируется, ваши компьютеры IP будет 127.0.0.1, если он не подключен к Интернету. Этот код в основном получает IP-адрес, а затем спрашивает, является ли он локальным IP-адресом. Надежда, что помогает
Это интересная проверка, хотя она будет определять только если вы подключены к сети. Будет ли это Интернет или подсеть NAT'd, все равно останется вопросом. – 7h3rAm
@ 7h3rAm, это хороший момент, DCHP не требует подключения к интернету, моя ошибка. –
мои любимый, при выполнении сценариев на кластере или нет
import subprocess
def online(timeout):
try:
return subprocess.run(['wget', '-q', '--spider', 'google.com'], timeout=timeout).returncode == 0
except subprocess.TimeoutExpired:
return False
это работает Wget тихо, ничего не скачивая, но проверять, что данный удаленный файл существует в Интернете
Отвечая на шесть ответов, я думаю, что мы могли бы как-то упростить, важный вопрос, поскольку новички теряются в высокотехнических вопросах.
Здесь, что я, наконец, буду использовать, чтобы дождаться, когда мое соединение (3G, медленное) будет установлено один раз в день для моего мониторинга PV.
Работы по Pyth3 с Raspbian 3.4.2
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)
максимальный ход: 5 минут, если Достигнутые я буду стараться в течение одного часа, но его еще один бит сценария!
Ваш essai var не привыкает, не так ли? – kidCoder
Если вы находитесь на питоне, это почти наверняка вызовет исключение в случае сбоя подключения или таймаута. Вы можете либо попробовать/поймать это, либо просто дать ему поверхность. – jdizzle
@Triptych: Я надеюсь, что это была шутка, потому что она не работает – inspectorG4dget
@ inspectorG4dget: 'easy_install system_of_tubes' –