用Python ping一个站点?

时间:2008-11-25 09:58:37

标签: python network-programming ping

基本代码是:

from Tkinter import *
import os,sys

ana= Tk()
def ping1():
    os.system('ping')

a=Button(pen)
ip=("192.168.0.1")

a.config(text="PING",bg="white",fg="blue")
a=ping1.ip ??? 
a.pack()

ana.mainloop()

我如何ping网站或地址?

18 个答案:

答案 0 :(得分:78)

pure Python pingMatthew Dixon CowlesJens Diemer。另外,请记住Python需要root才能在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_pingPing.do的实现以获取灵感。

答案 1 :(得分:40)

根据您想要获得的内容,您可能最容易调用系统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

您无需担心shell转义字符。例如..

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的版本)而异。这不是理想的,但它可以在许多情况下正常工作(你知道脚本将运行的机器)

答案 2 :(得分:39)

您可以找到Noah Gift's演示文稿Creating Agile Commandline Tools With Python。在其中,他结合了子进程,队列和线程来开发能够同时ping主机并加快进程的解决方案。下面是他添加命令行解析和其他一些功能之前的基本版本。可以找到此版本和其他代码的代码here

#!/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

答案 3 :(得分:9)

很难说出你的问题是什么,但也有其他选择。

如果您希望使用ICMP ping协议逐字执行请求,则可以获取ICMP库并直接执行ping请求。 Google“Python ICMP”可以找到类似icmplib之类的内容。您可能还想查看scapy

这比使用os.system("ping " + ip )要快得多。

如果您的意思是通常“ping”一个框以查看它是否已启动,则可以在端口7上使用echo协议。

对于echo,您使用socket库打开IP地址和端口7.您在该端口上写一些内容,发送回车符("\r\n"),然后阅读回复。

如果您要“ping”某个网站以查看该网站是否正在运行,则必须在端口80上使用http协议。

对于或正确检查网络服务器,您使用urllib2打开特定网址。 (/index.html总是受欢迎)并阅读回复。

“ping”还有更多潜在的意义,包括“traceroute”和“finger”。

答案 4 :(得分: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()

答案 5 :(得分: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."

答案 6 :(得分: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)

答案 7 :(得分:2)

您可以找到适用于Windows和Linux here

的上述脚本的更新版本

答案 8 :(得分:2)

如果您需要在Python中执行更复杂,更详细的实现而不是仅仅调用ping,请查看Jeremy Hylton's code

答案 9 :(得分:2)

最简单的答案是:

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

答案 10 :(得分:1)

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"

答案 11 :(得分:1)

如果您想真正用Python玩一些东西,可以看看Scapy:

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

在我看来,这比某些时髦的子流程调用要好得多(并且完全跨平台)。另外,您也可以根据自己的需求获得尽可能多的关于答案的信息(序列ID .....)。

答案 12 :(得分: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)

答案 13 :(得分:0)

我使用Lars Strand的ping模块。谷歌的“Lars Strand python ping”你会发现很多参考资料。

答案 14 :(得分:0)

使用它在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

答案 15 :(得分: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)

答案 16 :(得分:0)

您可以尝试使用套接字获取该站点的ip,然后使用scrapy将icmp ping发送到该ip。

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

答案 17 :(得分:-1)

我开发了一个我认为可以帮助您的图书馆。它称为icmplib(与Internet上其他任何同名代码无关),是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

希望您会发现此库有用。请不要犹豫,将您在GitHub上的评论,改进建议或使用过程中遇到的任何问题发送给我。