Python获取本地IP地址的多种实现方案与标准库解析

Evan
Evan
发布时间:2026-10-13| 2人浏览过
原创

本文详细解析Python获取本地IP地址的多种方法。首先介绍Python标准库的功能范围,随后深入探讨利用socket模块通过gethostname、UDP连接测试及系统调用(如ioctl)获取IP的原理与代码实现。同时对比了依赖hosts文件的局限性、Windows特有的API调用方式,以及使用ifcfg第三方库的便捷性,为不同场景下的网络编程提供实用参考。

标准库

Python内置了功能丰富的标准库。其核心语言主要涵盖数字、字符串、列表、字典、文件等基础类型及常用函数,而标准库则扩展了系统管理、网络通信、文本处理、数据库接口、图形系统以及XML处理等高级功能。

Python标准库的核心功能涵盖以下方面:

1. 文本处理:支持文本格式化、正则表达式匹配、文本差异计算与合并、Unicode编码支持以及二进制数据处理等功能。

2. 文件处理:提供文件操作、临时文件创建、文件压缩与归档、配置文件管理等实用功能。

3. 操作系统接口:包含线程与进程管理、IO复用机制、日期与时间处理、系统函数调用以及日志记录(logging)等功能。

4. 网络通信:支持网络套接字(Socket)、SSL加密通信以及异步网络通信等底层网络操作。

5. 网络协议支持:内置HTTP、FTP、SMTP、POP、IMAP、NNTP、XMLRPC等多种网络协议的支持,并提供了构建网络服务器的基础框架。

6. W3C格式支持:包含对HTML、SGML和XML等格式的处理能力。

7. 其他功能:涵盖国际化支持、数学运算、HASH算法处理以及Tkinter图形界面库等。

利用Python标准库获取本地IP地址

这是最简单的方法,但可靠性较低。该方法依赖系统的hosts文件配置,若hosts文件中未正确配置主机名映射,通常只能获取到回环地址127.0.0.1。

import socket
socket.gethostbyname(socket.gethostname())
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(("8.8.8.8", 80))
print(s.getsockname()[0])
s.close()
import socket
alias myip="python -c 'import socket; print([l for l in ([ip for ip in socket.gethostbyname_ex(socket.gethostname())[2] if not ip.startswith(\"127.\")][:1], [[(s.connect((\"8.8.8.8\", 53)), s.getsockname()[0], s.close()) for s in [socket.socket(socket.AF_INET, socket.SOCK_DGRAM)]][0][1]]) if l][0][0])'"
 
 
print([l for l in ([ip for ip in socket.gethostbyname_ex(socket.gethostname())[2] if not ip.startswith("127.")][:1], [[(s.connect(('8.8.8.8', 53)), s.getsockname()[0], s.close()) for s in [socket.socket(socket.AF_INET, socket.SOCK_DGRAM)]][0][1]]) if l][0][0])
 
 
print((([ip for ip in socket.gethostbyname_ex(socket.gethostname())[2] if not ip.startswith("127.")] or [[(s.connect(("8.8.8.8", 53)), s.getsockname()[0], s.close()) for s in [socket.socket(socket.AF_INET, socket.SOCK_DGRAM)]][0][1]]) + ["no IP found"])[0])
 
 
 
print([ip for ip in socket.gethostbyname_ex(socket.gethostname())[2] if not ip.startswith("127.")][:1])
 
 
print([(s.connect(('8.8.8.8', 53)), s.getsockname()[0], s.close()) for s in [socket.socket(socket.AF_INET, socket.SOCK_DGRAM)]][0][1])
import os
import socket
 
if os.name != "nt":
 import fcntl
 import struct
 
 def get_interface_ip(ifname):
 s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
 return socket.inet_ntoa(fcntl.ioctl(s.fileno(), 0x8915, struct.pack('256s',
  ifname[:15]))[20:24])
 
def get_lan_ip():
 ip = socket.gethostbyname(socket.gethostname())
 if ip.startswith("127.") and os.name != "nt":
 interfaces = [
 "eth0",
 "eth1",
 "eth2",
 "wlan0",
 "wlan1",
 "wifi0",
 "ath0",
 "ath1",
 "ppp0",
 ]
 for ifname in interfaces:
 try:
 ip = get_interface_ip(ifname)
 break
 except IOError:
 pass
 return ip

在Linux系统中,可以通过指定网卡名称来获取对应的IP地址。

>>> import socket, struct, fcntl
>>> sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
>>> sockfd = sock.fileno()
>>> SIOCGIFADDR = 0x8915
>>>
>>> def get_ip(iface = 'eth0'):
... ifreq = struct.pack('16sH14s', iface, socket.AF_INET, '\x00'*14)
... try:
... res = fcntl.ioctl(sockfd, SIOCGIFADDR, ifreq)
... except:
... return None
... ip = struct.unpack('16sH2x4s8x', res)[2]
... return socket.inet_ntoa(ip)
...
>>> get_ip('eth0')
'10.80.40.234'
>>>

此方法仅适用于Windows操作系统。

def getIPAddresses():
 from ctypes import Structure, windll, sizeof
 from ctypes import POINTER, byref
 from ctypes import c_ulong, c_uint, c_ubyte, c_char
 MAX_ADAPTER_DESCRIPTION_LENGTH = 128
 MAX_ADAPTER_NAME_LENGTH = 256
 MAX_ADAPTER_ADDRESS_LENGTH = 8
 class IP_ADDR_STRING(Structure):
 pass
 LP_IP_ADDR_STRING = POINTER(IP_ADDR_STRING)
 IP_ADDR_STRING._fields_ = [
 ("next", LP_IP_ADDR_STRING),
 ("ipAddress", c_char * 16),
 ("ipMask", c_char * 16),
 ("context", c_ulong)]
 class IP_ADAPTER_INFO (Structure):
 pass
 LP_IP_ADAPTER_INFO = POINTER(IP_ADAPTER_INFO)
 IP_ADAPTER_INFO._fields_ = [
 ("next", LP_IP_ADAPTER_INFO),
 ("comboIndex", c_ulong),
 ("adapterName", c_char * (MAX_ADAPTER_NAME_LENGTH + 4)),
 ("description", c_char * (MAX_ADAPTER_DESCRIPTION_LENGTH + 4)),
 ("addressLength", c_uint),
 ("address", c_ubyte * MAX_ADAPTER_ADDRESS_LENGTH),
 ("index", c_ulong),
 ("type", c_uint),
 ("dhcpEnabled", c_uint),
 ("currentIpAddress", LP_IP_ADDR_STRING),
 ("ipAddressList", IP_ADDR_STRING),
 ("gatewayList", IP_ADDR_STRING),
 ("dhcpServer", IP_ADDR_STRING),
 ("haveWins", c_uint),
 ("primaryWinsServer", IP_ADDR_STRING),
 ("secondaryWinsServer", IP_ADDR_STRING),
 ("leaseObtained", c_ulong),
 ("leaseExpires", c_ulong)]
 GetAdaptersInfo = windll.iphlpapi.GetAdaptersInfo
 GetAdaptersInfo.restype = c_ulong
 GetAdaptersInfo.argtypes = [LP_IP_ADAPTER_INFO, POINTER(c_ulong)]
 adapterList = (IP_ADAPTER_INFO * 10)()
 buflen = c_ulong(sizeof(adapterList))
 rc = GetAdaptersInfo(byref(adapterList[0]), byref(buflen))
 if rc == 0:
 for a in adapterList:
 adNode = a.ipAddressList
 while True:
 ipAddr = adNode.ipAddress
 if ipAddr:
  yield ipAddr
 adNode = adNode.next
 if not adNode:
  break

使用第三方库

相关资源地址:https://github.com/ftao/python-ifcfg (支持本地下载)

import ifcfg
import json
 
for name, interface in ifcfg.interfaces().items():
 # do something with interface
 print interface['device']
 print interface['inet']
 print interface['inet6']
 print interface['netmask']
 print interface['broadcast']
 
default = ifcfg.default_interface()

总结

以上为本文介绍的全部内容。希望这些关于Python获取本地IP地址的方法能对您的学习或工作有所帮助。如有任何疑问,欢迎留言交流,感谢支持。

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

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 算法库。