web-dev-qa-db-fra.com

Ping un site en Python?

Le code de base est:

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

Comment pourrais-je cingler un site ou une adresse?

69
user40572

Voir cette pure Python ping par Matthew Dixon Cowles et Jens Diemer . Rappelez-vous également que Python a besoin de root pour générer des sockets ICMP (c.-à-d. 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.

78
orip

Selon ce que vous souhaitez réaliser, vous êtes probablement le plus facile à appeler la commande ping système.

Le meilleur moyen de le faire est d'utiliser le module de sous-processus, même si vous devez vous rappeler que la commande ping est différente sur 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 Shell. Par exemple..

Host = "google.com; `echo test`

..will not exécute la commande echo.

Maintenant, pour obtenir les résultats du ping, vous pouvez analyser la variable out. 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, rappelez-vous que la sortie variera en fonction du système d'exploitation (et même de la version de ping). Ce n'est pas idéal, mais cela fonctionnera bien dans de nombreuses situations (où vous connaissez les machines sur lesquelles le script s'exécutera)

40
dbr

Vous pouvez trouver Noah Gift's presentation Création d'outils de ligne de commande agiles avec Python . Il y associe des sous-processus, une file d’attente et des threads pour développer une solution capable d’envoyer des requêtes ping simultanément aux hôtes et d’accélérer le processus. Vous trouverez ci-dessous une version de base avant d'ajouter l'analyse en ligne de commande et certaines autres fonctionnalités. Le code de cette version et d’autres peuvent être trouvés 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 auteur de: Administration système Python pour Unix et Linux

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

39
Ryan Cox

Il est difficile de dire quelle est votre question, mais il existe des 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 la requête ping directement. Google "Python ICMP" pour trouver des choses comme ceci icmplib . Vous voudrez peut-être aussi regarder scapy .

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

Si vous voulez génériquement "cingler" une boîte pour voir si elle est active, vous pouvez utiliser le protocole echo sur le port 7.

Pour echo, utilisez la bibliothèque socket pour ouvrir l’adresse IP et le port 7. Vous écrivez quelque chose sur ce port, envoyez un retour chariot ("\r\n"), puis lisez la réponse.

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

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

Il existe encore une signification potentielle de "ping", y compris "traceroute" et "doigt".

10
S.Lott

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

Voici un court extrait utilisant subprocess. La méthode check_call renvoie 0 en cas de succès ou déclenche une exception. De cette façon, je n'ai pas à analyser la sortie de ping. J'utilise shlex pour scinder les arguments de la ligne de commande.

  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
Moondoggy

lire un nom de fichier, le fichier contient une seule URL par ligne, comme ceci:

http://www.poolsaboveground.com/Apache/hadoop/core/
http://mirrors.sonic.net/Apache/hadoop/core/

utiliser la commande:

python url.py urls.txt

obtenir le résultat:

Round Trip Time: 253 ms - mirrors.sonic.net
Round Trip Time: 245 ms - www.globalish.com
Round Trip Time: 327 ms - www.poolsaboveground.com

code source (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 __== '__main__':
    with open(sys.argv[1]) as f:
        content = f.readlines() 
    Pinger(content)
3
hustljian

Jetez un coup d'œil à le code de Jeremy Hylton , si vous avez besoin d'une implémentation plus complexe et détaillée en Python plutôt que d'appeler simplement ping.

2
Brent.Longborough

Vous pouvez trouver une version mise à jour du script mentionné qui fonctionne à la fois sous Windows et Linux ici

2
Born To Ride
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"
1
Ibrahim Kasim

Si vous voulez quelque chose de réellement en Python, avec lequel vous pouvez jouer, jetez un œil à Scapy:

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

À mon avis, c'est beaucoup mieux (et totalement multi-plateforme) que certains appels de sous-processus géniaux. Vous pouvez aussi avoir autant d’informations sur la réponse (ID de séquence .....) que vous le souhaitez, tout comme le paquet lui-même.

1
Cukic0d

J'utilise le module ping de Lars Strand. Google pour "Lars Strand python ping" et vous trouverez beaucoup de références.

0
akr

Utilisez ceci, il est testé sur Python 2.7 et fonctionne correctement. Il renvoie le temps de ping en millisecondes en cas de succès et renvoie False en cas d'échec.

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
0
MSS

utilisation de la commande ping système pour effectuer un ping sur une liste d'hôtes

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 __== '__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)
0
Corey Goldberg