PythonTkinter 练习11之 自编工具 扫描地址段IP
#Time: 2020/03/05
#Author: Xiaohong
#运行环境: OS: Win7 64位 专业版Pack1
# Python: 3.7
功能:输入要扫描的地址段,检测哪些地址可以ping通
q缺点:1. 只考虑IPV4地址 2.只考虑Windows平台
Toolbox_main.py
import tkinter as tk
from Tl_baidu_scan_screen import *
from Tl_ip_scan_screen import *
class Win_Program:
def __init__(self):
self.master = tk.Tk()
self.master.state("zoomed") # 窗口最大化
self.master.title("Xiaohong's Toolbox")
self.master.grid()
self.SetupUI()
def SetupUI(self):
# 获取屏幕长/宽
Screen_width = self.master.winfo_screenwidth()
Screen_height = self.master.winfo_screenheight()
print(Screen_height,Screen_width)
fm1=tk.LabelFrame(self.master,text='爬取部分',padx=5,pady=5,width=800,height=100)
fm1.grid(row=0,column=1,padx=10,pady=10)
button1=tk.Button(fm1,text='baidu图片识别',command=lambda:self.Call_baidu_scan_win(self.master,Screen_width,Screen_height))
button1.grid(row=0,column=1,padx=5,pady=0)
fm2=tk.LabelFrame(self.master,text='其他部分',padx=5,pady=5,width=800,height=100)
fm2.grid(row=1,column=1,padx=10,pady=10)
button2=tk.Button(fm2,text='IP 地址扫描',command=lambda:self.Call_ip_scan_win(self.master,Screen_width,Screen_height))
button2.grid(row=0,column=1,padx=5,pady=0)
def Call_baidu_scan_win(self,father_win,Screen_width,Screen_height):
Tl_baidu_scan_screen(father_win,Screen_width,Screen_height)
pass
def Call_ip_scan_win(self,father_win,Screen_width,Screen_height):
Tl_ip_scan_screen(father_win,Screen_width,Screen_height)
pass
if __name__ == "__main__":
win_program = Win_Program()
tk.mainloop()
Tl_ip_scan_screen.py: (重点在 第 70 行 正则表达式来判断 是否符合IPV4的地址)
import tkinter as tk
import re
import tkinter.messagebox
from Tl_ip_scan import *
class Tl_ip_scan_screen:
def __init__(self,father_win,Screen_width,Screen_height):
self.master = tk.Toplevel(father_win)
self.master.title('IP 地址扫描')
# 创建的Toplevel对象 在最上层
self.master.attributes("-toolwindow", 1)
self.master.wm_attributes("-topmost", 1)
self.master.grid()
width = 660
height = 420
x = Screen_width / 2 - width / 2
y = Screen_height / 2 - height / 2
self.master.geometry('%dx%d+%d+%d' % (width, height, x, y))
self.master.grid()
self.SetupUI()
def SetupUI(self):
entry_validate=self.master.register(self.check_vaild)
fm1=tk.LabelFrame(self.master,text='IP 地址段',padx=5,pady=5,width=600,height=100)
fm1.grid(row=0,column=1,columnspan=2,padx=5,pady=5)
lb1=tk.Label(fm1,text='IP 从')
lb1.grid(row=0,column=1)
# 设定默认值
web_site = tk.StringVar()
web_site.set('192.168.101.26')
web_site_value = tk.Entry(fm1, textvariable=web_site, font=('Arial', 10),width=15,validate='focusout',vcmd=(entry_validate,'%P'))
web_site_value.grid(row=0,column=2)
lb1=tk.Label(fm1,text='到')
lb1.grid(row=0,column=3)
web_site_to = tk.StringVar()
web_site_to.set('192.168.101.30')
web_site_to_value = tk.Entry(fm1, textvariable=web_site_to, font=('Arial', 10), width=15, validate='focusout',
vcmd=(entry_validate, '%P'))
web_site_to_value.grid(row=0,column=4)
button1=tk.Button(fm1,text='扫描',command=lambda :self.Call_ip_Scan(web_site_value.get(),web_site_to_value.get(),lb1=lb1,lb2=lb2))
button1.grid(row=0,column=5,padx=2)
button2 = tk.Button(fm1, text='返回', command=self.master.quit)
button2.grid(row=0, column=6)
fm3 = tk.LabelFrame(self.master,text='OK结果', padx=5, pady=5, width=400, height=250)
fm3.grid(row=1, column=1,padx=5, pady=5,sticky='w')
lb1 = tk.Listbox(fm3,height=9)
lb1.grid(row=0,column=1)
fm4 = tk.LabelFrame(self.master,text='NO结果', padx=5, pady=5, width=400, height=250)
fm4.grid(row=1, column=2,padx=5, pady=5,sticky='w')
lb2 = tk.Listbox(fm4,height=9)
lb2.grid(row=0,column=2)
self.master.mainloop()
def check_vaild(self,content):
if content=="":
return true
#用正则表达式来判断是否是IPV4的地址
if re.match(r"^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$",
content):
return True
else:
tkinter.messagebox.showerror(title='操作失败', message='无效的IP地址:' + content)
return False
def Call_ip_Scan(self,ip_from,ip_to,lb1,lb2):
if self.check_vaild(ip_from):
if self.check_vaild(ip_to):
# 找到ip地址的最后一部分,如192.168.101.26 ,取出26
ip_from_end = ip_from[ip_from.rfind('.')+1:]
ip_to_end = ip_to[ip_to.rfind('.') + 1:]
# 找到ip地址的前3部分,如192.168.101.26 ,取出 192.168.101.
ip_from_begin = ip_from[:ip_from.rfind('.') + 1]
ip_list=[]
# 生成待扫描的IP地址列表
for i in range(int(ip_from_end),int(ip_to_end)+1):
ip_list.append(ip_from_begin+str(i))
reachlb,unreachlb=Tl_ip_scan(ip_list)
for i in reachlb:
lb1.insert(tk.END,i)
for i in unreachlb:
lb2.insert(tk.END, i)
Tl_ip_scan.py (重点在 第 15 行 、第 25 行) 多线程执行Ping 命令
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import subprocess
import threading
import os
import platform
global unreach_list,reach_list,platOS
unreach_list=list() #保存无法ping通的ip list
reach_list=list() #保存可以ping通的ip list
#根据不同的OS,调用不同的命令语句
def is_reacheable(ip):
backinfo = subprocess.os.system('ping -n 1 -w 1 %s >nul' % ip) # 实现pingIP地址的功能,-n1指发送报文一次,-w1指等待1毫秒
if backinfo: # 返回值非0,代表无法pingt通
unreach_list.append(ip)
else: # 返回值为0,代表pingt通
reach_list.append(ip)
def Tl_ip_scan(ip_list):
threads = []
for line in ip_list:
thr = threading.Thread(target=is_reacheable, args=(line,))
thr.start()
threads.append(thr)
for thr in threads:
thr.join()
return reach_list,unreach_list
运行的效果是: