Python에서 사이트를 핑 하시겠습니까?


80

Python으로 웹 사이트 또는 IP 주소를 어떻게 ping합니까?


2
"ping"을 정의하십시오. ICMP ping 프로토콜을 사용 하시겠습니까, 아니면 웹 서버가 실행 중인지 확인 하시겠습니까? 또는 다른 것?
S.Lott

이것은 내가 해결하고 있던 문제에 더 도움이되는 것으로 판명되었습니다 : stackoverflow.com/questions/3764291/checking-network-connection
jedierikb

1
여기 순수한 파이썬의 구현이 있습니다 : falatic.com/index.php/39/pinging-with-python
thinker007

답변:


82

Matthew Dixon CowlesJens Diemer의 순수 Python 핑 을 참조하십시오 . 또한 Python은 Linux에서 ICMP (예 : ping) 소켓을 생성하려면 루트가 필요합니다.

import ping, socket
try:
    ping.verbose_ping('www.google.com', count=3)
    delay = ping.Ping('www.wikipedia.org', timeout=2000).do()
except socket.error, e:
    print "Ping Error:", e

소스 코드 자체는 읽기의 구현을 쉽게 볼 수 verbose_ping와의를 Ping.do영감을.


4
pingtime.clock내 Linux 상자에서 유용한 정보를 얻지 못하는 사용 . timeit.default_timer( time.time내 컴퓨터와 동일 ) 작동합니다. time.clock-> timeit.default_timer gist.github.com/255009
jfs

@Vinicius-감사합니다! github의 새 위치로 업데이트되었습니다. 또한 지속적으로 유지되는 것 같습니다!
orip

3
ping에는 do_one이라는 메서드가 없습니다. 핑 시간을 얻는 간단한 방법을 찾지 못했습니다.
Joseph Turian

1
'run'은 'count'로 이름이 변경되었습니다
pferate

1
@ChrisWithers 'ping'바이너리는 'setuid'비트를 통해 루트로 실행됩니다. superuser.com/a/1035983/4706
orip 2016 년

42

달성하려는 항목에 따라 시스템 ping 명령을 가장 쉽게 호출 할 수 있습니다.

하위 프로세스 모듈을 사용하는 것이이 작업을 수행하는 가장 좋은 방법이지만 ping 명령은 운영 체제마다 다르다는 점을 기억해야합니다!

import subprocess

host = "www.google.com"

ping = subprocess.Popen(
    ["ping", "-c", "4", host],
    stdout = subprocess.PIPE,
    stderr = subprocess.PIPE
)

out, error = ping.communicate()
print out

쉘 이스케이프 문자에 대해 걱정할 필요가 없습니다. 예를 들어 ..

host = "google.com; `echo test`

.. echo 명령을 실행 하지 않습니다 .

이제 실제로 ping 결과를 얻으려면 out변수를 구문 분석 할 수 있습니다. 출력 예 :

round-trip min/avg/max/stddev = 248.139/249.474/250.530/0.896 ms

정규식 예 :

import re
matcher = re.compile("round-trip min/avg/max/stddev = (\d+.\d+)/(\d+.\d+)/(\d+.\d+)/(\d+.\d+)")
print matcher.search(out).groups()

# ('248.139', '249.474', '250.530', '0.896')

다시 말하지만, 출력은 운영 체제 (및 버전 ping) 에 따라 달라질 수 있습니다 . 이것은 이상적이지는 않지만 많은 상황에서 잘 작동합니다 (스크립트가 실행될 컴퓨터를 알고있는 경우).


일치 out를 방해하는 것처럼 보이는 인코딩 된 \ n 포함 으로 정규식 일치 표현식을 조정해야 함을 발견했습니다 .matcher = re.compile("\nround-trip min/avg/max/stddev = (\d+.\d+)/(\d+.\d+)/(\d+.\d+)/(\d+.\d+)")
Pierz


Windows의 경우 사용해야합니다 -n대신 -c. ( ePi272314의 답변 참조 )
Stevoisiak

39

Noah Gift의 프레젠테이션 Creating Agile Commandline Tools With Python을 찾을 수 있습니다 . 여기에서 그는 하위 프로세스, 큐 및 스레딩을 결합하여 호스트를 동시에 ping하고 프로세스 속도를 높일 수있는 솔루션을 개발합니다. 다음은 명령 줄 구문 분석 및 기타 기능을 추가하기 전의 기본 버전입니다. 이 버전 및 기타 버전에 대한 코드는 여기 에서 찾을 수 있습니다.

#!/usr/bin/env python2.5
from threading import Thread
import subprocess
from Queue import Queue

num_threads = 4
queue = Queue()
ips = ["10.0.1.1", "10.0.1.3", "10.0.1.11", "10.0.1.51"]
#wraps system ping command
def pinger(i, q):
    """Pings subnet"""
    while True:
        ip = q.get()
        print "Thread %s: Pinging %s" % (i, ip)
        ret = subprocess.call("ping -c 1 %s" % ip,
            shell=True,
            stdout=open('/dev/null', 'w'),
            stderr=subprocess.STDOUT)
        if ret == 0:
            print "%s: is alive" % ip
        else:
            print "%s: did not respond" % ip
        q.task_done()
#Spawn thread pool
for i in range(num_threads):

    worker = Thread(target=pinger, args=(i, queue))
    worker.setDaemon(True)
    worker.start()
#Place work in queue
for ip in ips:
    queue.put(ip)
#Wait until worker threads are done to exit    
queue.join()

그는 또한 다음의 저자이기도합니다 : Python for Unix and Linux System Administration

http://ecx.images-amazon.com/images/I/515qmR%2B4sjL._SL500_AA240_.jpg


4
이것이 실제로 질문에 대한 답은 아니지만 매우 유용한 정보입니다!
ig0774

나는 그것이 PyCon에서 온다는 것을 알고 있지만 ... 꽤 나쁘다. 시스템 호출을 수행하는 것은 시간과 리소스를 낭비하는 동시에 매우 시스템에 따라 다르며 구문 분석하기 어렵습니다. 이 스레드에는 다른 것이 있기 때문에 ICMP 요청을 보내고 받기 위해 Python을 사용하는 방법을 선택해야합니다.
Cukic0d

9

질문이 무엇인지 말하기는 어렵지만 몇 가지 대안이 있습니다.

말 그대로 ICMP ping 프로토콜을 사용하여 요청을 실행하려는 경우 ICMP 라이브러리를 가져 와서 직접 ping 요청을 실행할 수 있습니다. Google "Python ICMP"는이 icmplib 같은 것을 찾습니다 . scapy 도 살펴볼 수 있습니다 .

이것은를 사용하는 것보다 훨씬 빠릅니다 os.system("ping " + ip ).

일반적으로 상자를 "핑"하여 작동하는지 확인하려는 경우 포트 7에서 에코 프로토콜을 사용할 수 있습니다.

echo의 경우 소켓 라이브러리를 사용하여 IP 주소와 포트 7을 엽니 다. 해당 포트에 무언가를 쓰고 캐리지 리턴 ( "\r\n")을 보낸 다음 응답을 읽습니다.

사이트가 실행 중인지 확인하기 위해 웹 사이트를 "ping"하려면 포트 80에서 http 프로토콜을 사용해야합니다.

웹 서버를 위해 또는 적절하게 확인하려면 urllib2 를 사용하여 특정 URL을 엽니 다. ( /index.html항상 인기가 있음) 응답을 읽으십시오.

"traceroute"및 "finger"를 포함하여 "ping"의 잠재적 인 의미가 더 많이 있습니다.


5
echo는 한때 널리 퍼져 있었지만 이제는 대부분의 시스템에서 기본적으로 비활성화되었습니다. 따라서 기계가 제대로 작동하는지 테스트하는 실용적인 방법이 아닙니다.
bortzmeyer

8

영감으로 비슷한 일을했습니다.

import urllib
import threading
import time

def pinger_urllib(host):
  """
  helper function timing the retrival of index.html 
  TODO: should there be a 1MB bogus file?
  """
  t1 = time.time()
  urllib.urlopen(host + '/index.html').read()
  return (time.time() - t1) * 1000.0


def task(m):
  """
  the actual task
  """
  delay = float(pinger_urllib(m))
  print '%-30s %5.0f [ms]' % (m, delay)

# parallelization
tasks = []
URLs = ['google.com', 'wikipedia.org']
for m in URLs:
  t = threading.Thread(target=task, args=(m,))
  t.start()
  tasks.append(t)

# synchronization point
for t in tasks:
  t.join()

1
외부 라이브러리에서 멀리 체재 기뻐subprocess
tshepang

index.html이 없으면 어떻게됩니까?
sbose 2013 년

4
더 중요한 것은 웹 서버가 없다면 어떨까요?
Kim Gräsman

실제로 연결할 필요가 없습니다 /index.html. 실제로라는 문서가있는 모든 사이트에서 index.html바로 서버 루트에 있습니다. 대신 당신은 줄 앞에 추가 http:// 또는 https://호스트
안티 Haapala

TCP 포트 80 "ping"+ HTTP 테스트만큼 ICMP 핑은 아니지만 실제로 콘텐츠를 수신하지 않으므로 HEAD (또는 OPTIONS) 요청을 수행하는 것이 더 좋을 수 있으므로 대역폭이 덜 영향을 미칩니다. 여분의 것을 더 원한다면 호스트에 TCP 80 소켓을 열고 즉시 닫으십시오.
Nick T

6

다음은 subprocess. 이 check_call메서드는 성공하면 0을 반환하거나 예외를 발생시킵니다. 이렇게하면 ping 출력을 구문 분석 할 필요가 없습니다. shlex명령 줄 인수를 분할하는 데 사용 하고 있습니다.

  import subprocess
  import shlex

  command_line = "ping -c 1 www.google.comsldjkflksj"
  args = shlex.split(command_line)
  try:
      subprocess.check_call(args,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
      print "Website is there."
  except subprocess.CalledProcessError:
      print "Couldn't get a ping."

3
경고 : 않는 창 (에없는 일 -c이다 -n가, 및 반환 코드에 대한 논리가 다릅니다)
WIM

3

파일 이름을 읽으면 파일에는 다음과 같이 한 줄에 하나의 URL이 포함됩니다.

http://www.poolsaboveground.com/apache/hadoop/core/
http://mirrors.sonic.net/apache/hadoop/core/

사용 명령 :

python url.py urls.txt

결과를 얻으십시오 :

Round Trip Time: 253 ms - mirrors.sonic.net
Round Trip Time: 245 ms - www.globalish.com
Round Trip Time: 327 ms - www.poolsaboveground.com

소스 코드 (url.py) :

import re
import sys
import urlparse
from subprocess import Popen, PIPE
from threading import Thread


class Pinger(object):
    def __init__(self, hosts):
        for host in hosts:
            hostname = urlparse.urlparse(host).hostname
            if hostname:
                pa = PingAgent(hostname)
                pa.start()
            else:
                continue

class PingAgent(Thread):
    def __init__(self, host):
        Thread.__init__(self)        
        self.host = host

    def run(self):
        p = Popen('ping -n 1 ' + self.host, stdout=PIPE)
        m = re.search('Average = (.*)ms', p.stdout.read())
        if m: print 'Round Trip Time: %s ms -' % m.group(1), self.host
        else: print 'Error: Invalid Response -', self.host


if __name__ == '__main__':
    with open(sys.argv[1]) as f:
        content = f.readlines() 
    Pinger(content)

2
import subprocess as s
ip=raw_input("Enter the IP/Domain name:")
if(s.call(["ping",ip])==0):
    print "your IP is alive"
else:
    print "Check ur IP"

2

실제로 Python으로 플레이 할 수있는 무언가를 원한다면 Scapy를 살펴보십시오.

from scapy.all import *
request = IP(dst="www.google.com")/ICMP()
answer = sr1(request)

그것은 내 생각에 펑키 한 하위 프로세스 호출보다 훨씬 낫습니다 (그리고 완전히 크로스 플랫폼). 또한 패킷 자체가있는만큼 원하는만큼 응답 (시퀀스 ID .....)에 대한 정보를 가질 수 있습니다.


2

가장 간단한 대답은 다음과 같습니다.

import os
os.system("ping google.com") 

1

여기에서 Windows와 Linux 모두에서 작동하는 언급 된 스크립트의 업데이트 된 버전을 찾을 수 있습니다.


연결된 코드는 Python 3.8에서 실패합니다. "구문 에러 : 유효하지 않은 구문"
Stevoisiak

1

나는 당신을 도울 수 있다고 생각하는 도서관을 개발합니다. icmplib (인터넷에서 찾을 수있는 동일한 이름의 다른 코드와 관련이 없음)라고하며 Python에서 ICMP 프로토콜을 순수하게 구현 한 것입니다.

완전히 객체 지향적이며 ICMP 프로토콜을 기반으로 응용 프로그램을 개발하려는 사용자를위한 저수준 클래스 및 소켓뿐만 아니라 클래식 핑, 멀티 핑 및 추적 경로와 같은 간단한 기능이 있습니다.

다른 주요 사항은 다음과 같습니다.

  • 루트 권한없이 실행할 수 있습니다.
  • ICMP 패킷의 페이로드 및 트래픽 클래스 (QoS)와 같은 많은 매개 변수를 사용자 정의 할 수 있습니다.
  • 크로스 플랫폼 : Linux, macOS 및 Windows에서 테스트되었습니다.
  • 빠르고 하위 프로세스를 사용한 호출과 달리 CPU / RAM 리소스가 거의 필요하지 않습니다.
  • 가볍고 추가 종속성에 의존하지 않습니다.

설치하려면 (Python 3.6 이상 필요) :

pip3 install icmplib

다음은 ping 함수의 간단한 예입니다.

host = ping('1.1.1.1', count=4, interval=1, timeout=2, privileged=True)

if host.is_alive:
    print(f'{host.address} is alive! avg_rtt={host.avg_rtt} ms')
else:
    print(f'{host.address} is dead')

루트 권한없이 라이브러리를 사용하려면 "privileged"매개 변수를 False로 설정하십시오.

프로젝트 페이지에서 전체 문서를 찾을 수 있습니다 : https://github.com/ValentinBELYN/icmplib

이 라이브러리가 유용하기를 바랍니다.


2
중재자 참고 사항 :이 답변 은 자체 프로모션에 대한 요구 사항을 따르고 , 요청하지 않았으며 (Ping을 사용하기위한 Python 솔루션을 요청 함) 용어 정의에 따라 스팸아닙니다 .
Martijn Pieters

0

시스템 ping 명령을 사용하여 호스트 목록을 ping합니다.

import re
from subprocess import Popen, PIPE
from threading import Thread


class Pinger(object):
    def __init__(self, hosts):
        for host in hosts:
            pa = PingAgent(host)
            pa.start()

class PingAgent(Thread):
    def __init__(self, host):
        Thread.__init__(self)        
        self.host = host

    def run(self):
        p = Popen('ping -n 1 ' + self.host, stdout=PIPE)
        m = re.search('Average = (.*)ms', p.stdout.read())
        if m: print 'Round Trip Time: %s ms -' % m.group(1), self.host
        else: print 'Error: Invalid Response -', self.host


if __name__ == '__main__':
    hosts = [
        'www.pylot.org',
        'www.goldb.org',
        'www.google.com',
        'www.yahoo.com',
        'www.techcrunch.com',
        'www.this_one_wont_work.com'
       ]
    Pinger(hosts)

6
나는 단지 킥과 킥킥 거리를 위해 www.this_one_wont_work.com을 등록 할 것입니다.
Matthew Scouten

p = Popen('ping -n 1 ' + self.host, stdout=PIPE)되어야합니다 p = Popen(['ping','-n','1','self.host'], stdout=PIPE)
toc777 2011

0

응답이 바이너리이기 때문에 하위 프로세스 ping 명령을 사용하여 ping 디코딩합니다.

import subprocess
ping_response = subprocess.Popen(["ping", "-a", "google.com"], stdout=subprocess.PIPE).stdout.read()
result = ping_response.decode('utf-8')
print(result)

0

당신은 사이트의 IP를 얻기 위해 소켓을 시도하고 ip에 대한 icmp ping을 실행하기 위해 scrapy를 사용할 수 있습니다.

import gevent
from gevent import monkey
# monkey.patch_all() should be executed before any library that will
# standard library
monkey.patch_all()

import socket
from scapy.all import IP, ICMP, sr1


def ping_site(fqdn):
    ip = socket.gethostbyaddr(fqdn)[-1][0]
    print(fqdn, ip, '\n')
    icmp = IP(dst=ip)/ICMP()
    resp = sr1(icmp, timeout=10)
    if resp:
        return (fqdn, False)
    else:
        return (fqdn, True)


sites = ['www.google.com', 'www.baidu.com', 'www.bing.com']
jobs = [gevent.spawn(ping_site, fqdn) for fqdn in sites]
gevent.joinall(jobs)
print([job.value for job in jobs])

-1

이것을 사용하면 python 2.7에서 테스트되었으며 성공하면 핑 시간을 밀리 초 단위로 반환하고 실패하면 False를 반환합니다.

import platform,subproccess,re
def Ping(hostname,timeout):
    if platform.system() == "Windows":
        command="ping "+hostname+" -n 1 -w "+str(timeout*1000)
    else:
        command="ping -i "+str(timeout)+" -c 1 " + hostname
    proccess = subprocess.Popen(command, stdout=subprocess.PIPE)
    matches=re.match('.*time=([0-9]+)ms.*', proccess.stdout.read(),re.DOTALL)
    if matches:
        return matches.group(1)
    else: 
        return False

1
Python 3.6에서 실패합니다. ModuleNotFoundError : 없음은 모듈 'subproccess'라는 이름
Stevoisiak

또한 command목록 대신 모든 인수를 포함하는 문자열이므로 command not foundLinux에서 전체 문자열을 트리거하므로 실패합니다 .
arielf
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.