पायथन में एक साइट पिंग?


80

मैं पायथन के साथ एक वेबसाइट या आईपी पते को कैसे पिंग करूं?


2
कृपया "पिंग" को परिभाषित करें। क्या आपका मतलब ICMP पिंग प्रोटोकॉल का उपयोग करना है या यह देखना है कि कोई वेब सर्वर चल रहा है? या कुछ और?
S.Lott

यह मेरे द्वारा
jedierikb

1
यहाँ शुद्ध अजगर का कार्यान्वयन है: falatic.com/index.php/39/pinging-with-python
विचारक

जवाबों:


82

मैथ्यू डिक्सन काउल और जेन्स डायमर द्वारा इस शुद्ध अजगर पिंग को देखें । इसके अलावा, याद रखें कि पायथन को रूट को लिनक्स में ICMP (यानी पिंग) सॉकेट की आवश्यकता होती है।

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लिए के कार्यान्वयन को देखें ।


4
pingtime.clockमेरे लिनक्स बॉक्स पर उपयोगी कुछ भी नहीं देता है कि उपयोग करता है। timeit.default_timer(यह time.timeमेरी मशीन पर बराबर है ) काम करता है। time.clock-> timeit.default_timer gist.github.com/255009
jfs

@Vicicius - धन्यवाद! Github पर नए स्थान के साथ अपडेट किया गया। लगता है जैसे यह लगातार बनाए रखा है, भी!
orip

3
पिंग में do_one नामक कोई विधि नहीं है। मुझे पिंग टाइम पाने का सरल तरीका नहीं मिला।
जोसेफ टुरियन

1
'रन' 'गिनती' के लिए नाम दिया गया है
pferate

1
@ क्रिस 'बिटकॉइन' बिट के माध्यम से रूट के रूप में 'पिंग' बाइनरी चलाता है। superuser.com/a/1035983/4706
orip

42

आप क्या हासिल करना चाहते हैं इसके आधार पर, आप शायद सिस्टम पिंग कमांड को कॉल करना सबसे आसान है।

सबप्रोसेस मॉड्यूल का उपयोग करना ऐसा करने का सबसे अच्छा तरीका है, हालाँकि आपको याद रखना होगा कि पिंग कमांड अलग-अलग ऑपरेटिंग सिस्टम पर अलग है!

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`

.. इको कमांड निष्पादित नहीं करेंगे ।

अब, वास्तव में पिंग परिणाम प्राप्त करने के लिए, आप 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) के आधार पर आउटपुट अलग-अलग होगा । यह आदर्श नहीं है, लेकिन यह कई स्थितियों में ठीक काम करेगा (जहां आप जानते हैं कि मशीनों को स्क्रिप्ट चालू होगी)


मैंने पाया कि मुझे आपके रेगेक्स मैच के एक्सप्रेशन को ट्विक करना होगा क्योंकि outइसमें एन्कोडेड \ n है जो मेल के साथ हस्तक्षेप करता है:matcher = re.compile("\nround-trip min/avg/max/stddev = (\d+.\d+)/(\d+.\d+)/(\d+.\d+)/(\d+.\d+)")
पियर डेस

@ पियरज़: रेगेक्स को बदले बिना केवल उपयोग करेंmatcher.search
jfs

विंडोज पर, आपको -nइसके बजाय उपयोग करना चाहिए -c। ( EPi272314 का उत्तर देखें )
स्टीवोसीक

39

आपको पायथन के साथ नोहा गिफ्ट की प्रस्तुति क्रिएटिंग एजाइल कमांडलाइन टूल्स मिल सकती है । इसमें वह सबप्रोसेस, क्यू और थ्रेडिंग को जोड़ता है ताकि समाधान विकसित किया जा सके जो मेजबानों को समतल करने और प्रक्रिया को गति देने में सक्षम हो। कमांड लाइन पार्सिंग और कुछ अन्य विशेषताओं को जोड़ने से पहले नीचे एक मूल संस्करण दिया गया है। इस संस्करण का कोड और अन्य यहां पाया जा सकता है

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

वह भी लेखक हैं: यूनिक्स और लिनक्स सिस्टम प्रशासन के लिए पायथन

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


4
नहीं जानते कि यह वास्तव में सवाल का जवाब देता है, लेकिन यह बहुत उपयोगी जानकारी है!
ig0774

मुझे पता है कि यह PyCon से आता है ... लेकिन यह बहुत बुरा है। सिस्टम कॉल को निष्पादित करना समय और संसाधन की बर्बादी है, जबकि अविश्वसनीय रूप से सिस्टम-निर्भर और पार्स करने के लिए कठिन है। आपको ICMP अनुरोध भेजने / प्राप्त करने के लिए अजगर का उपयोग करने की विधि का विकल्प चुनना चाहिए, क्योंकि इस धागे पर अन्य भी हैं।
क्यूसिक

9

यह कहना कठिन है कि आपका प्रश्न क्या है, लेकिन कुछ विकल्प हैं।

यदि आप आईसीएमपी पिंग प्रोटोकॉल का उपयोग करके शाब्दिक रूप से अनुरोध को निष्पादित करने का मतलब रखते हैं, तो आप आईसीएमपी पुस्तकालय प्राप्त कर सकते हैं और सीधे पिंग अनुरोध को निष्पादित कर सकते हैं। Google "पायथन ICMP" इस icmplib जैसी चीजों को खोजने के लिए । आप scapy को भी देखना चाह सकते हैं ।

यह उपयोग करने की तुलना में बहुत तेज होगा os.system("ping " + ip )

यदि आप उदारतापूर्वक "पिंग" बॉक्स से मतलब रखते हैं, तो यह देखने के लिए कि आप पोर्ट 7 पर इको प्रोटोकॉल का उपयोग कर सकते हैं।

इको के लिए, आप आईपी ​​पते और पोर्ट को खोलने के लिए सॉकेट लाइब्रेरी का उपयोग करते हैं । 7. आप उस पोर्ट पर कुछ लिखते हैं, एक गाड़ी वापसी ( "\r\n") भेजते हैं और फिर उत्तर पढ़ते हैं।

यदि आप एक वेब साइट को "पिंग" करने का मतलब देखते हैं कि साइट चल रही है, तो आपको पोर्ट 80 पर http प्रोटोकॉल का उपयोग करना होगा।

वेब सर्वर की ठीक से जाँच करने के लिए , आप एक विशिष्ट URL खोलने के लिए urllib2 का उपयोग करते हैं । (/index.html हमेशा लोकप्रिय है) और प्रतिक्रिया पढ़ें।

अभी भी "ट्रेसरआउट" और "उंगली" सहित "पिंग" के अधिक संभावित अर्थ हैं।


5
गूंज कभी व्यापक थी लेकिन अब यह अधिकांश प्रणालियों पर डिफ़ॉल्ट रूप से अक्षम हो गई है। इसलिए, यह परीक्षण करने का व्यावहारिक तरीका नहीं है कि मशीन ठीक चलती है या नहीं।
bortzmeyer

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

1
खुशी है कि तुम बाहरी पुस्तकालयों और से दूर रहने लगाsubprocess
tshepang

अगर कोई index.html नहीं है तो क्या होगा?
sbose

4
इससे भी महत्वपूर्ण बात, अगर कोई वेब सर्वर नहीं है तो क्या होगा?
किम ग्रासमैन

वास्तव में, इस बात को समझने की कोई आवश्यकता नहीं है /index.html; किसी भी साइट में जहां वास्तव में एक दस्तावेज होगा जिसे कहा जाता है index.html, यह सर्वर रूट में वहीं होगा। इसके बजाय आप प्रीपेंड http:// या https://होस्ट करने के लिए
कहेंगे

हालांकि यह वास्तव में एक ICMP पिंग नहीं है, जो TCP पोर्ट 80 "पिंग" + HTTP टेस्ट के रूप में है, तो संभवतः HEAD (या विकल्प) अनुरोध करना बेहतर होगा क्योंकि आप वास्तव में कोई सामग्री प्राप्त नहीं करेंगे, इसलिए बैंडविड्थ होगा इसे कम प्रभावित करें। यदि आप कुछ और अतिरिक्त चाहते हैं, तो आप केवल मेजबान के लिए एक टीसीपी 80 सॉकेट खोलने की कोशिश कर सकते हैं और इसे तुरंत बंद कर सकते हैं।
निक टी

6

यहाँ एक छोटा सा स्निपेट का उपयोग किया गया है subprocesscheck_callविधि या तो सफलता के लिए 0 देता है, या एक अपवाद को जन्म देती है। इस तरह, मुझे पिंग के आउटपुट को पार्स नहीं करना है। मैं 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."

3
चेतावनी: करता खिड़कियां (पर काम नहीं -cहै -nवहाँ, और बदले कोड के बारे में तर्क अलग है)
विम

3

फ़ाइल का नाम पढ़ें, फ़ाइल में प्रति पंक्ति एक यूआरएल शामिल है, जैसे:

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)


2

यदि आप वास्तव में पाइथन में कुछ चाहते हैं, जिसके साथ आप खेल सकते हैं, तो स्केपी पर एक नज़र डालें:

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

कुछ फंकी सबप्रोसेस कॉल की तुलना में यह मेरी राय में बहुत बेहतर (और पूरी तरह से क्रॉस-प्लेटफॉर्म) है। साथ ही आपको उत्तर के बारे में अधिक जानकारी हो सकती है (अनुक्रम आईडी .....) जैसा आप चाहते हैं, जैसा कि आपके पास पैकेट है।



1

आप उल्लेखित स्क्रिप्ट का एक अद्यतन संस्करण पा सकते हैं जो यहां विंडोज और लिनक्स दोनों पर काम करता है


जुड़ा हुआ कोड पायथन 3.8 पर विफल रहता है। "SyntaxError: अमान्य वाक्यविन्यास"
Stevoisiak

1

मैं एक पुस्तकालय विकसित करता हूं जो मुझे लगता है कि आपकी मदद कर सकता है। इसे icmplib कहा जाता है (उसी नाम के किसी भी अन्य कोड से संबंधित है जो इंटरनेट पर पाया जा सकता है) और पायथन में ICMP प्रोटोकॉल का शुद्ध कार्यान्वयन है।

यह पूरी तरह से ऑब्जेक्ट ओरिएंटेड है और इसमें सरल कार्य हैं जैसे कि क्लासिक पिंग, मल्टीपिंग और ट्रेसरआउट, साथ ही निम्न स्तर की कक्षाएं और उन लोगों के लिए सॉकेट जो आईसीएमपी प्रोटोकॉल के आधार पर एप्लिकेशन विकसित करना चाहते हैं।

यहाँ कुछ अन्य मुख्य बातें हैं:

  • बिना रूट विशेषाधिकार के चलाया जा सकता है।
  • आप ICMP पैकेट और ट्रैफ़िक क्लास (QoS) के पेलोड जैसे कई मापदंडों को अनुकूलित कर सकते हैं।
  • क्रॉस-प्लेटफॉर्म: लिनक्स, मैकओएस और विंडोज पर परीक्षण किया गया।
  • उपप्रकार के साथ किए गए कॉल के विपरीत फास्ट और कुछ सीपीयू / रैम संसाधनों की आवश्यकता है।
  • लाइटवेट और किसी भी अतिरिक्त निर्भरता पर निर्भर नहीं करता है।

इसे स्थापित करने के लिए (अजगर 3.6+ आवश्यक):

pip3 install icmplib

यहाँ पिंग फ़ंक्शन का एक सरल उदाहरण है:

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

यदि आप रूट विशेषाधिकार के बिना लाइब्रेरी का उपयोग करना चाहते हैं, तो "विशेषाधिकार प्राप्त" पैरामीटर को गलत पर सेट करें।

आप परियोजना पृष्ठ पर पूर्ण प्रलेखन पा सकते हैं: https://github.com/ValentinBELYN/icmplib

आशा है कि आप इस पुस्तकालय को उपयोगी पाएंगे।


2
मॉडरेटर नोट : यह उत्तर आत्म-प्रचार के लिए हमारी आवश्यकताओं का अनुसरण करता है , अनचाही नहीं है (प्रश्न पिंग का उपयोग करने के लिए पायथन समाधान के लिए पूछता है) और इसलिए शब्द की हमारी परिभाषा से स्पैम नहीं है
मार्टिन पीटर्स

0

मेजबानों की सूची को पिंग करने के लिए सिस्टम पिंग कमांड का उपयोग करना:

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)

6
मैं सिर्फ kicks और गिगल्स के लिए www.this_one_wont_work.com रजिस्टर करने जा रहा हूं।
मैथ्यू स्काउटन

p = Popen('ping -n 1 ' + self.host, stdout=PIPE)होना चाहिए p = Popen(['ping','-n','1','self.host'], stdout=PIPE)
toc777

0

सबप्रोसेस पिंग कमांड का उपयोग करके पिंग को डीकोड करना क्योंकि प्रतिक्रिया द्विआधारी है:

import subprocess
ping_response = subprocess.Popen(["ping", "-a", "google.com"], stdout=subprocess.PIPE).stdout.read()
result = ping_response.decode('utf-8')
print(result)

0

आप साइट के आईपी पाने के लिए सॉकेट की कोशिश कर सकते हैं और आईपी के लिए icmp पिंग करने के लिए स्क्रैप का उपयोग कर सकते हैं।

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

-1

इसका उपयोग अजगर 2.7 पर परीक्षण किया गया है और यह ठीक काम करता है यदि मिलीसेकंड में पिंग का समय वापस आता है तो सफलता मिलती है और असफलता लौटती है।

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

1
अजगर 3.6 पर विफल। ModuleNotFoundError: 'Subproccess' नाम का कोई मॉड्यूल नहीं
Stevoisiak

यह भी विफल रहता है क्योंकि commandएक सूची के बजाय सभी तर्कों सहित एक स्ट्रिंग है ताकि command not foundलिनक्स पर पूर्ण स्ट्रिंग के लिए ट्रिगर हो ।
२१:
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.