网络测试工具
工具介绍:
这是一个功能完整的网络测速工具,可以测试网络的下载速度、上传速度和延迟。
功能特点:
1. 速度测试
- 下载速度测试
- 上传速度测试
- Ping延迟测试
- 自动选择最佳服务器
2. 实时显示
- 进度条显示测试进度
- 实时显示测试状态
- 清晰的数据展示
3. 历史记录
- 保存测试历史
- 显示最近6次测试结果
- 支持导出历史记录
使用要求:
- Python 3.6+
- 需要安装的库:
python -m pip install speedtest-cli
使用方法:
1. 安装依赖:
- 首先安装必要的库
- 确保网络连接正常
2. 开始测速:
- 点击"开始测速"按钮
- 等待测试完成(约1-2分钟)
- 查看测试结果
3. 历史记录:
- 自动保存每次测试结果
- 查看最近的测试历史
- 可导出完整历史记录
完整代码:
import tkinter as tk
from tkinter import ttk, messagebox
try:
import speedtest
except ImportError:
messagebox.showerror("错误", "请先安装 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("网络测速工具")
self.window.geometry("600x500")
# 创建主框架
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))
# 测速结果显示
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):
# 当前速度显示
display_frame = ttk.LabelFrame(self.main_frame, text="测速结果", 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)
# 服务器信息
ttk.Label(display_frame, text="测速服务器:").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)
# 进度条
self.progress = ttk.Progressbar(display_frame, length=300, mode='determinate')
self.progress.grid(row=4, column=0, columnspan=2, pady=10)
# 状态标签
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="开始测速", command=self.start_test)
self.start_button.grid(row=0, column=0, padx=5)
ttk.Button(control_frame, text="导出历史", 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)
# 创建表格
columns = ('time', 'download', 'upload', 'ping')
self.history_tree = ttk.Treeview(history_frame, columns=columns, height=6)
self.history_tree.heading('time', text='时间')
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'] = "正在初始化..."
# 在新线程中运行测速
threading.Thread(target=self.run_speedtest, daemon=True).start()
def run_speedtest(self):
try:
# 初始化
self.status['text'] = "正在连接到测速服务器..."
self.st = speedtest.Speedtest()
self.progress['value'] = 20
# 选择服务器
self.status['text'] = "正在选择最佳服务器..."
server = self.st.get_best_server()
self.server_info['text'] = f"{server['sponsor']} ({server['name']})"
self.progress['value'] = 40
# 测试下载速度
self.status['text'] = "正在测试下载速度..."
download_speed = self.st.download() / 1_000_000 # 转换为Mbps
self.download_speed['text'] = f"{download_speed:.1f} Mbps"
self.progress['value'] = 60
# 测试上传速度
self.status['text'] = "正在测试上传速度..."
upload_speed = self.st.upload() / 1_000_000 # 转换为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
# 保存结果
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'] = "测速完成"
except Exception as e:
messagebox.showerror("错误", f"测速过程中出错:{str(e)}")
self.status['text'] = "测速失败"
finally:
self.testing = False
self.start_button['state'] = 'normal'
def export_history(self):
if not self.history:
messagebox.showinfo("提示", "没有历史记录可供导出")
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("时间,下载速度(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("成功", "历史记录已导出")
except Exception as e:
messagebox.showerror("错误", f"导出过程中出错:{str(e)}")
def run(self):
self.window.mainloop()
if __name__ == "__main__":
app = NetworkSpeedTest()
app.run()