programing

파이썬에서 사용 가능하고 활성화된 네트워크 연결이 있는지 확인하려면 어떻게 해야 합니까?

i4 2023. 6. 20. 21:21
반응형

파이썬에서 사용 가능하고 활성화된 네트워크 연결이 있는지 확인하려면 어떻게 해야 합니까?

저는 제가 온라인 API에 접속할 수 있는지 알고 싶지만, 그러기 위해서는 인터넷 접속이 필요합니다.

파이썬을 사용하여 사용 가능하고 활성화된 연결이 있는지 확인하려면 어떻게 해야 합니까?

다음과 같은 것을 사용할 수 있습니다.

from urllib import request

def internet_on():
    try:
        request.urlopen('http://216.58.192.142', timeout=1)
        return True
    except request.URLError as err: 
        return False

2을 Python 2.x로 합니다.import urllib2 as request:

현재 8.8.8.8은 Google의 IP 주소 중 하나입니다.신속한 응답을 기대할 수 있는 사이트로 변경합니다.

이 고정 IP는 영원히 google.com 에 매핑되지 않습니다.따라서 이 코드는 강력하지 않습니다. 지속적인 유지보수가 필요합니다.

위의 코드에서 FQDN(정규화된 도메인 이름) 대신 고정 IP 주소를 사용하는 이유는 FQDN을 사용하려면 DNS 조회가 필요하기 때문입니다.되어 있지 가 " " " " " " " " " " " " " " " " " " " " " " " " " " " 에 대한 할 수 .urllib_request.urlopen1초 @ 감사합니다.@rzetterberg가 이 점을 지적해 주셔서 감사합니다.


위의 고정 IP 주소가 작동하지 않는 경우 다음을 실행하여 google.com (unix)의 현재 IP 주소를 찾을 수 있습니다.

% dig google.com  +trace 
...
google.com.     300 IN  A   216.58.192.142

만약 우리가 어떤 인터넷 서버에 연결할 수 있다면, 우리는 실제로 연결이 가능합니다.그러나 가장 빠르고 안정적인 접근 방식을 위해서는 모든 솔루션이 최소한 다음 요구 사항을 준수해야 합니다.

  • DNS 확인을 방지합니다(대부분의 시간 동안 사용할 수 있도록 잘 알려진 IP가 필요합니다.
  • 애플리케이션 계층 연결 방지(HTTP/FTP/IMAP 서비스에 연결)
  • Python 또는 선택한 다른 언어로 외부 유틸리티를 호출하지 않음(타사 솔루션에 의존하지 않는 언어에 구애받지 않는 솔루션을 개발해야 함)

이를 준수하기 위해 Google의 공용 DNS 서버 중 하나에 연결할 수 있는지 확인하는 방법이 있습니다.이러한 서버의 IPv4 주소는 다음과 같습니다.8.8.8.8그리고.8.8.4.4아무 것이나 연결해 볼 수 있습니다.

호의빠른 Nmap8.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

시피다보,53/tcp열려 있고 열려 있지 않습니다.사용자가 경우에는 root 사용자를 .sudo 는또.-Pn조작된 시도 패킷을 보내고 호스트가 작동 중인지 확인하는 Nmap의 인수입니다.

Python으로 시도하기 전에 Netcat이라는 외부 도구를 사용하여 연결을 테스트해 보겠습니다.

$ nc 8.8.8.8 53 -zv
Connection to 8.8.8.8 53 port [tcp/domain] succeeded!

넷캣은 우리가 연락할 수 있다는 것을 확인했습니다.8.8.8.81파운드가 53/tcp 이제소연설수있다습니정할결을켓▁connect▁socket▁to에 소켓 연결을 할 수 .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 socket.error as ex:
        print(ex)
        return False

internet()

또 다른 방법은 수동으로 조작된 DNS 시도를 이러한 서버 중 하나로 보내고 응답을 기다리는 것입니다.그러나 패킷 손실, DNS 확인 실패 등으로 인해 비교적 느릴 수 있습니다.만약 당신이 다르게 생각한다면 댓글을 달아주세요.

업데이트 #4: 공용 이름 서버 목록은 IP를 테스트하는 데 유용한 참조 자료입니다.

업데이트 #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

업데이트 #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위의 출력에서 각 작성자의 이러한 모든 구현이 인터넷에 대한 연결을 정확하게 식별한다는 것을 의미합니다.시간은 밀리초 분해능으로 표시됩니다.

덕분에 타임아웃이 @theamk #1: @theamk님, 시간초이인다에니분됩, 화초기는같이과음다어로 되었습니다.3s결석으로

HTML을 가져오지 않도록 HEAD 요청만 하는 것이 더 빠를 것입니다.

try:
    import httplib  # python < 3.0
except:
    import http.client as httplib


def have_internet() -> bool:
    conn = httplib.HTTPSConnection("8.8.8.8", timeout=5)
    try:
        conn.request("HEAD", "/")
        return True
    except Exception:
        return False
    finally:
        conn.close()

답변에 대한 으로 ubutnu/Kevin C 답변대한사다다용음니를 합니다.requests다음과 같은 패키지:

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

단지 파이썬 3.2의 새로운 코드에 대해 unutbu가 말한 것을 업데이트하기 위해.

def check_connectivity(reference):
    try:
        urllib.request.urlopen(reference, timeout=1)
        return True
    except urllib.request.URLError:
        return False

참고로 여기 입력(참조)은 확인하려는 URL입니다.저는 당신이 사는 곳과 빠르게 연결되는 것을 선택하는 것을 제안합니다. 즉,저는 한국에 살고 있기 때문에 아마 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!' )

3의 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")

로컬 호스트가 다음에서 변경된 경우에는 이 작업이 작동하지 않을 수 있습니다.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 주소인지 묻습니다.도움이 되길 바랍니다.

의 최신 휴대용 솔루션requests:

import requests

def internet():
    """Detect an internet connection."""

    connection = None
    try:
        r = requests.get("https://google.com")
        r.raise_for_status()
        print("Internet connection detected.")
        connection = True
    except:
        print("Internet connection not detected.")
        connection = False
    finally:
        return connection

또는 예외가 발생하는 버전:

import requests
from requests.exceptions import ConnectionError

def internet():
    """Detect an internet connection."""

    try:
        r = requests.get("https://google.com")
        r.raise_for_status()
        print("Internet connection detected.")
    except ConnectionError as e:
        print("Internet connection not detected.")
        raise e

이것을 하는 가장 좋은 방법은 파이썬이 웹사이트를 찾을 수 없을 때 항상 제공하는 IP 주소를 확인하도록 하는 것입니다.이 경우 내 코드는 다음과 같습니다.

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 subprocess

def online(timeout):
    try:
        return subprocess.run(
            ['wget', '-q', '--spider', 'google.com'],
            timeout=timeout
        ).returncode == 0
    except subprocess.TimeoutExpired:
        return False

이것은 웹에 주어진 원격 파일이 존재하는지 확인하는 것 외에 아무것도 다운로드하지 않고 조용히 wget을 실행합니다.

unutbu의 답변을 출발점으로 삼고, 과거 "정적" IP 주소 변경으로 인해 화상을 입은 적이 있는 저는 DNS 조회(예: URL "https://www.google.com ")를 사용하여 한 번 확인한 다음 이후 확인에 사용할 수 있도록 응답 서버의 IP 주소를 저장하는 간단한 클래스를 만들었습니다.이러한 방식으로 IP 주소는 항상 최신 상태입니다(클래스가 적어도 몇 년에 한 번은 다시 초기화된다고 가정).저는 또한 서버의 IP 주소를 얻는 방법을 보여준 이 답변에 대해 Gawry에게 공을 돌립니다.이 솔루션의 명백한 해킹은 무시해 주십시오. 여기서는 최소한의 작업 사례를 살펴보겠습니다.:)

제가 가진 것은 다음과 같습니다.

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()

식스의 대답을 들어보면, 저는 우리가 어떻게든 단순화할 수 있다고 생각합니다. 새로 온 사람들이 고도로 기술적인 문제에 빠져 있기 때문에 중요한 문제입니다.

여기서는 PV 모니터링을 위해 하루에 한 번씩 연결(3G, 저속)이 설정될 때까지 기다리는 데 마지막으로 사용할 것입니다.

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분에 도달하면 한 시간 내에 시도할 것이지만 다른 스크립트입니다.

Ivelin의 답변을 받아 라우터가 IP 주소 192.168.0.1을 전달하고 google.com 을 쿼리할 때 인터넷 연결이 없으면 헤드를 반환할 때 추가 확인을 추가합니다.

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

이것은 Python 3.6에서 작동합니다.

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 socket,time
    mem1 = 0
    while True:
        try:
                host = socket.gethostbyname("www.google.com") #Change to personal choice of site
                s = socket.create_connection((host, 80), 2)
                s.close()
                mem2 = 1
                if (mem2 == mem1):
                    pass #Add commands to be executed on every check
                else:
                    mem1 = mem2
                    print ("Internet is working") #Will be executed on state change

        except Exception as e:
                mem2 = 0
                if (mem2 == mem1):
                    pass
                else:
                    mem1 = mem2
                    print ("Internet is down")
        time.sleep(10) #timeInterval for checking

프로젝트의 경우 Google 공용 DNS 서버 8.8.8.8을 ping하기 위해 수정된 스크립트를 사용합니다.1초의 시간 초과 및 외부 종속성이 없는 코어 파이썬 라이브러리 사용:

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()

시간 초과 선택 값은 1이지만 이 예에서는 1초보다 쉽게 실패할 수 있는 부동 소수점 번호일 수 있습니다.

를 실행하여 파이프가 최신 상태인지 확인합니다.

pip install --upgrade pip

다음을 사용하여 요청 패키지 설치

pip install requests  
    import requests
    import webbrowser
    url = "http://www.youtube.com"

    timeout = 6
    try:
        request = requests.get(url, timeout=timeout)
        print("Connected to the Internet")
        print("browser is loading url")
        webbrowser.open(url)
    except (requests.ConnectionError, requests.Timeout) as exception:
       print("poor or no internet connection.")

요청을 가져오고 이 간단한 파이썬 코드를 사용해 보십시오.

def check_internet():
    url = 'http://www.google.com/'
    timeout = 5
    try:
        _ = requests.get(url, timeout=timeout)
        return True
    except requests.ConnectionError:
        return False

저는 단지 Ivelin의 해결책을 참고하고 싶습니다. 왜냐하면 거기에 대해 언급할 수 없기 때문입니다.

이전 SSL 인증서가 있는 python 2.7(나의 경우 업데이트할 수 없음, 다른 이야기)에서는 인증서 오류가 발생할 수 있습니다.이 경우 '8.8.8.8'을 'dns.google' 또는 '8888.google'로 대체하면 도움이 됩니다.

이것이 누군가에게도 도움이 되기를 바랍니다.

try:
    import httplib  # python < 3.0
except:
    import http.client as httplib


def have_internet():
    conn = httplib.HTTPSConnection("8888.google", timeout=5)
    try:
        conn.request("HEAD", "/")
        return True
    except Exception:
        return False
    finally:
        conn.close()

언급URL : https://stackoverflow.com/questions/3764291/how-can-i-see-if-theres-an-available-and-active-network-connection-in-python

반응형