如何从 Python 中的 NIC(网络接口控制器)获取 IP 地址?

新手上路,请多包涵

当 Unix 上的 Python 脚本发生错误时,将发送一封电子邮件。

如果 IP 地址是 192.168.100.37 这是测试服务器,我被要求将 {Testing Environment} 添加到电子邮件的主题行。这样我们就可以拥有一个脚本版本和一种方法来判断电子邮件是否来自测试服务器上的混乱数据。

但是,当我用谷歌搜索时,我一直在寻找这段代码:

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

但是,这给了我 127.0.1.1 的 IP 地址。当我使用 ifconfig 我明白了

eth0      Link encap:Ethernet  HWaddr 00:1c:c4:2c:c8:3e
          inet addr:192.168.100.37  Bcast:192.168.100.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:75760697 errors:0 dropped:411180 overruns:0 frame:0
          TX packets:23166399 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:59525958247 (59.5 GB)  TX bytes:10142130096 (10.1 GB)
          Interrupt:19 Memory:f0500000-f0520000

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:25573544 errors:0 dropped:0 overruns:0 frame:0
          TX packets:25573544 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:44531490070 (44.5 GB)  TX bytes:44531490070 (44.5 GB)

首先,我不知道它从哪里得到 127.0.1.1,但无论哪种方式,这都不是我想要的。当我用谷歌搜索时,我一直在使用相同的语法、 Bash 脚本或 netifaces,并且我正在尝试使用标准库。

那么如何在 Python 中获取 eth0 的 IP 地址呢?

原文由 Memor-X 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 549
2 个回答

两种方法:

方法#1(使用外部包)

您需要询问绑定到您的 eth0 接口的 IP 地址。这可以从 netifaces 包 中获得

import netifaces as ni
ip = ni.ifaddresses('eth0')[ni.AF_INET][0]['addr']
print(ip)  # should print "192.168.100.37"

您还可以通过以下方式获取所有可用接口的列表

ni.interfaces()

方法#2(无外包)

这是一种无需使用 python 包即可获取 IP 地址的方法:

 import socket
import fcntl
import struct

def get_ip_address(ifname):
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    return socket.inet_ntoa(fcntl.ioctl(
        s.fileno(),
        0x8915,  # SIOCGIFADDR
        struct.pack('256s', ifname[:15])
    )[20:24])

get_ip_address('eth0')  # '192.168.0.110'

注意:通过检测 IP 地址来确定您使用的是什么环境是一件很麻烦的事情。几乎所有框架都提供了一种非常简单的方法来设置/修改环境变量以指示当前环境。尝试查看您的文档。它应该像做一样简单

if app.config['ENV'] == 'production':
  # send production email
else:
  # send development email

原文由 Martin Konecny 发布,翻译遵循 CC BY-SA 4.0 许可协议

或者,如果您想获取用于连接网络的任何接口的 IP 地址而无需知道其名称,您可以使用以下命令:

 import socket
def get_ip_address():
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    s.connect(("8.8.8.8", 80))
    return s.getsockname()[0]

我知道这与你的问题有点不同,但其他人可能会到达这里并发现这个更有用。您不必拥有到 8.8.8.8 的路由即可使用它。它所做的只是打开一个套接字,但不发送任何数据。

原文由 jeremyjjbrown 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题