コンテンツにスキップ

Top

Python で gethostbyname で IPアドレスを取得したら 127.0.0.1 が返ってきて困った

Python で 自身のIPアドレスを取得する方法でネット上で散見しているのが、

import socket 
ip_addr = socket.gethostbyname(socket.gethostname())
確かにWindowsだと問題なく取れるのだけど、Linux(Ubuntu)で同じことをしたら 127.0.0.1が返却されて困った。

ので、Linuxで取得できる方法を調べた。

ネットワークインターフェース名(eth0とか)を指定して取得する

netifacesのifaddressesを使えばインターフェース名がわかっていればダイレクトにIPアドレスがとれる。
インターフェース名が "eth0"だとしたら、

import netifaces

ip_addr = netifaces.ifaddresses("eth0")[netifaces.AF_INET][0]['addr']

ただ最近のネットワークインターフェース名 eth0 じゃなく、 enp2s0 だったりするし、無線のほう(wlan0やwlp1s0)かもしれないし、いろんなLinuxマシンで動かしたい場合に決め打ちだと困る。
ので、インターフェース名はその都度取得したいところ。

で、取得するには、

import socket 

if_nameindex_list = socket.if_nameindex()
と、socket の if_nameindex を使えばよい。これでインターフェース名の配列が取得できる。

ちなみに有線が2つあるとか、有線と無線で両方IPアドレス設定してるとかあるとかの場合、当然、そのうちのどれを使うのかなんてそのプログラム次第なので、そのあたりは各人が勝手に判断してくれ。

Windows でも Linux でも Python で IPアドレス が取得できるソース

上記を踏まえてソース。
os.nameはwindowsだとnt、Linuxだとposixが返却されるのでそれで分岐している。
もし、そのインターフェースにIPアドレスが設定されてない場合はKeyErrorが飛ぶのでtry catch で対処している。
また、127.0.0.1を取得してもしょうがない(127.0.0.1がいやでこの話始まっとるわけで)のでそこはスキップするようにしている。

import netifaces
import os
import socket

def main():
    my_ip_addr = ''
    if os.name == "nt":
        # Windowsの場合
        my_ip_addr = socket.gethostbyname(socket.gethostname())
        print(my_ip_addr)
    elif os.name == "posix":
        # Linuxの場合
        if_nameindex_list = socket.if_nameindex()
        for if_nameindex in if_nameindex_list:
            try:
                my_ip_addr = netifaces.ifaddresses(if_nameindex[1])[netifaces.AF_INET][0]['addr']
                if my_ip_addr != '127.0.0.1':
                    print(if_nameindex[1] + " : " + my_ip_addr)
                    break
            except KeyError:
                print(if_nameindex[1] + ' has no addr.')


if __name__ == "__main__":
    main()
これで、WindowsでもLinuxでもIPアドレスが取得できる。
やったね!

以上!