LoginSignup
21
15

More than 3 years have passed since last update.

PythonでWiFiの速度計測をする

Posted at

この記事は JSL (日本システム技研) Advent Calendar 2019 の13日目の記事です。


最近、社内のWiFiが遅くなるタイミングがあるような気がしていて、とはいえどの程度遅くなっているか定量的に分からなかったため、スピードテストを定期実行するスクリプトを書いてみました。

最初にまとめ

CUIからスピードテスト

まず、cron等で定期的に実行したかったためCUIでスピードテストを実行することを考えました

私のイメージではスピードテストといえば以下のように検索→実行…のようにして計測するものでした。

スクリーンショット 2019-12-23 15.54.09.png

Linux上でネットワーク回線速度を計測する手段について整理してみた | Developers.IO) の記事などをみつつ調査したところ speedtest.net がCLIを提供しているようでした

また、Speedtest CLIはPython packageも提供しており、

  • pipでbinaryをinstallすることが可能
    • brewで管理しなくても仮想環境化でspeedtestコマンドが使えそう
  • Python上でimportすることもできそう

なことがわかりました

speedtest実行環境の構築

pipenvを使って環境構築しました

$ mkdir wifi_speedtest
$ cd $_  
# pipenv 未インストールの場合
# brew install pipenv

# 仮想環境作成
$ pipenv --python 3.7

# パッケージのインストール
$ pipenv install speedtest-cli

# 仮想環境の有効化
$ pipenv shell

# speedtestコマンドのテスト
(.venv) $ speedtest --version
speedtest-cli 2.1.2
Python 3.7.4 (default, Oct 12 2019, 18:55:28) [Clang 11.0.0 (clang-1100.0.33.8)]

CUI上でSpeedtestを実行してみる

speedtest --list で有志が提供している接続先サーバの一覧が取れるのでいずれかに決めて番号を控えておきます。

(.venv) $ speedtest --list | grep Tokyo
15047) OPEN Project (via 20G SINET) (Tokyo, Japan) [6.34 km]
24333) Rakuten Mobile , Inc (Tokyo, Japan) [6.34 km]
28910) fdcservers.net (Tokyo, Japan) [6.34 km]
18516) GIAM PING VIETPN.COM (Tokyo, Japan) [6.34 km]
22247) Tokyonet (Castro, Brazil) [18486.74 km]

以下のように指定すると常に指定したサーバでスピードテストを実行します。例えば、 Rakuten Mobile , Inc 提供のサーバの場合、番号は 24333 となります。

# スピードテストを実行
(.venv) $ speedtest --server 24333
Retrieving speedtest.net configuration...
Testing from XXX (xx.xx.xx.xx)...
Retrieving speedtest.net server list...
Retrieving information for the selected server...
Hosted by Rakuten Mobile , Inc (Tokyo) [6.34 km]: 200.123 ms
Testing download speed................................................................................
Download: 16.08 Mbit/s
Testing upload speed......................................................................................................
Upload: 31.96 Mbit/s

無事計測できました(クライアント情報は一部隠しています)

  • Download: 16.08 Mbit/s
  • Upload: 31.96 Mbit/s

ただ、これだとプログラム上で扱いづらいので --json を付与して json 形式で結果を取得してみます

(.venv) $ speedtest --server 24333 --json
結果
{"download": 20208058.464686207, "upload": 54426180.687909536, "ping": 48.215, "server": {"url": "http://ookla.mbspeed.net:8080/speedtest/upload.php", "lat": "35.6833", "lon": "139.6833", "name": "Tokyo", "country": "Japan", "cc": "JP", "sponsor": "Rakuten Mobile , Inc", "id": "24333", "host": "ookla.mbspeed.net:8080", "d": 6.336536019993832, "latency": 48.215}, "timestamp": "2019-12-23T07:23:16.316637Z", "bytes_sent": 68534272, "bytes_received": 25353712, "share": null, "client": {"ip": "xx.xx.xx.xx", "lat": "xx.xxxx", "lon": "xxx.xxxx", "isp": "XXX", "isprating": "3.7", "rating": "0", "ispdlavg": "0", "ispulavg": "0", "loggedin": "0", "country": "JP"}}

これをPython上で扱うことを考えます

PythonでSpeedtestを実行する

せっかくPython Packageとして提供しているので、Pythonの中でプラグラマブルにスピードテストを実行することも考えましたが、今回はCUIでの実行結果をそのまま扱うことを考えたので subprocessモジュール でspeedtestコマンドを実行することにしました

subprocess --- サブプロセス管理 — Python 3.8.1 ドキュメント

wifi_speedtest.py
def get_speedtest_result():
    process = subprocess.run(['speedtest', '--server', '24333', '--json'], capture_output=True)
    return json.loads(process.stdout)


def bit_to_mbit(bit):
    """
    誤差とかは気にしない感じの作り
    """
    return bit / 1024 / 1024


result = get_speedtest_result()
print(bit_to_mbit(result["download"]), bit_to_mbit(result["upload"]))
結果
13.46394215 50.48002296

subprocess でコマンド実行する方法はいくつかありますが、今回は公式で使用例に載っている run() + capture_output=True で標準出力を取得しました

今回はSpreadSheetのAPIを叩いて記録するようにしました(詳細は割愛 以下を大いに参考にさせていただきました)。

Slackに飛ばすなり好きな方法で記録すると良いと思います。


余談ですが、Pipenvのscriptsを活用すると、cronから実行するときの仮想環境の有効化などが不要で便利でした(pipenv run経由で実行したプロセスは仮想環境化での実行と同じ扱いになる)

Pipfile
[scripts]
dev = 'python wifi_speedtest.py'
21
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
21
15