如何通过API获取自托管OpenSpeedTest测速结果?寻求非Selenium方案
解决自托管OpenSpeedTest测速结果抓取问题
一、利用下载/上传请求自行计算测速结果
你观察到的http://10.86.37.20:3000/download?n=随机数这类请求完全可以用来计算测速结果,逻辑和前端测速的核心原理一致:
- 下载速度:发起请求时记录开始时间,获取响应头里的文件大小(这里是50MB),等文件完全下载后记录结束时间,用「文件大小/耗时」计算速度,注意单位转换(比如转成Mbps的话,公式是
(文件字节数*8)/(1024*1024)/耗时秒) - 上传速度:找到服务器接收上传的接口(可通过浏览器F12的Network面板查看前端上传请求的端点,通常是
/upload),生成指定大小的随机数据上传,同样记录开始/结束时间计算速度 - Ping与抖动:可以向服务器发送多个小请求(比如GET
/ping,如果服务器提供这个端点),记录每个请求的往返时间,平均值就是Ping值,多次往返时间的差值平均值就是抖动值
示例代码(基于requests库):
import requests import time def calculate_download_speed(download_url): start_time = time.time() response = requests.get(download_url, stream=True) total_size = int(response.headers.get('Content-Length', 0)) # 读取所有数据确保下载完成 for chunk in response.iter_content(chunk_size=1024): pass end_time = time.time() elapsed = end_time - start_time if elapsed <= 0: return 0 # 转换为Mbps单位 speed_mbps = (total_size * 8) / (1024 * 1024) / elapsed return round(speed_mbps, 2) # 调用示例 download_speed = calculate_download_speed("http://10.86.37.20:3000/download?n=0.015355377695134287") print(f"下载速度: {download_speed} Mbps")
二、用BeautifulSoup抓取前端渲染的结果
如果你的OpenSpeedTest实例是静态页面,或者测速完成后结果会写入页面DOM,可以直接请求页面解析结果:
- 先访问测速页面,触发自动测速(多数实例加载后会自动启动)
- 循环请求页面,直到结果元素出现(避免测速未完成就解析)
- 用BeautifulSoup提取对应ID的元素文本
示例代码:
import requests from bs4 import BeautifulSoup import time def get_speedtest_results(server_url): session = requests.Session() # 初始化会话,触发测速 session.get(server_url) # 最多等待30秒,直到获取到结果 max_wait = 30 start_wait = time.time() while time.time() - start_wait < max_wait: response = session.get(server_url) soup = BeautifulSoup(response.text, 'html.parser') # 提取目标元素 download_elem = soup.find(id='downResult') upload_elem = soup.find(id='upRestxt') ping_elem = soup.find(id='pingResult') jitter_elem = soup.find(id='jitterDesk') # 验证所有结果都已加载 if all([download_elem, upload_elem, ping_elem, jitter_elem]) and download_elem.text.strip(): return { 'download': download_elem.text.strip(), 'upload': upload_elem.text.strip(), 'ping': ping_elem.text.strip(), 'jitter': jitter_elem.text.strip() } time.sleep(2) return None # 调用示例 results = get_speedtest_results("http://10.86.37.20:3000") if results: print(f"下载: {results['download']}, 上传: {results['upload']}, Ping: {results['ping']}, 抖动: {results['jitter']}") else: print("超时未获取到测速结果")
注意事项
- 部分OpenSpeedTest实例有会话限制,务必用
requests.Session()保持会话 - 如果是单页应用(SPA),前端结果由JS动态生成,直接请求页面可能拿不到数据,这种情况下自行计算测速结果更可靠
- 建议多次测试取平均值,结果会更稳定
内容的提问来源于stack exchange,提问作者vibhav shukla
相关产品推荐
相关产品推荐

