13 ответов:
возможно, вы могли бы использовать что-то вроде этого:
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-адрес вместо полного доменного имени (Полное доменное имя) - это потому, что полное доменное имя потребует поиска DNS. Когда машина не имеет рабочего подключения к интернету, сам поиск DNS может заблокировать вызов
urllib_request.urlopenболее чем на секунду. Спасибо @rzetterberg за указание на это.
если фиксированный IP-адрес выше не работает, вы можете найти текущий IP-адрес для google.com (в unix), запустив
% dig google.com +trace ... google.com. 300 IN A 216.58.192.142
если мы можем подключиться к какому-то интернет-серверу, то у нас действительно есть подключение. Однако для максимально быстрого и надежного подхода все решения должны соответствовать, как минимум, следующим требованиям:
- избегайте разрешения DNS (нам понадобится IP, который хорошо известен и гарантированно будет доступен в течение большей части времени)
- избегайте подключений на уровне приложений (подключение к службе HTTP / FTP / IMAP)
- избегайте звонков внешние утилиты из Python или другого языка выбора (нам нужно придумать язык-агностическое решение, которое не зависит от сторонних решений)
чтобы соответствовать этим, один подход может быть, чтобы проверить, если один из публичные DNS-серверы Google достижим. 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, 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
это будет быстрее, чтобы просто сделать запрос головы, так что никакой 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
просто чтобы обновить то, что 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бонус: это может быть распространено на эту функцию, которая пингует веб-сайт.
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
вы можете просто попробовать загрузить данные, и если соединение не удастся, вы будете знать, что что-то с подключением не в порядке.
в основном вы не можете проверить, подключен ли компьютер к интернету. Причин сбоя может быть много, например неправильная конфигурация 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!' )для python 3, Используйте
urllib.request.urlopen(host)
попробуйте операцию, которую вы пытались сделать в любом случае. Если это не удается python должен бросить вам исключение, чтобы вы знали.
чтобы попробовать какую-то тривиальную операцию, чтобы сначала обнаружить соединение, будет введено условие гонки. Что делать, если подключение к интернету действительно, когда вы тестируете, но идет вниз, прежде чем вам нужно сделать реальную работу?
лучший способ сделать это-проверить его на IP-адрес, который python всегда дает, если он не может найти веб-сайт. В данном случае это мой код:
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("")
С unutbu это в качестве отправной точки, и были сожжены в прошлом году такой "статический" IP-адрес меняется, я сделал простой класс, который проверяет, как с помощью DNS-запросов (т. е., используя URL-адрес "https://www.google.com"), а затем сохраняет IP-адрес сервера отвечать на запросы для использования на последующих проверок. Таким образом, IP-адрес всегда обновляется (при условии, что класс повторно инициализируется по крайней мере один раз в несколько лет или около того). Я также отдаю должное gawry для ответ, который показал мне, как получить 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()
Это может не сработать, если localhost был изменен с
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-адрес localhost . Надеюсь, что это поможет
принимая шесть ' ответ я думаю, что мы могли бы упростить как-то, важный вопрос, поскольку новички теряются в очень технических вопросах.
вот что я, наконец, буду использовать, чтобы дождаться моего соединения (3G, slow), которое будет установлено один раз в день для моего мониторинга 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 минут, если достигнуто, я попробую через один час, но это еще один бит скрипта!
мой любимый, при запуске скриптов на кластере или нет
import subprocess def online(timeout): try: return subprocess.run( ['wget', '-q', '--spider', 'google.com'], timeout=timeout ).returncode == 0 except subprocess.TimeoutExpired: return Falseэто работает wget тихо, не загружая ничего, но проверяя, что данный удаленный файл существует в интернете
Comments