PythonTkinter 練習11之 自編工具 掃描地址段IP

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

運行的效果是:


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章