基于Python編寫簡(jiǎn)單的網(wǎng)絡(luò)測(cè)試工具
工具介紹
這是一個(gè)功能完整的網(wǎng)絡(luò)測(cè)速工具,可以測(cè)試網(wǎng)絡(luò)的下載速度、上傳速度和延遲。
功能特點(diǎn)
1. 速度測(cè)試
- 下載速度測(cè)試
- 上傳速度測(cè)試
- Ping延遲測(cè)試
- 自動(dòng)選擇最佳服務(wù)器
2. 實(shí)時(shí)顯示
- 進(jìn)度條顯示測(cè)試進(jìn)度
- 實(shí)時(shí)顯示測(cè)試狀態(tài)
- 清晰的數(shù)據(jù)展示
3. 歷史記錄
- 保存測(cè)試歷史
- 顯示最近6次測(cè)試結(jié)果
- 支持導(dǎo)出歷史記錄
使用要求
Python 3.6+
需要安裝的庫(kù):
python -m pip install speedtest-cli
使用方法
1. 安裝依賴:
- 首先安裝必要的庫(kù)
- 確保網(wǎng)絡(luò)連接正常
2. 開始測(cè)速:
- 點(diǎn)擊"開始測(cè)速"按鈕
- 等待測(cè)試完成(約1-2分鐘)
- 查看測(cè)試結(jié)果
3. 歷史記錄:
- 自動(dòng)保存每次測(cè)試結(jié)果
- 查看最近的測(cè)試歷史
- 可導(dǎo)出完整歷史記錄
完整代碼
import tkinter as tk from tkinter import ttk, messagebox try: import speedtest except ImportError: messagebox.showerror("錯(cuò)誤", "請(qǐng)先安裝 speedtest-cli:\npip install speedtest-cli") raise import threading import time from datetime import datetime import json import os from pathlib import Path class NetworkSpeedTest: def __init__(self): self.window = tk.Tk() self.window.title("網(wǎng)絡(luò)測(cè)速工具") self.window.geometry("600x500") # 創(chuàng)建主框架 self.main_frame = ttk.Frame(self.window, padding="10") self.main_frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S)) # 測(cè)速結(jié)果顯示 self.setup_display() # 控制按鈕 self.setup_controls() # 歷史記錄 self.setup_history() # 初始化speedtest self.st = None self.testing = False self.history_file = Path.home() / '.speedtest_history.json' self.load_history() def setup_display(self): # 當(dāng)前速度顯示 display_frame = ttk.LabelFrame(self.main_frame, text="測(cè)速結(jié)果", padding="10") display_frame.grid(row=0, column=0, sticky=(tk.W, tk.E), pady=10) # 下載速度 ttk.Label(display_frame, text="下載速度:").grid(row=0, column=0, pady=5) self.download_speed = ttk.Label(display_frame, text="-- Mbps") self.download_speed.grid(row=0, column=1, padx=20) # 上傳速度 ttk.Label(display_frame, text="上傳速度:").grid(row=1, column=0, pady=5) self.upload_speed = ttk.Label(display_frame, text="-- Mbps") self.upload_speed.grid(row=1, column=1, padx=20) # Ping值 ttk.Label(display_frame, text="Ping延遲:").grid(row=2, column=0, pady=5) self.ping = ttk.Label(display_frame, text="-- ms") self.ping.grid(row=2, column=1, padx=20) # 服務(wù)器信息 ttk.Label(display_frame, text="測(cè)速服務(wù)器:").grid(row=3, column=0, pady=5) self.server_info = ttk.Label(display_frame, text="--") self.server_info.grid(row=3, column=1, padx=20) # 進(jìn)度條 self.progress = ttk.Progressbar(display_frame, length=300, mode='determinate') self.progress.grid(row=4, column=0, columnspan=2, pady=10) # 狀態(tài)標(biāo)簽 self.status = ttk.Label(display_frame, text="就緒") self.status.grid(row=5, column=0, columnspan=2) def setup_controls(self): control_frame = ttk.Frame(self.main_frame) control_frame.grid(row=1, column=0, pady=10) self.start_button = ttk.Button(control_frame, text="開始測(cè)速", command=self.start_test) self.start_button.grid(row=0, column=0, padx=5) ttk.Button(control_frame, text="導(dǎo)出歷史", command=self.export_history).grid(row=0, column=1, padx=5) def setup_history(self): history_frame = ttk.LabelFrame(self.main_frame, text="歷史記錄", padding="10") history_frame.grid(row=2, column=0, sticky=(tk.W, tk.E), pady=10) # 創(chuàng)建表格 columns = ('time', 'download', 'upload', 'ping') self.history_tree = ttk.Treeview(history_frame, columns=columns, height=6) self.history_tree.heading('time', text='時(shí)間') self.history_tree.heading('download', text='下載(Mbps)') self.history_tree.heading('upload', text='上傳(Mbps)') self.history_tree.heading('ping', text='Ping(ms)') self.history_tree.column('#0', width=0, stretch=tk.NO) self.history_tree.column('time', width=150) self.history_tree.column('download', width=100) self.history_tree.column('upload', width=100) self.history_tree.column('ping', width=100) self.history_tree.grid(row=0, column=0) def load_history(self): if self.history_file.exists(): try: with open(self.history_file, 'r') as f: self.history = json.load(f) self.update_history_display() except: self.history = [] else: self.history = [] def save_history(self): with open(self.history_file, 'w') as f: json.dump(self.history, f) def update_history_display(self): for item in self.history_tree.get_children(): self.history_tree.delete(item) for record in self.history[-6:]: # 只顯示最近6條記錄 self.history_tree.insert('', 0, values=( record['time'], f"{record['download']:.1f}", f"{record['upload']:.1f}", f"{record['ping']:.0f}" )) def start_test(self): if self.testing: return self.testing = True self.start_button['state'] = 'disabled' self.progress['value'] = 0 self.status['text'] = "正在初始化..." # 在新線程中運(yùn)行測(cè)速 threading.Thread(target=self.run_speedtest, daemon=True).start() def run_speedtest(self): try: # 初始化 self.status['text'] = "正在連接到測(cè)速服務(wù)器..." self.st = speedtest.Speedtest() self.progress['value'] = 20 # 選擇服務(wù)器 self.status['text'] = "正在選擇最佳服務(wù)器..." server = self.st.get_best_server() self.server_info['text'] = f"{server['sponsor']} ({server['name']})" self.progress['value'] = 40 # 測(cè)試下載速度 self.status['text'] = "正在測(cè)試下載速度..." download_speed = self.st.download() / 1_000_000 # 轉(zhuǎn)換為Mbps self.download_speed['text'] = f"{download_speed:.1f} Mbps" self.progress['value'] = 60 # 測(cè)試上傳速度 self.status['text'] = "正在測(cè)試上傳速度..." upload_speed = self.st.upload() / 1_000_000 # 轉(zhuǎn)換為Mbps self.upload_speed['text'] = f"{upload_speed:.1f} Mbps" self.progress['value'] = 80 # 獲取ping值 ping_time = server['latency'] self.ping['text'] = f"{ping_time:.0f} ms" self.progress['value'] = 100 # 保存結(jié)果 self.history.append({ 'time': datetime.now().strftime("%Y-%m-%d %H:%M:%S"), 'download': download_speed, 'upload': upload_speed, 'ping': ping_time }) self.save_history() self.update_history_display() self.status['text'] = "測(cè)速完成" except Exception as e: messagebox.showerror("錯(cuò)誤", f"測(cè)速過程中出錯(cuò):{str(e)}") self.status['text'] = "測(cè)速失敗" finally: self.testing = False self.start_button['state'] = 'normal' def export_history(self): if not self.history: messagebox.showinfo("提示", "沒有歷史記錄可供導(dǎo)出") return file_path = tk.filedialog.asksaveasfilename( defaultextension=".csv", filetypes=[("CSV files", "*.csv")], initialfile="speedtest_history.csv" ) if file_path: try: with open(file_path, 'w', encoding='utf-8') as f: f.write("時(shí)間,下載速度(Mbps),上傳速度(Mbps),Ping延遲(ms)\n") for record in self.history: f.write(f"{record['time']},{record['download']:.1f}," f"{record['upload']:.1f},{record['ping']:.0f}\n") messagebox.showinfo("成功", "歷史記錄已導(dǎo)出") except Exception as e: messagebox.showerror("錯(cuò)誤", f"導(dǎo)出過程中出錯(cuò):{str(e)}") def run(self): self.window.mainloop() if __name__ == "__main__": app = NetworkSpeedTest() app.run()
效果圖
以上就是基于Python編寫簡(jiǎn)單的網(wǎng)絡(luò)測(cè)試工具的詳細(xì)內(nèi)容,更多關(guān)于Python網(wǎng)絡(luò)測(cè)試的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Python使用異步線程池如何實(shí)現(xiàn)異步TCP服務(wù)器交互
這篇文章主要介紹了Python使用異步線程池如何實(shí)現(xiàn)異步TCP服務(wù)器交互問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-11-11opencv實(shí)現(xiàn)簡(jiǎn)單人臉識(shí)別
這篇文章主要為大家詳細(xì)介紹了opencv實(shí)現(xiàn)簡(jiǎn)單人臉識(shí)別,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-08-08Python多進(jìn)程與多線程的使用場(chǎng)景詳解
這篇文章主要給大家介紹了關(guān)于Python多進(jìn)程與多線程使用場(chǎng)景的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03Python中將文件從一個(gè)服務(wù)器復(fù)制到另一個(gè)服務(wù)器的4種方法
Python中將文件從一個(gè)服務(wù)器復(fù)制到另一個(gè)服務(wù)器通常涉及到網(wǎng)絡(luò)傳輸,這個(gè)過程可以通過多種方式實(shí)現(xiàn),本文主要為大家介紹了4種常用方法,需要的可以參考下2024-10-10Python實(shí)現(xiàn)復(fù)制文件從一個(gè)目錄到另外一個(gè)目錄
這篇文章主要為大家詳細(xì)介紹了如何使用Python實(shí)現(xiàn)復(fù)制文件從一個(gè)目錄到另外一個(gè)目錄,文中的示例代碼簡(jiǎn)潔易懂,有需要的小伙伴可以參考一下2025-01-01在Python中使用itertools模塊中的組合函數(shù)的教程
這篇文章主要介紹了在Python中使用itertools模塊中的組合函數(shù)的教程,來自IBM官方技術(shù)文檔,需要的朋友可以參考下2015-04-04超詳細(xì)注釋之OpenCV旋轉(zhuǎn)圖像任意角度
這篇文章主要介紹了OpenCV旋轉(zhuǎn)圖像任意角度,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-09-09