Pythonでサイトにpingを実行しますか?


80

PythonでWebサイトまたはIPアドレスにpingを実行するにはどうすればよいですか?


2
「ping」を定義してください。ICMP pingプロトコルを使用するつもりですか、それともWebサーバーが実行されているかどうかを確認するつもりですか?または、他の何か?
S.Lott 2008年

これは私が解決していた問題に対してより役立つことが
わかりました

1
これが純粋なPythonの実装です:falatic.com/index.php/39/ping-with-python
thinker007

回答:


82

Matthew DixonCowlesJensDiemerによるこの純粋な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インスピレーション。


4
pingtime.clockLinuxボックスで何も役に立たない使用。timeit.default_timertime.time私のマシンと同じです)動作します。time.clock-> timeit.default_timer gist.github.com/255009
jfs 2009

@ Vinicius-ありがとう!githubの新しい場所で更新されました。それも常に維持されているようです!
orip 2011

3
pingにはdo_oneというメソッドはありません。ping時間を取得する簡単な方法が見つかりませんでした。
ジョセフ・トゥリアン2011年

1
'run'は 'count'に名前が変更されました
2013

1
@ ChrisWithers'ping 'バイナリは、' setuid 'ビットを介してルートとして実行されます。superuser.com/a/1035983/4706
orip 2016

42

何を達成したいかにもよりますが、おそらく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+)")
Pierz


Windowsでは、の-n代わりにを使用する必要があります-c。(参照ePi272314の答え
Stevoisiak

39

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


4
これが実際に質問に答えているかどうかはわかりませんが、非常に役立つ情報です。
ig0774 2010年

私はそれがPyConから来ていることを知っています...しかしそれはかなり悪いです。システムコールの実行は時間とリソースの浪費ですが、システムに非常に依存し、解析が困難です。このスレッドには他にもあるので、Pythonを使用してICMP要求を送受信するメソッドを選択する必要があります。
Cukic0d

9

あなたの質問が何であるかを言うのは難しいですが、いくつかの選択肢があります。

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」にはさらに多くの潜在的な意味があります。


5
エコーはかつて普及していましたが、現在ではほとんどのシステムでデフォルトで無効になっています。したがって、マシンが正常に動作するかどうかをテストする実用的な方法ではありません。
bortzmeyer 2008年

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 2012

index.htmlがない場合はどうなりますか?
sbose 2013

4
さらに重要なのは、Webサーバーがない場合はどうなるでしょうか。
キム・Gräsman

確かに、それを連結する必要はありません/index.html; と呼ばれるドキュメントが実際に存在するサイトでindex.htmlは、サーバールートにあります。代わりに、あなたはしたい先頭に追加 http://またはhttps://ホストへ
アンティHaapala

これは実際にはTCPポート80の「ping」+ HTTPテストほどのICMPpingではありませんが、実際にはコンテンツを受信しないため、HEAD(またはOPTIONS)要求を実行する方がよいでしょう。影響が少ない。もっとスペアが必要な場合は、ホストに対してTCP 80ソケットを開いて、すぐに閉じてみてください。
ニック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
警告:Windows上の作業は(しない-c-nそこに、戻りコードについてのロジックが異なる)
WIM

3

ファイル名を読み取ると、ファイルには次のように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)

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

私はあなたを助けることができると思うライブラリを開発します。これはicmplib(インターネット上にある同じ名前の他のコードとは無関係)と呼ばれ、PythonでのICMPプロトコルの純粋な実装です。

これは完全にオブジェクト指向であり、従来のping、multiping、tracerouteなどの単純な機能に加えて、ICMPプロトコルに基づいてアプリケーションを開発したい人のための低レベルのクラスとソケットを備えています。

その他のハイライトは次のとおりです。

  • root権限なしで実行できます。
  • 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')

root権限なしでライブラリを使用する場合は、「privileged」パラメータをFalseに設定します。

完全なドキュメントはプロジェクトページにあります:https//github.com/ValentinBELYN/icmplib

このライブラリがお役に立てば幸いです。


2
モデレーターのメモ:この回答は、自己宣伝の要件に従っており、一方的なものではなく(質問は、pingを使用するためのPythonソリューションを求めています)、用語の定義によるスパムではありません
MartijnPieters

0

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)

6
キックと笑いのためだけにwww.this_one_wont_work.comを登録します。
マシュースカウテン

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を取得し、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])

-1

これを使用すると、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

1
Python3.6では失敗します。ModuleNotFoundError: 'subproccess'という名前のないモジュール
Stevoisiak

またcommand、リストではなくすべての引数を含む文字列であるため失敗しcommand not found、Linuxでは完全な文字列がトリガーされます。
arielf
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.