3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Pythonを使って周囲の Wi-Fi 情報(SSID・BSSID・電波強度)を取得する

Last updated at Posted at 2022-01-16

モチベーション

Windows で Wi-Fi の SSID と BSSID を取得したいと思ったのがきっかけ。
はじめはコマンドラインで netsh wlan show networks mode=bssid で Wi-Fi の一覧を取得しようかと考えていたのですが、[参考資料](# 参考資料)にある通り、何度実行しても同一のSSID/BSSIDになってしまったり、複数あるはずのSSIDが接続中のSSID1つだけになってしまったりしました。

解決方法を以下に引用します。

C#を使ってWindowsAPIを呼び出すことでWifiの電波強度一覧を取得することができました。
使用したAPIはWlanScan()です。NativeWifiというオープンソースのライブラリを使って使用することができました。

上記を Python でもできないか調べたところ、win32wifi を見つけました。

環境

  • Windows 10
  • Python 3.6
  • 追加ライブラリ
    • win32wifi

※ 3.7 以上で実行しようとすると import comtypes でエラーが生じます。[参考資料](# 参考資料)の方法で回避できるかもしれません。

プログラム

実行をする場合は中身を確認しながら自己責任でお願いします。

WlanRegisterNotification にて通知がきても Wi-Fi 情報が空の場合があるため3回実行しています。
(何か使い方が間違っているのでしょうか...)

from win32wifi import Win32Wifi as ww
import threading


def get_ssid(trial=3):
    ## Wlanが変更を登録するEvent
    th_ev = threading.Event()
    def callback(wnd, p):
        th_ev.set()

    interfaces = ww.getWirelessInterfaces()
    handle = ww.WlanOpenHandle()


    ## 試行回数
    for i in range(trial):
            
        ssid_dict = {}
        for interface in interfaces:
            ## 検索
            ws = ww.WlanScan(handle, interface.guid)
            ## 登録完了を最大10秒待機する。
            cb = ww.WlanRegisterNotification(handle, callback)
            th_ev.wait(10)
            th_ev.clear()

            networks = ww.getWirelessNetworkBssList(interface)
            for network in networks:
                ssid = network.ssid.decode()
                bssid = network.bssid
                quality = network.link_quality

                ## ssid がなければリストを追加
                if ssid not in ssid_dict.keys():
                    ssid_dict[ssid] = []

                ## bssid と電波強度を追加
                ssid_dict[ssid].append((bssid, quality))

        ## 空でなければ break
        if ssid_dict != {}:
            break

    ww.WlanCloseHandle(handle)

    return ssid_dict


if __name__ == "__main__":
    print(get_ssid())

実行結果(例)

実行毎に更新し、周囲の SSID と BSSID、電波強度を取得できました。
win32wifi のソースコードを確認するとより多くの情報を取得できると思います。

{'SampleSSID1': [('XX:XX:XX:XX:XX:XX', 100)], 'SampleSSID2': [('YY:YY:YY:YY:YY:YY',80)], ..... }

参考資料

3
3
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
3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?