在实际操作中,我们经常需要对一系列已分配的IP进行ping检测,以确认其是否正在运行。然而,我们的表格仅有一个标签页,且仅包含一个ip地址列。
iP |
---|
192.168.196.106 |
192.168.196.107 |
192.168.196.108 |
192.168.196.109 |
实现思路
我们的策略是读取表格,然后对每个IP地址使用ping3进行ping检测。为了提高ping检测的效率,我们采用多线程并发技术,因为ping操作是一种占用I/O的行为,更适合使用多线程。在这里,我们使用Python内置的threading模块,通过创建Thread类的线程对象并执行它来实现多线程。线程对象的创建包括两部分:目标函数(target)和参数列表(args)。在执行时,将参数列表传递给目标函数。
首先,我们编写一个名为single_ping
的函数,用于执行单个IP
地址的ping
操作。接下来,我们将使用Python
的内置threading
模块创建多个线程来执行这个函数。由于线程的执行顺序是不确定的,我们将结果存储在一个名为ping_results
的字典中。在每个线程开始执行时,我们将传入该字典,并在执行过程中更新自己IP
地址的执行结果。这样可以避免冲突。
代码实现
按照以上思路,我们编写的代码结果如下:
import threading
import pandas as pd
import ping3
def single_ping(ip,timeout,ping_results):
'''
description: ping一个单独的IP地址
:param ip: 要ping的IP地址
:param timeout: ping的超时时间
:param ping_results: 所有IPping的结果,字典格式,key是IP,value是ping的结果。
'''
ping_time = ping3.ping(ip,timeout=timeout)
ping_results[ip] = ping_time
def batch_ping(file="ping.xlsx",result_file="ping_result.xlsx",timeout=4):
'''
description: 从文件中读取待ping的列表,然后使用多线程批量去ping,结果再到一个表格文件中
:param file: 待ping的表格文件
:param timeout: 超时时间
'''
# 通过pandas读取ip列表
df = pd.read_excel(file)
ip_items = df.to_dict(orient='records')
# 将字典的列表转换为字符串的列表
ip_list = [ i['ip'] for i in ip_items]
# 用于存储ping结果的字典
ping_results = {}
# 使用多线程进行批量的ping操作
threads = []
# 循环读取IP
for ip in ip_list:
# 将每个IP地址传、超时时间和存放结果的字典,通过多线程方式传给目标函数,创建一个线程
t = threading.Thread(target=single_ping,args=(ip,timeout,ping_results))
# 线程追加到线程池
threads.append(t)
# 启动此线程任务
t.start()
# 阻塞多线程任务,即当所有的线程执行完成后再继续主程序的余下部分代码
for t in threads:
t.join()
# 将ping的结果再写会到原来的字典列表中去
# 以从表格中读取到的字典列表作为数据源,以保证顺序一致
for i in ip_items:
# 根据 IP 地址获取其结果
item_ping_result = ping_results[i['ip']]
# 对情况进行判断,以文字的方式编写结果
if item_ping_result is None:
i['result'] = '超时失败'
elif item_ping_result is False:
i['result'] = '域名解析失败'
else:
i['result'] = '成功'
# 极简表格操作法,写入表格
new_df = pd.DataFrame(ip_items)
new_df.to_excel(result_file,index=False,columns=['ip','result'])
if __name__ == '__main__':
batch_ping()
注意:
ip_list = [ i['ip'] for i in ip_items]
中的ip
是对于ping.xlsx
表头的字段
脚本运行结果是生成一个表格文件,其内容表
iP | result |
---|---|
192.168.196.106 | 域名解析失败 |
192.168.196.107 | 成功 |
192.168.196.108 | 域名解析失败 |
192.168.196.109 | 域名解析失败 |
结合这段代码和 netaddr 库,我们可以编写一个批量 ping 指定网段的功能,并对 IP 地址的使用情况进行总结分析。例如,我们可以查看 IP 地址的使用百分比,以及剩余可分配的 IP 地址等。此外,我们还可以与 Django 和 netaddr 结合,编写一个 IPAM(IP 地址管理系统),用于记录分配出去的 IP 地址以及查看 IP 的实际使用情况等。
扩展知识点:
ping3是一个基于Python3的ICMP ping实现模块,可以使用原始套接字进行ping操作。它是一个纯粹的Python3版本的ICMP ping工具包,无需特定用户权限即可发送ICMP包。