Пинговать сайт в Python?

Основной код:

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

Как я могу пинговать сайты или адреса?

20 ответов

Посмотрите на этот чистый пинг Питона Мэтью Диксоном Коулзом и Дженсом Димером. Также помните, что Python требует root для порождения ICMP-сокетов (т.е. ping) в Linux.

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 различна в разных операционных системах!

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.

Теперь, чтобы на самом деле получить результаты пинга, вы можете разобрать 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). Это не идеально, но во многих ситуациях будет работать нормально (если вы знаете, на каких машинах будет работать скрипт)

Вы можете найти презентацию Noah Gift Создание гибких инструментов командной строки с помощью Python. В нем он объединяет подпроцесс, очередь и многопоточность для разработки решения, способного одновременно пинговать хосты и ускорять процесс. Ниже приведена базовая версия, прежде чем он добавит синтаксический анализ командной строки и некоторые другие функции. Код этой версии и другие можно найти здесь

#!/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 для системного администрирования Unix и Linux

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

Трудно сказать, каков твой вопрос, но есть несколько альтернатив.

Если вы хотите буквально выполнить запрос, используя протокол ping ICMP, вы можете получить библиотеку ICMP и выполнить запрос ping напрямую. Google "Python ICMP", чтобы найти такие вещи, как этот icmplib. Возможно, вы захотите взглянуть и на Скапы.

Это будет намного быстрее, чем при использовании os.system("ping " + ip ),

Если вы хотите в общем "пинговать" окно, чтобы проверить, работает ли оно, вы можете использовать протокол эха на порту 7.

Для эха вы используете библиотеку сокетов, чтобы открыть IP-адрес и порт 7. Вы пишете что-то на этот порт, отправляете возврат каретки ("\r\n") и затем прочитайте ответ.

Если вы хотите "пропинговать" веб-сайт, чтобы узнать, работает ли этот сайт, вы должны использовать протокол http на порту 80.

Для правильной проверки веб-сервера вы используете urllib2, чтобы открыть определенный URL. (/index.html всегда популярен) и читайте ответ.

Есть еще более потенциальное значение слова "пинг", включая "traceroute" и "палец".

Самый простой ответ:

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

Я сделал что-то подобное в качестве вдохновения:

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, 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."

Я разрабатываю библиотеку, которая, как мне кажется, может вам помочь. Он называется icmplib (не связан с каким-либо другим кодом с таким же именем, который можно найти в Интернете) и представляет собой чистую реализацию протокола ICMP на Python.

Он полностью объектно-ориентирован и имеет простые функции, такие как классический ping, multiping и traceroute, а также низкоуровневые классы и сокеты для тех, кто хочет разрабатывать приложения на основе протокола ICMP.

Вот еще несколько интересных моментов:

  • Может работать без root-прав.
  • Вы можете настроить многие параметры, такие как полезная нагрузка пакетов ICMP и класс трафика (QoS).
  • Кроссплатформенность: протестировано на Linux, macOS и Windows.
  • Быстро и требует мало ресурсов ЦП / ОЗУ, в отличие от вызовов, выполняемых с помощью подпроцесса.
  • Легкий и не требует дополнительных зависимостей.

Чтобы установить его (требуется 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')

Установите для параметра "привилегированный" значение False, если вы хотите использовать библиотеку без привилегий root.

Вы можете найти полную документацию на странице проекта:https://github.com/ValentinBELYN/icmplib

Надеюсь, вы найдете эту библиотеку полезной. Не стесняйтесь присылать мне свои комментарии к GitHub, предложения по его улучшению или любые проблемы, с которыми вы столкнетесь при его использовании.

Прочитайте имя файла, файл содержит один 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 здесь

На 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))
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"

If you want something actually in Python, that you can play with, have a look at Scapy:

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

That's in my opinion much better (and fully cross-platform), than some funky subprocess calls. Also you can have as much information about the answer (sequence ID.....) as you want, as you have the packet itself.

Взгляните на код Джереми Хилтона, если вам нужно сделать более сложную, детальную реализацию в Python, а не просто вызывать ping,

вы можете попробовать сокет, чтобы получить IP-адрес сайта, и использовать scrapy для выполнения ICMP-пинга по 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])

Если вы хотите только проверить, активна ли машина на 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)

Теперь по отображаемому сообщению об ошибке (или номеру ошибки) можно определить, активна машина или нет.

Используя команду subprocess 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)

Используя команду 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)

Я использую модуль ping от Lars Strand. Google для "Lars Strand Python Ping", и вы найдете много ссылок.

Используйте это, он протестирован на python 2.7 и работает нормально, он возвращает время пинга в миллисекундах, если успех, и возвращает 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
Другие вопросы по тегам