ぺーぱーふぇいす

雑記と備忘録。私はプログラマ。

【Mac + Python】接続しているWi-FiのSSIDを取得する

特定のWi-Fiに接続している場合に行いたい処理とかあるかもしれない。
例えば、操作しているMacbookが自宅のWi-Fiに接続されている状態であるならば、自宅のNASの音楽ライブラリと自動的に同期させたい……とか。

そんな時にPythonSSIDを調べる個人的チップ。

サンプル

まず前提。MacPythonのver。

$ sw_vers
ProductName:    Mac OS X
ProductVersion: 10.14.1
BuildVersion:   18B75

$ python --version
Python 3.7.0

上記の通り、動作させるのがMacだとわかっているのであればこんな感じ。

import subprocess
import re

class WiFiUtil:
    """Wi-Fi関連ユーティリティ
    """

    @staticmethod
    def getUsingSSID():
        """接続中のWi-FiのSSIDを取得する
        
        Returns:
            str -- SSID
        """

        cmd = ['/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport', '-I']
        cmd_res = subprocess.run(cmd, stdout=subprocess.PIPE)
        output = cmd_res.stdout.decode('utf-8')
        matchs = re.findall(r' +SSID: .+', output)
        res = ""
        if len(matchs) > 0:
            res = matchs[0]
            res = re.sub(r'^ +SSID: ', '', res)
            res = res.rstrip()
        return res

if __name__ == '__main__':
    res = WiFiUtil.getUsingSSID()
    print(res) #SSIDが出力される

サンプル解説

MacではWi-Fiの状態を確認、制御するコマンドが用意されている。
絶対パス/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport

オプションに-Iをつけることで現在接続中のWi-Fiの状態を調べることができる。
出力結果はこんな感じ。

     agrCtlRSSI: xxx
     agrExtRSSI: xxx
    agrCtlNoise: xxx
    agrExtNoise: xxx
          state: xxx
        op mode: xxx
     lastTxRate: xxx
        maxRate: xxx
lastAssocStatus: xxx
    802.11 auth: xxx
      link auth: xxx
          BSSID: xxx
           SSID: xxx
            MCS: xxx
        channel: xxx

Pythonからシェルコマンドを実行して、この標準出力結果を取得。
欲しいSSID: XXXに該当する箇所を正規表現とかを使って引き抜いている。

なお、subprocess.run()で取得している標準出力結果はbyte配列で変換されるので、Macのターミナルでデフォルトの文字コードとしてUTF-8でデコードしてから正規表現等で結果を引き抜いている。

いじょー。

余談

2018/11/21追記

結果的にOSのコマンドを利用する泥臭い感じになった。
「よっしゃ、OSのCLI動かして標準出力結果抜いたろ!」ってPythonでやる場合、ネックなのはクロスプラットフォームで動かす時なんかだろうか。

今回はSSIDを抜き取るためにmacOSairportというコマンドを使ったが、当然これがWindowsLinuxなら同様な機能を持つ別コマンドにしなければならない。
Pythonosとかplatformあたりのモジュールを使って、実行環境のOSを調べて実行するコマンドを変えることもそうだが、個人的に厄介だと思うのはsubprocessに実装されている標準出力を得る方法で返却されるのがバイト配列だという点だろうか。
mac OSでは特にターミナルの設定をいじっていなければUTF-8で(たぶん)デコードできるだろうが、Windowsのcmd.exeはOSに設定してあるロケール文字コードが変化するし、LinuxSSHで接続した時に文字化けとかする場合を考えると設定によりけりなんじゃないかな?。知らんけど。

最近はメインで使っているのがMacbookだからそんなに気はのらないけど、せっかくVMがガンガン動かせるようになってきたので暇ならクロスプラットフォームPythonスクリプトの構築に向けていろいろ調べておこうかな。