Python跨平台获取指定网络接口IP地址的实现

落日邮差
落日邮差
发布时间:2026-10-11| 6人浏览过
原创

本文介绍如何使用Python的netifaces库跨平台获取指定网络接口的IPv4和IPv6地址。重点解决Windows系统下接口名称与注册表GUID的映射问题,提供完整的代码实现,包括获取接口ID、查询IP地址及跨平台兼容处理。

核心原理与跨平台差异

在Python中获取网络接口IP地址,通常依赖 netifaces 库。然而,Windows与Linux在接口标识方式上存在显著差异:

  • Linux:直接使用接口名称(如 eth0, ens33)即可查询。
  • Windows:接口名称(如 WLAN)并非底层唯一标识。真正的标识符是注册表中的GUID(全局唯一标识符),路径位于 SYSTEM\CurrentControlSet\Control\Network\{4d36e972-e325-11ce-bfc1-08002be10318}。

因此,在Windows环境下,必须先通过接口名称获取其对应的GUID,再使用该GUID查询IP地址。

Windows接口名称与GUID映射

为了实现跨平台兼容,首先需要编写一个辅助函数,将Windows下的接口名称映射到其唯一的GUID。这需要通过Windows注册表实现。

import netifaces as ni
# import winreg as wr

# 将windows下的接口的名称和唯一ID一一对应存入字典并返回
def get_connection_name_from_guid(iface_guids):  
    wr = __import__('winreg', globals(), locals(), ['wr'])
    iface_dict = {}
    reg = wr.ConnectRegistry(None, wr.HKEY_LOCAL_MACHINE)
    reg_key = wr.OpenKey(reg, r'SYSTEM\CurrentControlSet\Control\Network\{4d36e972-e325-11ce-bfc1-08002be10318}')

    for i in iface_guids:
        try:
            reg_subkey = wr.OpenKey(reg_key, i + r'\Connection')
            iface_dict[wr.QueryValueEx(reg_subkey, 'Name')[0]] = i
        except FileNotFoundError:
            pass
    return iface_dict

 # 根据输入的接口名称,返回唯一ID
def win_from_name_get_id(ifname): 
    x = ni.interfaces()
    return get_connection_name_from_guid(x).get(ifname)

该代码通过遍历所有可用接口的GUID,从注册表中读取其 Name 值,建立“名称-GUID”字典。测试时,传入 WLAN 可返回对应的GUID字符串。

获取IPv4与IPv6地址

在解决Windows的映射问题后,即可统一通过 netifaces.ifaddresses 获取IP地址。注意区分 AF_INET(IPv4)和 AF_INET6(IPv6)。

from netifaces import ifaddresses, AF_INET, AF_INET6
import platform

# 获取接口IPv4地址
def get_ip_address(ifname):
    if platform.system() == "Linux":
        try:
        	# AF_INET表示的是IPv4地址(AF_LINK则表示的是MAC地址)
            return ifaddresses(ifname)[AF_INET][0]['addr']
        except ValueError:
            return None
    elif platform.system() == "Windows":
    	# 需要首先调用win_from_name_get_id函数,获取接口的ID
        from win_ifname import win_from_name_get_id
        if_id = win_from_name_get_id(ifname)
        if not if_id:
            return
        else:
            return ifaddresses(if_id)[AF_INET][0]['addr']
    else:
        print('操作系统不支持,本脚本只能工作在Windows或者Linux环境!')

# 获取接口IPv6地址,和IPv4同理
def get_ipv6_address(ifname):
    if platform.system() == "Linux":
        try:
            return ifaddresses(ifname)[AF_INET6][0]['addr']
        except ValueError:
            return None
    elif platform.system() == "Windows":
        from win_ifname import win_from_name_get_id
        if_id = win_from_name_get_id(ifname)
        if not if_id:
            return
        else:
            # 此处依然要提供WIN的网卡ID, 而不是名字
            return ifaddresses(if_id)[AF_INET6][0]['addr']
    else:
        print('操作系统不支持,本脚本只能工作在Windows或者Linux环境!')


if __name__ == "__main__":
    if platform.system() == "Linux":
        print(get_ip_address('ens33'))
        print(get_ipv6_address('ens33'))
    elif platform.system() == "Windows":
        print(get_ip_address('WLAN'))
        print(get_ipv6_address('WLAN'))

关键逻辑说明

  1. 平台判断:使用 platform.system() 区分操作系统。
  2. Windows处理:调用 win_from_name_get_id 获取GUID。若获取失败(返回None),则直接返回,避免后续报错。
  3. 异常处理:使用 try-except 捕获 ValueError,防止接口不存在或无IP地址时程序崩溃。

总结

通过上述代码,实现了在Linux和Windows系统下,根据接口名称获取指定IPv4和IPv6地址的功能。核心难点在于Windows系统对接口标识的特殊要求,需通过注册表解析GUID。以上就是Python获取Linux和Windows系统指定接口的IP地址的步骤及代码的详细内容,更多关于Python网络编程的资料请关注本站其它相关文章!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。