手动实现一个测网速的功能python+speedtest
引言
下午突发奇想,通常测网速我们都是用第三方的app或者网站很不方便,而且可能会泄露隐私,想试试自己写一个测网速的功能。
总体设计
借助python的第三方库speedtest
,主要设计了三个功能:测网速、显示历史记录、绘制历史记录图标。
面向对象的思想,封装三个功能,再在main
函数设计一个菜单。
测网速功能
这部分就是借助speedtest
库,创建Speedtest()
对象,使用get_servers()
可以获取当前可用的服务器节点,download()
,upload()
下载上传的速度,将得到的速度(返回的是浮点型)处理成单位是Mbps
,加上断言。
历史记录
这部分的话用到了IO流
文件操作,将刚才得到的速度放入列表写入csv文件存储
绘图
绘图部分用的就是matplotlib
完整代码
"""
-*- coding: utf-8 -*-
@Project : learningProject
@File : demo.py
@Author : xiuzhi233
@Time : 2024/1/6 14:06
@Describe :
测网速功能
"""
import speedtest
import time
import platform
import csv
from datetime import datetime
from pprint import pprint
class SpeedTester:
def __init__(self):
# 初始化 Speedtest 对象和历史记录文件路径
self.st = speedtest.Speedtest()
self.history_file = "speed_history.csv"
def measure_speed(self):
# pprint("当前可用的服务器节点", self.st.get_servers())
try:
# 使用 Speedtest 对象测量下载、上传速度和ping延迟
download_speed = self.st.download()
upload_speed = self.st.upload()
ping_latency = self.st.results.ping
# 将速度转换为 Mbps,并存储到字典中
print(download_speed, type(download_speed))
speed_mbps = {
"download": download_speed / 1e6,
"upload": upload_speed / 1e6,
}
return speed_mbps, ping_latency
except Exception as e:
print(f"Error: {e}")
return None
def save_to_history(self, speed, latency):
# 将测速结果和时间戳保存到历史记录文件中
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
with open(self.history_file, mode="a", newline="") as file:
writer = csv.writer(file)
writer.writerow([timestamp, speed["download"], speed["upload"], latency])
def display_history(self):
try:
# 从历史记录文件中读取数据并显示
with open(self.history_file, mode="r") as file:
reader = csv.reader(file)
for row in reader:
print(row)
except FileNotFoundError:
print("历史记录文件不存在,请先进行测速。")
def plot_history(self):
timestamps, download_speeds, upload_speeds, latencies = [], [], [], []
try:
# 从历史记录文件中读取数据
with open(self.history_file, mode="r") as file:
reader = csv.reader(file)
next(reader) # 跳过标题行
for row in reader:
timestamps.append(row[0])
download_speeds.append(float(row[1]))
upload_speeds.append(float(row[2]))
latencies.append(float(row[3]))
# 打印历史记录数据
print("\n历史记录:")
print(f"{'Timestamp':<20} {'Download Speed':<15} {'Upload Speed':<15} {'Ping Latency':<15}")
for i in range(len(timestamps)):
print(f"{timestamps[i]:<20} {download_speeds[i]:<15.2f} Mbps {upload_speeds[i]:<15.2f} Mbps {latencies[i]:<15.2f} ms")
except FileNotFoundError:
print("历史记录文件不存在,请先进行测速。")
def main():
# 创建 SpeedTester 对象
speed_tester = SpeedTester()
while True:
print("\n选择操作:")
print("1. 测量网速")
print("2. 显示历史记录")
print("3. 绘制历史记录图表")
print("4. 退出")
choice = input("请输入数字进行操作: ")
if choice == "1":
# 测量网速并保存结果到历史记录
speeds, latency = speed_tester.measure_speed()
if speeds:
print(f"\nDownload Speed: {speeds['download']:.2f} Mbps")
print(f"Upload Speed: {speeds['upload']:.2f} Mbps")
print(f"Ping Latency: {latency} ms")
speed_tester.save_to_history(speeds, latency)
else:
print("测速失败,请检查网络连接或URL是否有效。")
elif choice == "2":
# 显示历史记录
speed_tester.display_history()
elif choice == "3":
# 绘制历史记录图表
speed_tester.plot_history()
elif choice == "4":
# 退出程序
print("感谢使用,再见!")
break
else:
# 无效的选择
print("无效的选择,请重新输入。")
if __name__ == "__main__":
main()