如何找到本地IP地址(即192.168.x。x或10.0.x.x)在Python平台独立,只使用标准库?


当前回答

恐怕除了连接到另一台计算机并让它把你的IP地址发送给你之外,没有任何好的独立于平台的方法来做到这一点。例如:findmyipaddress。注意,如果你需要一个NAT后的IP地址,除非你所连接的计算机也是NAT后的IP地址,这是行不通的。

下面是一个适用于Linux的解决方案:获取与网络接口关联的IP地址。

其他回答

import socket
socket.gethostbyname(socket.getfqdn())
import socket
print(socket.gethostbyname(socket.getfqdn()))

Netifaces可通过PIP和easy_install获得。(我知道,它不在基础,但它可能值得安装。)

Netifaces在不同平台上确实有一些奇怪之处:

localhost/loop-back接口可能并不总是包含在内(Cygwin)。 地址按协议列出(例如IPv4, IPv6),协议按接口列出。在某些系统(Linux)上,每个协议-接口对都有自己的关联接口(使用interface_name:n表示法),而在其他系统(Windows)上,单个接口将有每个协议的地址列表。在这两种情况下都有一个协议列表,但它可能只包含一个元素。

下面是一些netifaces代码:

import netifaces

PROTO = netifaces.AF_INET   # We want only IPv4, for now at least

# Get list of network interfaces
# Note: Can't filter for 'lo' here because Windows lacks it.
ifaces = netifaces.interfaces()

# Get all addresses (of all kinds) for each interface
if_addrs = [netifaces.ifaddresses(iface) for iface in ifaces]

# Filter for the desired address type
if_inet_addrs = [addr[PROTO] for addr in if_addrs if PROTO in addr]

iface_addrs = [s['addr'] for a in if_inet_addrs for s in a if 'addr' in s]
# Can filter for '127.0.0.1' here.

上面的代码没有将地址映射回接口名(对于动态生成ebtables/iptables规则很有用)。所以这里有一个版本,它将上述信息和接口名称保存在一个元组中:

import netifaces

PROTO = netifaces.AF_INET   # We want only IPv4, for now at least

# Get list of network interfaces
ifaces = netifaces.interfaces()

# Get addresses for each interface
if_addrs = [(netifaces.ifaddresses(iface), iface) for iface in ifaces]

# Filter for only IPv4 addresses
if_inet_addrs = [(tup[0][PROTO], tup[1]) for tup in if_addrs if PROTO in tup[0]]

iface_addrs = [(s['addr'], tup[1]) for tup in if_inet_addrs for s in tup[0] if 'addr' in s]

而且,不,我不喜欢列表理解。这些天我的大脑就是这么运转的。

下面的代码段将全部打印出来:

from __future__ import print_function  # For 2.x folks
from pprint import pprint as pp

print('\nifaces = ', end='')
pp(ifaces)

print('\nif_addrs = ', end='')
pp(if_addrs)

print('\nif_inet_addrs = ', end='')
pp(if_inet_addrs)

print('\niface_addrs = ', end='')
pp(iface_addrs)

享受吧!

使用新引入的asyncio包的Python 3.4版本。

async def get_local_ip():
    loop = asyncio.get_event_loop()
    transport, protocol = await loop.create_datagram_endpoint(
        asyncio.DatagramProtocol,
        remote_addr=('8.8.8.8', 80))
    result = transport.get_extra_info('sockname')[0]
    transport.close()
    return result

这是基于UnkwnTech的精彩回答。

通过命令行utils产生“干净”输出的一个简单方法:

import commands
ips = commands.getoutput("/sbin/ifconfig | grep -i \"inet\" | grep -iv \"inet6\" | " +
                         "awk {'print $2'} | sed -ne 's/addr\:/ /p'")
print ips

它将显示系统上的所有IPv4地址。