94 votes

Ping d'un site en Python ?

Comment faire un ping sur un site web ou une adresse IP avec Python ?

3 votes

Veuillez définir le terme "ping". Voulez-vous dire utiliser le protocole ICMP ping, ou voir si un serveur web fonctionne ? Ou quelque chose d'autre ?

0 votes

Cela s'est avéré plus utile pour un problème que je résolvais : stackoverflow.com/questions/3764291/checking-network-connection

1 votes

Voici l'implémentation de python pur : falatic.com/index.php/39/pinging-with-python

85voto

orip Points 28225

Voir ceci ping en Python pur par Matthew Dixon Cowles y Jens Diemer . N'oubliez pas non plus que Python nécessite Root pour lancer des sockets ICMP (c'est-à-dire ping) sous 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

Le code source lui-même est facile à lire, voir les implémentations de verbose_ping et de Ping.do pour l'inspiration.

4 votes

ping utilise time.clock qui ne donne rien d'utile sur ma boîte Linux. timeit.default_timer (il est égal à time.time sur ma machine) fonctionne. time.clock -> timeit.default_timer gist.github.com/255009

0 votes

@Vinicius - merci ! Mis à jour avec le nouvel emplacement sur github. Il semble qu'il soit constamment maintenu, aussi !

3 votes

Ping n'a pas de méthode appelée do_one. Je n'ai pas trouvé de moyen simple pour obtenir le temps de ping.

47voto

dbr Points 66401

En fonction de ce que vous voulez réaliser, le plus simple est probablement d'appeler la commande ping du système

L'utilisation du module de sous-processus est la meilleure façon de procéder, même si vous devez vous rappeler que la commande ping est différente sur les différents systèmes d'exploitation !

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

Vous n'avez pas à vous soucier des caractères d'échappement de l'interpréteur de commandes. Par exemple

host = "google.com; `echo test`

no exécuter la commande echo.

Maintenant, pour obtenir les résultats du ping, vous pouvez analyser les données suivantes out variable. Exemple de sortie :

round-trip min/avg/max/stddev = 248.139/249.474/250.530/0.896 ms

Exemple de regex :

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

Encore une fois, n'oubliez pas que le résultat variera en fonction du système d'exploitation (et même de la version de l'outil de gestion de l'information). ping ). Ce n'est pas idéal, mais cela fonctionnera bien dans de nombreuses situations (où vous connaissez les machines sur lesquelles le script sera exécuté).

0 votes

J'ai découvert que je devais modifier votre expression de correspondance regex comme le out contient des données codées \n qui semblent interférer avec la correspondance : matcher = re.compile("\nround-trip min/avg/max/stddev = (\d+.\d+)/(\d+.\d+)/(\d+.\d+)/(\d+.\d+)")

0 votes

0 votes

Sous Windows, vous devez utiliser -n au lieu de -c . ( Voir la réponse de ePi272314 )

40voto

Ryan Cox Points 3397

Vous pouvez trouver Cadeau de Noah présentation Création d'outils en ligne de commande agiles avec Python . Il y combine les sous-processus, les files d'attente et le threading pour développer une solution capable d'envoyer des messages à des hôtes simultanément et d'accélérer le processus. Vous trouverez ci-dessous une version de base avant qu'il n'ajoute l'analyse de la ligne de commande et d'autres fonctionnalités. Le code de cette version et des autres se trouve à l'adresse suivante ici

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

Il est également l'auteur de : Python pour l'administration système Unix et Linux

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

4 votes

Je ne sais pas si cela répond vraiment à la question, mais c'est une information très utile !

0 votes

Je sais que ça vient de PyCon... mais c'est plutôt mauvais. Faire des appels système est une perte de temps et de ressources, tout en étant incroyablement dépendant du système, et difficile à analyser. Vous devriez plutôt opter pour une méthode utilisant Python pour envoyer/recevoir des requêtes ICMP, comme il y en a d'autres sur ce fil.

10voto

S.Lott Points 207588

Il est difficile de dire quelle est votre question, mais il existe quelques alternatives.

Si vous voulez littéralement exécuter une requête en utilisant le protocole ping ICMP, vous pouvez obtenir une bibliothèque ICMP et exécuter directement la requête ping. Cherchez sur Google "Python ICMP" pour trouver des choses comme ceci icmplib . Vous pouvez consulter scapy aussi.

Cela sera beaucoup plus rapide que d'utiliser os.system("ping " + ip ) .

Si vous voulez faire un "ping" générique d'une boîte pour voir si elle est en service, vous pouvez utiliser le protocole écho sur le port 7.

Pour l'écho, vous utilisez l'option prise de courant pour ouvrir l'adresse IP et le port 7. Vous écrivez quelque chose sur ce port, envoyez un retour chariot ( "\r\n" ) et ensuite lire la réponse.

Si vous voulez faire un "ping" à un site web pour voir s'il fonctionne, vous devez utiliser le protocole http sur le port 80.

Pour ou vérifier correctement un serveur web, vous utilisez urllib2 pour ouvrir une URL spécifique. ( /index.html est toujours populaire) et lisez la réponse.

Il existe encore d'autres significations possibles de "ping", notamment "traceroute" et "finger".

5 votes

Echo était autrefois très répandu mais il est désormais désactivé par défaut sur la plupart des systèmes. Ce n'est donc pas un moyen pratique de tester si la machine fonctionne bien.

8voto

Harald Schilly Points 750

J'ai fait quelque chose de similaire de cette façon, en guise d'inspiration :

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 votes

Heureux que vous soyez resté loin des bibliothèques externes et subprocess

0 votes

Et s'il n'y a pas d'index.html ?

4 votes

Plus important encore, que se passe-t-il s'il n'y a pas de serveur web ?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X