如何在Python中获取网络接口卡名称?

36

有没有办法获取计算机中NIC卡的名称,例如eth0、lo?如果可以的话,如何获取?

我已经进行了调查,但到目前为止,我只发现了获取IP地址和MAC地址的代码,例如:

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

需要一些代码方面的建议,非常感谢。

9个回答

52

我使用过一个很棒的Python库,叫做psutil。它可以在Linux、Windows和OSX等平台上使用,在Python 2.6到3.6中都有支持。

Psutil提供了一个net_if_addrs()函数,返回一个字典,其中键是NIC名称,值是每个分配给NIC的命名元组列表,包括地址族、NIC地址、网络掩码、广播地址和目标地址。

以下是使用net_if_addrs()的简单示例,它将打印出一个Python列表,其中包含NIC名称:

import psutil

addrs = psutil.net_if_addrs()
print(addrs.keys())

3
这是最佳答案。可用于Win/Linux/Mac,并且是一个文档完备的库,可用于许多其他操作系统内省。 - Gustavo Gonçalves

44

在Linux上,您可以通过列出/sys/class/net/中的链接来实现。

os.listdir('/sys/class/net/')

不确定这是否适用于所有发行版。


26

4
我在这里补充一下评论,Windows支持是在3.8版中添加的,而不是3.3版。3.3版仅支持Linux。 - Liam Plybon

25

因为当我搜索这些信息时,谷歌会跳出这个答案,所以我想补充一下我的方法来获取可用接口(以及IP地址)。非常好用的模块netifaces可以以便携的方式完成这项任务。


1
很好 - 它甚至在标准库中。实际问题的直接答案是:import netifaces; if_list = netifaces.interfaces() - bitinerant
2
@bitinerant 这不在标准库中。必须使用 pip 安装后才能使用。 - winsome
1
@winsome - 我错了,抱歉。Python 3包在Ubuntu上默认安装,至少在18.04桌面版(ubuntu-minimal依赖于nplannplan又依赖于netplan.io,而netplan.io则依赖于python3-netifaces)。 - bitinerant
在Windows上,此库将GUID作为网络名称返回。 - Dmytro Ovdiienko

13

我不认为标准库中有任何内容可以查询这些名称。

如果我需要在 Linux 系统上获取这些名称,我会解析 ifconfig 的输出或者 /proc/net/dev 的内容。可以查看这篇博客文章来解决类似的问题。


那Windows系统呢?有没有类似的方法? - JavaNoob
Windows 不是我的强项。也许 ipconfig /all 提供的一些信息是合适的? - Arlaharen
1
Python >= 3.3 中有一个。答案链接:https://dev59.com/s2865IYBdhLWcg3wZNrT#58191277 - yang5

8

使用Python的ctypes模块,你可以调用C库函数getifaddrs

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from ctypes import *

class Sockaddr(Structure):
    _fields_ = [('sa_family', c_ushort), ('sa_data', c_char * 14)]

class Ifa_Ifu(Union):
    _fields_ = [('ifu_broadaddr', POINTER(Sockaddr)),
                ('ifu_dstaddr', POINTER(Sockaddr))]

class Ifaddrs(Structure):
    pass

Ifaddrs._fields_ = [('ifa_next', POINTER(Ifaddrs)), ('ifa_name', c_char_p),
                    ('ifa_flags', c_uint), ('ifa_addr', POINTER(Sockaddr)),
                    ('ifa_netmask', POINTER(Sockaddr)), ('ifa_ifu', Ifa_Ifu),
                    ('ifa_data', c_void_p)]


def get_interfaces():
    libc = CDLL('libc.so.6')
    libc.getifaddrs.restype = c_int
    ifaddr_p = pointer(Ifaddrs())
    ret = libc.getifaddrs(pointer((ifaddr_p)))
    interfaces = set()
    head = ifaddr_p
    while ifaddr_p:
        interfaces.add(ifaddr_p.contents.ifa_name)
        ifaddr_p = ifaddr_p.contents.ifa_next
    libc.freeifaddrs(head) 
    return interfaces

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

请注意,这种方法不具备可移植性。

7

补充@Kristian Evensen所提到的,以下是我在遇到问题时使用的方法。如果你只是想获取接口列表,请使用:

interface_list = netifaces.interfaces()

如果你想使用特定的接口,但不知道末尾的数字是什么(例如:eth0),请使用以下命令:

interface_list = netifaces.interfaces()
interface = filter(lambda x: 'eth' in x,interface_list)

3
@jonas,我举了以太坊的例子。他们可以使用LO替代ETH。我相信我给出的回答足以回答楼主的问题。不确定这是否值得被踩。 - nihiser
这完全没有回答问题:“获取机器上NIC卡的名称”。您根本不知道接口名称或前缀。您应该尽可能灵活地编写代码。 - Jonas Libbrecht
3
@jonas第一行获取这些名称。 - nihiser

5

就像David Breuer所说的那样,在Linux中,您可以只列出“/ sys / class / net”目录(至少在Fedora上有效)。如果您需要有关某个接口的详细信息,可以浏览接口目录以获取更多信息。

def getAllInterfaces():
    return os.listdir('/sys/class/net/')

1

有一个Python包get-nic,可以提供NIC状态、上下线、IP地址、MAC地址等信息。


pip install get-nic

from get_nic import getnic

getnic.interfaces()

Output: ["eth0", "wlo1"]

interfaces = getnic.interfaces()
getnic.ipaddr(interfaces)

Output: 
{'lo': {'state': 'UNKNOWN', 'inet4': '127.0.0.1/8', 'inet6': '::1/128'}, 'enp3s0': {'state': 'DOWN', 'HWaddr': 'a4:5d:36:c2:34:3e'}, 'wlo1': {'state': 'UP', 'HWaddr': '48:d2:24:7f:63:10', 'inet4': '10.16.1.34/24', 'inet6': 'fe80::ab4a:95f7:26bd:82dd/64'}}

请参阅GitHub页面获取更多信息:https://github.com/tech-novic/get-nic-details


目前仅支持Linux操作系统。 - Shayan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接