基于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+
需要安裝的庫:
python -m pip install speedtest-cli
使用方法
1. 安裝依賴:
- 首先安裝必要的庫
- 確保網(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-11
opencv實(shí)現(xiàn)簡(jiǎn)單人臉識(shí)別
這篇文章主要為大家詳細(xì)介紹了opencv實(shí)現(xiàn)簡(jiǎn)單人臉識(shí)別,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-08-08
Python多進(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-03
Python中將文件從一個(gè)服務(wù)器復(fù)制到另一個(gè)服務(wù)器的4種方法
Python中將文件從一個(gè)服務(wù)器復(fù)制到另一個(gè)服務(wù)器通常涉及到網(wǎng)絡(luò)傳輸,這個(gè)過程可以通過多種方式實(shí)現(xiàn),本文主要為大家介紹了4種常用方法,需要的可以參考下2024-10-10
Python實(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

