我创建了一个机器人,试图从我的互联网提供商那里拿回钱

2025-05-24

我创建了一个机器人,试图从我的互联网提供商那里拿回钱

我和互联网服务提供商(ISP)的合同里,他们规定了预期网速的范围,但也规定了最低保证网速。如果他们不能保证网速高于最低保证网速,我每年可以享受几次折扣。

我不想坐在电脑前发垃圾信息到 speedtest.net 上查看我的网速什么时候变慢。我想知道网速有没有下降。下降的时间是一致的吗?有什么规律吗?我需要数据和一些数据可视化工具来了解我是否/何时有资格享受折扣,以及是否值得尝试。

像这样

带宽图

树莓派

在我信赖的树莓派上运行。通过路由器的 USB 线供电,并通过以太网连接,因此结果(除非使用其他网络)应该是可靠的。

实时查看我当前的带宽结果或阅读GitHub上的源代码

过度设计

这个项目一开始就太复杂了。我使用了一个名为 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))
)
Enter fullscreen mode Exit fullscreen mode

这不仅非常脆弱,而且容易受到 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
Enter fullscreen mode Exit fullscreen mode

此脚本通过 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
});
Enter fullscreen mode Exit fullscreen mode

对于存储,我想要一些根本不需要任何设置的东西。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)}`;
                }
            }
        }
    }
    });
}
Enter fullscreen mode Exit fullscreen mode

我发现 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
PREV
使用高性能 JavaScript 解决难题
NEXT
开源软件 Livre:conheça 和 entenda de uma vez por todas o que cada umsignifica