用 Python 来 Ping 一个网站?

2024-12-30 08:41:00
admin
原创
50
摘要:问题描述:如何使用 Python ping 网站或 IP 地址?解决方案 1:请参阅Matthew Dixon Cowles和Jens Diemer编写的纯 Python ping。另外,请记住,Python 需要 root 才能在 Linux 中生成 ICMP(即 ping)套接字。import ping,...

问题描述:

如何使用 Python ping 网站或 IP 地址?


解决方案 1:

请参阅Matthew Dixon Cowles和Jens Diemer编写的纯 Python ping。另外,请记住,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_ping和的实现Ping.do可以获得启发。

解决方案 2:

根据您想要实现的目标,最简单的方法可能是调用系统 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)而有所不同。这不是最理想的,但在许多情况下(您知道脚本将在哪些机器上运行)都可以正常工作。

解决方案 3:

您可以找到Noah Gift 的演示文稿 《使用 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 和 Linux System Administration

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

解决方案 4:

很难说你的问题是什么,但是还有一些其他选择。

如果您的意思是使用 ICMP ping 协议执行请求,您可以获取 ICMP 库并直接执行 ping 请求。Google 搜索“Python ICMP”以查找类似icmplib 的内容。您可能还想看看scapy。

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

如果您的意思是一般地“ping”一个盒子来查看它是否启动,您可以在端口 7 上使用 echo 协议。

对于回显,您使用套接字库打开 IP 地址和端口 7。您在该端口上写入一些内容,发送回车符 ( `"
"`),然后读取答复。

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

为了正确检查 Web 服务器,您可以使用urllib2打开特定的 URL。(/index.html一直很受欢迎)并读取响应。

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

解决方案 5:

最简单的答案是:

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

解决方案 6:

我做了一些类似的事情,以此获得启发:

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

解决方案 7:

以下是使用 的简短代码片段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."

解决方案 8:

我开发了一个库,我认为它能帮到你。它叫做 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

希望您发现这个图书馆很有用。

解决方案 9:

读取一个文件名,该文件每行包含一个 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)

解决方案 10:

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:

如果你想要一些实际用 Python 编写的、可以玩的东西,可以看看 Scapy:

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

在我看来,这比一些古怪的子进程调用要好得多(而且完全跨平台)。此外,您可以获得尽可能多的有关答案的信息(序列 ID......),就像您拥有数据包本身一样。

解决方案 12:

在 python 3 上,您可以使用ping3。

from ping3 import ping, verbose_ping
ip-host = '8.8.8.8'
if not ping(ip-host):
    raise ValueError('{} is not available.'.format(ip-host))

解决方案 13:

使用系统 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)

解决方案 14:

您可以在此处找到适用于 Windows 和 Linux 的上述脚本的更新版本

解决方案 15:

使用子进程 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:

您可以尝试使用套接字来获取站点的 ip,然后使用 scrapy 对该 ip 执行 icmp ping。

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, '
')
    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:

如果您只想检查某个 IP 上的机器是否处于活动状态,那么使用 python 套接字即可。

import socket
s = socket.socket()
try:
    s.connect(("192.168.1.123", 1234)) # You can use any port number here
except Exception as e:
    print(e.errno, e)

现在,根据显示的错误信息(或错误编号),您可以确定机器是否处于活动状态。

解决方案 18:

使用它在 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
相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1006  
  华为作为全球领先的科技公司,其成功的关键之一在于其高效的研发管理体系——集成产品开发(IPD)。IPD不仅仅是一套流程工具,更是一种团队协作与文化融合的实践体系。通过IPD,华为将跨部门的资源、能力和智慧有效整合,实现了从产品概念到市场交付的全流程高效运作。IPD的核心在于打破传统职能部门的壁垒,强调团队协作与文化的深...
IPD集成产品开发流程   0  
  创新是企业持续发展的核心驱动力,而集成产品开发(IPD, Integrated Product Development)作为一种先进的管理方法,能够帮助企业实现从产品概念到市场落地的全流程优化。通过系统化的流程设计和跨职能团队的协同合作,IPD不仅能够提升开发效率,还能显著降低风险,确保产品在市场上具备竞争力。许多企业...
华为IPD流程   0  
  在快速变化的市场中,企业面临着缩短产品上市时间的巨大压力。消费者需求的多样化和技术的迅猛发展,使得产品生命周期日益缩短。企业必须更快地推出新产品,以抢占市场先机并满足客户期望。然而,传统的产品开发流程往往效率低下,难以应对这种挑战。集成产品开发(IPD)流程作为一种系统化的产品开发方法,能够帮助企业在确保质量的同时,显...
IPD培训课程   0  
  研发IPD(Integrated Product Development,集成产品开发)流程是企业实现高效产品开发的核心方法论之一。它通过跨部门协作、并行工程和结构化流程,确保产品从概念到市场的高效交付。然而,在IPD流程中,绩效评估与改进方法的设计与实施往往成为企业面临的重大挑战。由于研发活动的复杂性和不确定性,传统...
IPD流程分为几个阶段   0  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用