使用Python标准库查找本地IP地址

730 投票
50 回答
986723 浏览
提问于 2025-04-11 09:25

我该如何在Python中找到本地IP地址(比如192.168.x.x或10.0.x.x),而且要跨平台使用,只用标准库呢?

50 个回答

475

这个方法会返回本地机器上的“主要”IP地址(也就是默认路由的那个)

  • 不需要可路由的网络访问或任何连接。
  • 即使所有接口都没有插入网络,它也能正常工作。
  • 不需要或甚至不会尝试去获取其他地方的信息。
  • 可以处理NAT、公共、私有、外部和内部IP地址。
  • 纯Python 2(或3),没有外部依赖。
  • 在Linux、Windows和OSX上都能运行。

Python 3或2:

    import socket
    def get_ip():
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        s.settimeout(0)
        try:
            # doesn't even have to be reachable
            s.connect(('10.254.254.254', 1))
            IP = s.getsockname()[0]
        except Exception:
            IP = '127.0.0.1'
        finally:
            s.close()
        return IP
    print(get_ip())

这个方法返回一个单一的IP地址,也就是主要的那个(默认路由的)。如果你需要获取所有接口上附加的所有IP地址(包括本地主机等),可以参考这个答案

如果你在一个像家庭WiFi路由器那样的NAT防火墙后面,那么这个方法不会显示你的公共NAT IP,而是显示你在本地网络上的私有IP,这个IP有一个默认路由指向你的本地WiFi路由器。如果你需要获取外部IP:

  • 可以在那个外部设备(WiFi路由器)上运行这个函数,或者

  • 连接到一个外部服务,比如https://www.ipify.org/,它可以反映出你在外部世界看到的IP。

... 不过这些想法和最初的问题完全不同。:)

642

我刚发现这个方法,虽然看起来有点不太正规,但他们说在*nix系统上试过,我在Windows上也试了,结果成功了。

import socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(("8.8.8.8", 80))
print(s.getsockname()[0])
s.close()

这个方法假设你有网络连接,并且没有本地的代理服务器。

569
import socket
socket.gethostbyname(socket.gethostname())

这个方法并不总是有效(在一些机器上,如果主机名在 /etc/hosts 文件中被设置为 127.0.0.1,它会返回 127.0.0.1),一个解决办法是使用 socket.getfqdn(),就像gimel所展示的那样。当然,你的机器需要有一个可以解析的主机名。

撰写回答