如何从Fast.com获得互联网速度结果 [英] How to get internet speed results from Fast.com

查看:75
本文介绍了如何从Fast.com获得互联网速度结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想定期检查我的互联网速度,并在路由器掉线某个阈值时重置路由器,这似乎可以解决我的ISP提供"的脆弱连接.

I want to regularly check my internet speed and reset my router if it drops a certain threshold, which seems to fix the crappy connection my ISP "provides".

尽管可能有更简单的方法进行此操作,但我认为我应该从Fast.com获得结果,这将为我提供所需的结果,例如下载速度,上载速度和对接近服务器的ping时间我.

Although there might be easier ways to go on about this, I figured I should get the results from Fast.com, which gives me the results I need, like download speed, upload speed, and ping times to a server close to me.

寻找任何指针.

推荐答案

该页面是JS驱动的,并且没有简单的方法通过简单地将HTML从页面上抓取来获得结果,因此requestsbs4一个人帮不上忙.
您需要运行一个完整的现代浏览器来运行测试,然后等待所需的时间再获取结果.

The page is JS-driven, and there's no easy way to get the results by simply scraping the HTML off the page, so requests and bs4 alone won't help you.
You need to run a full modern browser to let the test run, and wait however long it needs and then get the results.

好吧,我们为此使用 Selenium ,它基本上可以控制Chrome,Firefox,Safari阳光下的任何浏览器.

Ok, let's use Selenium for this, which can control Chrome, Firefox, Safari, basically any browser under the sun.

通过运行以下命令安装软件包:

Install the package by running:

pip install selenium

我们还需要安装驱动程序来控制我们的浏览器,您可以在此处找到它(实际上,请完整阅读有关安装的页面,其中包含运行它所需的一切).然后,我们需要将该可执行文件放入我们的PATH中.最简单的方法是将其放在Windows的c:\Windows或Linux的/usr/bin下.但是SO和Internet上有大量文档,因此请学习正确执行此操作的正确方法,您将需要它.

We also need to install a driver to control our browser, you can find it here (In fact read the page about installation completely, it has everything you need to get it running). Then we need to place that executable in our PATH. Easiest way is to just put it under c:\Windows on Windows or /usr/bin on Linux. But there's tons of documentation on SO and in the internet, so learn the proper way to do this correctly, you'll need it.

要避免这种情况,我们还需要美丽汤,是事实上的HTML解析器(请注意,我们可以继续使用selenium和浏览器,但是我习惯于使用bs4来完成这项工作).使用

With that out of the way, we also need Beautiful Soup, which is the defacto HTML parser (on that note, we can keep using selenium and browser, but I'm used to using bs4 for this job). Install it using

pip install bs4

运行测试

现在要获得结果,我们需要运行浏览器,转到 https://fast.com ,让测试完成,然后获取结果的HTML,然后提取所需的信息.

Running the test

Now to get the results, we need to run the browser, go to https://fast.com, let the test finish, then get the HTML for the results, then extract the info we need.

好吧,我们可以等30秒钟,直到一切完成.但是,如果提早完成怎么办?还是根本不完成?然后,我们将无缘无故地等待着.有更好的方法.

Well, we could just wait, like 30s until everything finishes. But what if it finishes early? Or not finish at all? Then we'd have waited for no reason. There's a better way.

测试完成后,微调器变为绿色.而且,如果我们从开发人员控制台观看DOM,就会看到它得到一个succeeded类.

When the test finishes, the spinner turns green. And if we watch the DOM from the Developer Console, we see that it gets a succeeded class.

但是,如果我们扩展结果,我们会看到上传结果还没有,当发生这种情况时,页面会再次更新,我们会达到以下状态:

But if we expand the results, we see the upload results are not in yet, when that happens, the page is updated once more and we reach at this state:

硒具有 显式等待 功能,可让您等到页面上发生某些事情为止.我们将使用它来检查并等待直到.succeeded类的某些元素变为可见.如果仅需要下载速度,则只需等待微调器获取.succeeded类,如果还需要上传结果,则需要等待.对于这项工作,我们可以使用以下辅助功能:

Selenium has an explicit wait feature that lets you wait until something happens on the page. We'll use it to check and wait until some element with .succeeded class becomes visible. If you just need the download speeds, simply wait for spinner to get .succeeded class, if you also need the uploads results, you need to wait for that instead. For this job we can use this helper function:

from selenium.common.exceptions import TimeoutException
from selenium.webdriver import Chrome
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait


def wait_visible(driver: Chrome, selector: str, timeout: int = 5):
    cond = EC.visibility_of_any_elements_located((By.CSS_SELECTOR, selector))
    try:
        WebDriverWait(driver, timeout).until(cond)
    except TimeoutException as e:
        raise LookupError(f'{selector} is not visible after {timeout}s') from e

提取结果

输入结果后,我们将获得包含上载和下载结果的父元素的HTML.

Extracting the results

Once the results are in, we get the HTML for the parent element that contains both upload and download results.

# this is the parent element that contains both download and upload results
results_selector = '.speed-controls-container'
results_el = driver.find_element_by_css_selector(results_selector)
results_html = results_el.get_attribute('outerHTML')

然后,我们将HTML馈送到BeautifulSoup并提取值.

Then we feed the HTML to BeautifulSoup and extract the values.

这是完整的代码:

from selenium.webdriver import Chrome, ChromeOptions
from selenium.webdriver.common.by import By
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from bs4 import BeautifulSoup
from contextlib import contextmanager


@contextmanager
def get_chrome() -> Chrome:
    # https://docs.python.org/3.7/library/contextlib.html#contextlib.contextmanager
    opts = ChromeOptions()
    opts.headless = True
    driver = Chrome(options=opts)
    yield driver
    driver.close()


def wait_visible(driver: Chrome, selector: str, timeout: int = 5):
    cond = EC.visibility_of_any_elements_located((By.CSS_SELECTOR, selector))
    try:
        WebDriverWait(driver, timeout).until(cond)
    except TimeoutException as e:
        raise LookupError(f'{selector} is not visible after {timeout}s') from e


def extract_speed_info(soup: BeautifulSoup) -> dict:
    dl_speed = soup.select_one('#speed-value').text
    dl_unit = soup.select_one('#speed-units').text
    upload_speed = soup.select_one('#upload-value').text
    upload_unit = soup.select_one('#upload-units').text

    return {
        'upload': f'{upload_speed} {upload_unit}',
        'download': f'{dl_speed} {dl_unit}'
    }


def run_speed_test() -> dict:
    with get_chrome() as driver:
        driver.get('https://fast.com')

        # wait at most 60s until upload results come in
        download_done_selector = '#speed-value.succeeded'
        upload_done_selector = '#upload-value.succeeded'
        wait_visible(driver, upload_done_selector, timeout=60)

        # this is the parent element that contains both download and upload results
        results_selector = '.speed-controls-container'
        results_el = driver.find_element_by_css_selector(results_selector)
        results_html = results_el.get_attribute('outerHTML')

    # we're finished with chrome, let it close (by exiting with block)

    soup = BeautifulSoup(results_html, 'html.parser')
    info = extract_speed_info(soup)
    return info


if __name__ == '__main__':
    try:
        results = run_speed_test()
        print('Speed results:', results)
    except LookupError as e:
        print('Cannot get speed results')
        print(e)

输出:

{'upload': '320 Kbps', 'download': '3.4 Mbps'}

这篇关于如何从Fast.com获得互联网速度结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆