子育てしながらエンジニアしたい

現在 7 歳 女の子の子育て中エンジニアによる、技術系 + 日常系ブログ。

Python で自身の IP アドレスを取得したい - Windows 編

[2019/07/17 追記]
本記事は Windows でのみ動作します。
Ubuntu 編を改めて記載しましたので、Ubuntu の方は以下の記事をご覧ください。

edosha.hatenablog.jp


低レイヤーのネットワークプログラミングをしていると、自身の IP アドレスを取得したいことがよくあります。
ところが Python では、これを簡単に取得するということができませんでした。

Stack overflow でもこれが議論になっており、一番簡単なのは外部ライブラリ "netifaces" を使うという結論でした。
stackoverflow.com

でも、移植性を考えると、できれば外部ライブラリは使いたくありません。
なんかないかな~と探していたら、標準ライブラリでいけそうな方法を見つけたので紹介します。

Python socket モジュールで自身の IP アドレスを取得する

実行環境は Python 3.5.3 / Windows 10 です。
標準ライブラリの socket モジュールを使います。

$ python --version
Python 3.5.3 :: Anaconda 4.4.0 (64-bit)

IP アドレスを取得する socket API

以下の 2 種類があります。

  • socket.gethostbyname(hostname)
    • ホスト名を '100.50.200.5' のようなIPv4形式のアドレスに変換します。
  • socket.gethostbyname_ex(hostname)
    • (hostname, aliaslist, ipaddrlist) のタプルを返し、 hostname は ip_address で指定したホストの正式名、 aliaslist は同じアドレスの別名のリスト(空の場合もある)、 ipaddrlist は同じホスト上の同一インターフェースのIPv4アドレスのリスト(ほとんどの場合は単一のアドレスのみ)を示します。

どちらも引数は hostname です。
つまり、自身の hostname を取得できれば、上記の API に渡すことで IP アドレスを取得できるということです。

hostname を取得する socket API

そのまんまです。

上記を組み合わせて、自身の IP アドレスを取得する

まずは自身の IP アドレスを確認してみます。

$ ipconfig | grep IPv4
ipconfig | grep IPv4
   IPv4 Address. . . . . . . . . . . : 192.168.1.10
   IPv4 Address. . . . . . . . . . . : 192.168.56.1
   IPv4 Address. . . . . . . . . . . : 10.150.2.139

3 つもありました。
1 番上は有線、2 番目は Virtual Box の仮想アダプタ、3 番目は無線です。

では、Python コンソールで socket API を使ってみましょう。

>>> import socket
>>> socket.gethostname()
'edosha_notepc'
>>> socket.gethostbyname(socket.gethostname())
'192.168.1.10'
>>> socket.gethostbyname_ex(socket.gethostname())
('edosha_notepc', [], ['192.168.56.1', '10.150.2.139', '192.168.1.10'])

gethostbyname で有線の IP アドレス、gethostbyname_ex で全ての IP アドレスが取得できました。

私のように 3 つもアドレスを使うのでなければ、gethostbyname でよさそうです。
どれかを選ばせたいときは gethostbyname_ex が有効かもしれません。