Як перевірити веб-сайт або IP-адресу за допомогою Python?
Як перевірити веб-сайт або IP-адресу за допомогою Python?
Відповіді:
Дивіться цей чистий пінг-пітон від Метью Діксона Каулза та Єнса Дімера . Також пам’ятайте, що 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
використовує, time.clock
що не дає нічого корисного на моєму Linux box. timeit.default_timer
(це дорівнює time.time
на моїй машині) працює. time.clock
-> timeit.default_timer
gist.github.com/255009
Залежно від того, що ви хочете отримати, вам, мабуть, найпростіше викликати системну команду 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
Вам не потрібно турбуватися про символи втечі оболонки. Наприклад..
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
). Це не ідеально, але в багатьох ситуаціях це буде добре працювати (коли ви знаєте, на яких машинах буде працювати скрипт)
out
містить закодований \ n, який, здається, заважає узгодженню:matcher = re.compile("\nround-trip min/avg/max/stddev = (\d+.\d+)/(\d+.\d+)/(\d+.\d+)/(\d+.\d+)")
Ви можете знайти презентацію Ноя Подарунка Створення гнучких інструментів командного рядка за допомогою 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 System Administration
http://ecx.images-amazon.com/images/I/515qmR%2B4sjL._SL500_AA240_.jpg
Важко сказати, у чому ваше питання, але є кілька альтернатив.
Якщо ви маєте на увазі буквальне виконання запиту за допомогою протоколу ICMP ping, ви можете отримати бібліотеку ICMP і виконати запит ping безпосередньо. Google "Python ICMP", щоб знайти такі речі, як цей icmplib . Можливо, ви також захочете поглянути на скапа .
Це буде набагато швидше, ніж використання os.system("ping " + ip )
.
Якщо ви маєте на увазі загальний "пінг" ящика, щоб перевірити, чи він піднявся, ви можете використовувати протокол відлуння на порту 7.
Для відлуння ви використовуєте бібліотеку сокетів, щоб відкрити IP-адресу та порт 7. Ви пишете щось на цьому порту, надсилаєте каретку return ( "\r\n"
), а потім читаєте відповідь.
Якщо ви маєте на увазі "перевірити" веб-сайт, щоб перевірити, чи він працює, вам доведеться використовувати протокол http на порту 80.
Для належної перевірки веб-сервера ви використовуєте urllib2, щоб відкрити певну URL-адресу. ( /index.html
завжди популярний) і прочитайте відповідь.
Є ще більше потенційних значень "ping", включаючи "traceroute" та "finger".
Я зробив щось подібне таким чином, як натхнення:
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
/index.html
; на будь-якому веб-сайті, де насправді був би документ, що називається index.html
, він знаходився б там же, в корені сервера. Замість цього ви б випереджати http://
або https://
до господаря
Ось короткий фрагмент з використанням 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."
-c
є -n
, і логіка щодо коду повернення інша)
прочитати ім'я файлу, файл містить одну 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)
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"
Якщо ви хочете щось власне на Python, з чим ви можете грати, подивіться на Scapy:
from scapy.all import *
request = IP(dst="www.google.com")/ICMP()
answer = sr1(request)
На мою думку, це набагато краще (і повністю крос-платформне), ніж деякі фанкі дзвінки підпроцесу. Також ви можете мати стільки інформації про відповідь (ідентифікатор послідовності .....) скільки завгодно, як і сам пакет.
Ви можете знайти оновлену версію згаданого сценарію, яка працює як для Windows, так і для Linux, тут
використання системної команди 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)
p = Popen('ping -n 1 ' + self.host, stdout=PIPE)
Має бути p = Popen(['ping','-n','1','self.host'], stdout=PIPE)
за допомогою команди 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)
ви можете спробувати сокет, щоб отримати ip сайту, і скористатися scrap для виведення 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])
Я розробляю бібліотеку, яка, на мою думку, може вам допомогти. Він називається icmplib (не пов'язаний з будь-яким іншим однойменним кодом, який можна знайти в Інтернеті) і є чистою реалізацією протоколу ICMP на Python.
Він повністю об'єктно-орієнтований і має прості функції, такі як класичний пінг, мультипінг та трасування, а також класи та сокети низького рівня для тих, хто хоче розробляти додатки на основі протоколу ICMP.
Ось деякі інші основні моменти:
Щоб встановити його (потрібен 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
Сподіваюсь, ця бібліотека вам стане в нагоді.
Використовуйте це, воно перевірено на 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
command
це рядок, що включає всі аргументи замість списку, тому запускає command not found
повний рядок у Linux.