我创建了一个机器人,试图从我的互联网提供商那里拿回钱
我和互联网服务提供商(ISP)的合同里,他们规定了预期网速的范围,但也规定了最低保证网速。如果他们不能保证网速高于最低保证网速,我每年可以享受几次折扣。
我不想坐在电脑前发垃圾信息到 speedtest.net 上查看我的网速什么时候变慢。我想知道网速有没有下降。下降的时间是一致的吗?有什么规律吗?我需要数据和一些数据可视化工具来了解我是否/何时有资格享受折扣,以及是否值得尝试。
像这样
在我信赖的树莓派上运行。通过路由器的 USB 线供电,并通过以太网连接,因此结果(除非使用其他网络)应该是可靠的。
过度设计
这个项目一开始就太复杂了。我使用了一个名为 Selenium 的 Web 浏览器自动化框架,访问 Netflix 的 fast.com 带宽测试来检查速度。它使用了一个无头 Chromium 实例。
# wait for test to finish i.e. when 'your speed message' is shown
WebDriverWait(driver, 120).until(
expected_conditions.presence_of_element_located(
(By.CSS_SELECTOR, FAST_COMPLETE_CSS))
)
这不仅非常脆弱,而且容易受到 CSS 更改的影响(必须硬编码,见上文),还意味着该项目的任何用户都需要为 Raspbian(Raspberry Pi 的默认 Linux 发行版)安装无头 Chromium 系统。在排除故障并使其运行后,我意识到它设计过度了。
此方法在项目中仍保留为一个选项 ( browsertest.py
),但由于浏览器开销较大,在 Raspberry Pi 上结果精度较低。注意:本项目适用于所有平台,但主要针对 Raspberry Pi。
后来我才发现 speedtest.net 有一个很棒的命令行库,我应该一开始就用它。下面是我获取下载速度的方法clitest.py
。
import speedtest
# ..
def get_speed():
"""
Use Speedtest CLI to test bandwidth speed.
:return: Download speed in Mbps
"""
s = speedtest.Speedtest()
s.download()
results_dict = s.results.dict()
return results_dict['download'] / 1048576 # convert bits to megabits
此脚本通过 crontab 运行,并指向服务器。类似命令python clitest.py 'https://server-location/save' 'password'
每半小时运行一次。Windows 的替代方案是任务计划程序,但我认为它比较笨重。
后端
我认为能够随时随地检查网速会很棒,所以我创建了一个Glitch 项目来存储、接收和托管结果。这是一个 Express/Node 项目,有两个 API 路由。
结果与密码一起发送/save
,该密码通过 Glitch 上的环境变量设置。
可以从 JSON 格式中读取结果切片/read
。Express 路由的具体示例如下。
// get bandwidth test results for graphing here
app.get("/read", function(request, response) {
const data = db.get("results").value();
const prepared = data.map(s => {
return { x: s.date, y: Number(s.speed).toFixed(3) };
});
const trimmed = prepared.slice(Math.max(prepared.length - 48, 1));
response.send(trimmed); // send a slice of results
});
对于存储,我想要一些根本不需要任何设置的东西。lowdb
是一个小型的本地 JSON 数据库,它非常完美,因为只会有一个进程读取或写入,并且写入事件每半小时左右发生一次。lowdb
如果“数据库”文件尚不存在,则创建它。
数据可视化
Chart.js 是 JavaScript 中常用的图表库,它使用了 Canvas API。它功能强大,默认显示效果也不错(不过也许我只是习惯了它的风格!)。包括 API 调用在内,它大约只有 50 行代码。
fetch('/read')
.then(response => response.json())
.then(json => renderGraph(json));
const safeDate = time => new Date(parseInt(time)).toUTCString();
const renderGraph = (speedData) => {
var ctx = document.getElementById('myChart').getContext('2d');
var myChart = new Chart(ctx, {
type: 'scatter',
data: {
datasets: [{
data: speedData,
backgroundColor: () => 'rgba(255, 99, 132, 0.2)',
borderColor: () => 'rgba(255, 99, 132, 1)',
borderWidth: 1,
pointRadius: 5,
}]
},
options: {
scales: {
xAxes: [{
type: 'linear',
position: 'bottom',
ticks: {
userCallback: (label, index, labels) => safeDate(label)
},
scaleLabel: {
display: true,
labelString: 'Date'
}
}],
yAxes: [{
scaleLabel: {
display: true,
labelString: 'Mbps'
},
ticks: {
beginAtZero: true
}
}],
},
title: {
display: true,
text: 'Bandwidth Test Results'
},
legend: {
display: false,
},
tooltips: {
callbacks: {
label: function(tooltipItem, data) {
return `${tooltipItem.value} Mbps @ ${safeDate(tooltipItem.label)}`;
}
}
}
}
});
}
我发现 Chart.js 很容易上手,而且和 JavaScript 一样,如果你想把一些东西整合起来,它非常高效。它的文档很棒,而且库也足够大,在 StackOverflow 上进行常见的搜索就能找到有用的答案。
下一步该怎么做
到目前为止,我的网速一直在保证的最低水平附近徘徊,当地时间晚上8点左右通常会下降。目前,我没什么可抱怨的!真是意外的惊喜。
由于我现在有最新的网速记录,以后诊断任何带宽问题都会变得非常简单。希望这个项目的一些代码能帮助你诊断一天中任何简单的带宽问题。
与 150 多名订阅我的关于编程和个人成长的新闻通讯的人一起!
我发布有关科技的推文@healeycodes。
文章来源:https://dev.to/healeycodes/i-built-a-bot-to-try-and-get-money-back-from-my-internet-provider-33ip