Wie pinge ich eine Website oder IP-Adresse mit Python?
Wie pinge ich eine Website oder IP-Adresse mit Python?
Antworten:
Sehen Sie diesen reinen Python-Ping von Matthew Dixon Cowles und Jens Diemer . Denken Sie auch daran, dass Python Root benötigt, um ICMP-Sockets (dh Ping-Sockets) unter Linux zu erzeugen.
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
Der Quellcode selbst ist leicht zu lesen, siehe die Implementierungen von verbose_ping
und von Ping.do
als Inspiration.
ping
Verwendungen time.clock
, die auf meiner Linux-Box nichts Nützliches ergeben. timeit.default_timer
(es ist gleich time.time
auf meinem Computer) funktioniert. time.clock
-> timeit.default_timer
gist.github.com/255009
Je nachdem, was Sie erreichen möchten, ist es wahrscheinlich am einfachsten, den System-Ping-Befehl aufzurufen.
Die Verwendung des Unterprozessmoduls ist der beste Weg, obwohl Sie sich daran erinnern müssen, dass der Ping-Befehl auf verschiedenen Betriebssystemen unterschiedlich ist!
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
Sie müssen sich keine Gedanken über Shell-Escape-Charaktere machen. Zum Beispiel..
host = "google.com; `echo test`
..wird den Echo-Befehl nicht ausführen.
Um die Ping-Ergebnisse tatsächlich zu erhalten, können Sie die out
Variable analysieren . Beispielausgabe:
round-trip min/avg/max/stddev = 248.139/249.474/250.530/0.896 ms
Beispiel Regex:
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')
Denken Sie auch hier daran, dass die Ausgabe je nach Betriebssystem (und sogar der Version von ping
) unterschiedlich sein wird. Dies ist nicht ideal, funktioniert aber in vielen Situationen einwandfrei (wenn Sie die Computer kennen, auf denen das Skript ausgeführt wird).
out
codierte \ n enthält, die den Matching zu stören scheinen:matcher = re.compile("\nround-trip min/avg/max/stddev = (\d+.\d+)/(\d+.\d+)/(\d+.\d+)/(\d+.\d+)")
Möglicherweise finden Sie die Präsentation von Noah Gift. Erstellen agiler Befehlszeilentools mit Python . Darin kombiniert er Unterprozess, Warteschlange und Threading, um eine Lösung zu entwickeln, die Hosts gleichzeitig anpingen und den Prozess beschleunigen kann. Im Folgenden finden Sie eine Basisversion, bevor er die Befehlszeilenanalyse und einige andere Funktionen hinzufügt. Den Code zu dieser und anderen Versionen finden Sie hier
#!/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()
Er ist außerdem Autor von: Python für Unix und Linux System Administration
http://ecx.images-amazon.com/images/I/515qmR%2B4sjL._SL500_AA240_.jpg
Es ist schwer zu sagen, was Ihre Frage ist, aber es gibt einige Alternativen.
Wenn Sie eine Anforderung buchstäblich mit dem ICMP-Ping-Protokoll ausführen möchten, können Sie eine ICMP-Bibliothek abrufen und die Ping-Anforderung direkt ausführen. Google "Python ICMP", um Dinge wie diese icmplib zu finden . Vielleicht möchten Sie sich auch scapy ansehen .
Dies ist viel schneller als die Verwendung os.system("ping " + ip )
.
Wenn Sie generisch eine Box "anpingen" möchten, um festzustellen, ob sie aktiv ist, können Sie das Echo-Protokoll an Port 7 verwenden.
Für Echo verwenden Sie die Socket- Bibliothek, um die IP-Adresse und den Port 7 zu öffnen. Sie schreiben etwas auf diesen Port, senden einen Wagenrücklauf ( "\r\n"
) und lesen dann die Antwort.
Wenn Sie eine Website "anpingen" möchten, um festzustellen, ob die Website ausgeführt wird, müssen Sie das http-Protokoll an Port 80 verwenden.
Um einen Webserver zu überprüfen oder ordnungsgemäß zu überprüfen, verwenden Sie urllib2 , um eine bestimmte URL zu öffnen. ( /index.html
ist immer beliebt) und lesen Sie die Antwort.
Es gibt noch mehr mögliche Bedeutungen von "Ping", einschließlich "Traceroute" und "Finger".
Ich habe etwas Ähnliches auf diese Weise gemacht, als Inspiration:
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()
subprocess
/index.html
; An jedem Ort, an dem tatsächlich ein Dokument aufgerufen wird index.html
, befindet es sich genau dort im Server-Stammverzeichnis. Stattdessen würden Sie voranstellen http://
oder https://
den Host
Hier ist ein kurzer Ausschnitt mit subprocess
. Die check_call
Methode gibt entweder 0 für den Erfolg zurück oder löst eine Ausnahme aus. Auf diese Weise muss ich die Ausgabe von Ping nicht analysieren. Ich verwende shlex
, um die Befehlszeilenargumente zu teilen.
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."
-c
ist -n
vorhanden und die Logik bezüglich des Rückkehrcodes ist anders)
Lesen Sie einen Dateinamen, die Datei enthält die eine URL pro Zeile, wie folgt:
http://www.poolsaboveground.com/apache/hadoop/core/
http://mirrors.sonic.net/apache/hadoop/core/
Befehl verwenden:
python url.py urls.txt
Holen Sie sich das Ergebnis:
Round Trip Time: 253 ms - mirrors.sonic.net
Round Trip Time: 245 ms - www.globalish.com
Round Trip Time: 327 ms - www.poolsaboveground.com
Quellcode (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)
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"
Wenn Sie etwas in Python wollen, mit dem Sie spielen können, schauen Sie sich Scapy an:
from scapy.all import *
request = IP(dst="www.google.com")/ICMP()
answer = sr1(request)
Das ist meiner Meinung nach viel besser (und vollständig plattformübergreifend) als einige funky Subprozessaufrufe. Sie können auch so viele Informationen über die Antwort (Sequenz-ID .....) haben, wie Sie möchten, wie Sie das Paket selbst haben.
Eine aktualisierte Version des genannten Skripts, das sowohl unter Windows als auch unter Linux funktioniert, finden Sie hier
Verwenden des System-Ping-Befehls zum Pingen einer Liste von Hosts:
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)
p = Popen('ping -n 1 ' + self.host, stdout=PIPE)
Sollte sein p = Popen(['ping','-n','1','self.host'], stdout=PIPE)
Verwenden Sie dies, es wurde unter Python 2.7 getestet und funktioniert einwandfrei. Bei Erfolg wird die Ping-Zeit in Millisekunden zurückgegeben und bei Fehlschlag False zurückgegeben.
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
command
eine Zeichenfolge, die alle Argumente anstelle einer Liste enthält, unter command not found
Linux die vollständige Zeichenfolge auslöst .
Verwenden des Unterprozess-Ping-Befehls zum Ping-Dekodieren, da die Antwort binär ist:
import subprocess
ping_response = subprocess.Popen(["ping", "-a", "google.com"], stdout=subprocess.PIPE).stdout.read()
result = ping_response.decode('utf-8')
print(result)