PythonでWebサイトまたはIPアドレスにpingを実行するにはどうすればよいですか?
PythonでWebサイトまたはIPアドレスにpingを実行するにはどうすればよいですか?
回答:
Matthew DixonCowlesとJensDiemerによるこの純粋なPythonpingを参照してください。また、PythonはLinuxでICMP(つまりping)ソケットを生成するためにrootを必要とすることを忘れないでください。
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
インスピレーション。
ping
time.clock
Linuxボックスで何も役に立たない使用。timeit.default_timer
(time.time
私のマシンと同じです)動作します。time.clock
-> timeit.default_timer
gist.github.com/255009
何を達成したいかにもよりますが、おそらくsystempingコマンドを呼び出すのが最も簡単です。
サブプロセスモジュールを使用するのがこれを行うための最良の方法ですが、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+)")
NoahGiftのプレゼンテーション 「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 forUnixおよびLinuxシステム管理
http://ecx.images-amazon.com/images/I/515qmR%2B4sjL._SL500_AA240_.jpg
あなたの質問が何であるかを言うのは難しいですが、いくつかの選択肢があります。
ICMP pingプロトコルを使用して文字通り要求を実行する場合は、ICMPライブラリを取得して、ping要求を直接実行できます。このicmplibのようなものを見つけるためのグーグル「PythonICMP」。scapyも見てみたいと思うかもしれません。
これは、を使用するよりもはるかに高速になりos.system("ping " + ip )
ます。
ボックスを一般的に「ping」して起動しているかどうかを確認する場合は、ポート7でエコープロトコルを使用できます。
エコーの場合は、ソケットライブラリを使用してIPアドレスとポート7を開きます。そのポートに何かを書き込み、キャリッジリターン("\r\n"
)を送信してから、応答を読み取ります。
Webサイトを「ping」してサイトが実行されているかどうかを確認する場合は、ポート80でhttpプロトコルを使用する必要があります。
Webサーバーを適切にチェックするには、urllib2を使用して特定のURLを開きます。(/index.html
常に人気があります)そして応答を読んでください。
「traceroute」や「finger」など、「ping」にはさらに多くの潜在的な意味があります。
インスピレーションとして、私はこのように似たようなことをしました:
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
; と呼ばれるドキュメントが実際に存在するサイトでindex.html
は、サーバールートにあります。代わりに、あなたはしたい先頭に追加 http://
またはhttps://
ホストへ
これは、を使用した短いスニペット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."
-c
で-n
そこに、戻りコードについてのロジックが異なる)
ファイル名を読み取ると、ファイルには次のように1行に1つの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)
WindowsとLinuxの両方で動作する前述のスクリプトの更新バージョンはここにあります
私はあなたを助けることができると思うライブラリを開発します。これはicmplib(インターネット上にある同じ名前の他のコードとは無関係)と呼ばれ、PythonでのICMPプロトコルの純粋な実装です。
これは完全にオブジェクト指向であり、従来のping、multiping、tracerouteなどの単純な機能に加えて、ICMPプロトコルに基づいてアプリケーションを開発したい人のための低レベルのクラスとソケットを備えています。
その他のハイライトは次のとおりです。
それをインストールするには(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')
root権限なしでライブラリを使用する場合は、「privileged」パラメータをFalseに設定します。
完全なドキュメントはプロジェクトページにあります:https: //github.com/ValentinBELYN/icmplib
このライブラリがお役に立てば幸いです。
system 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)
p = Popen('ping -n 1 ' + self.host, stdout=PIPE)
あるべき p = Popen(['ping','-n','1','self.host'], stdout=PIPE)
応答がバイナリであるため、サブプロセス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)
ソケットを使用してサイトのIPを取得し、scrapyを使用してIPへのicmppingを実行することができます。
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])
これを使用すると、Python 2.7でテストされ、正常に動作し、成功した場合はミリ秒単位でping時間を返し、失敗した場合は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
command
、リストではなくすべての引数を含む文字列であるため失敗しcommand not found
、Linuxでは完全な文字列がトリガーされます。