如何在Python中独立于平台且仅使用标准库找到本地IP地址(即192.168.x.x或10.0.x.x)?
如何在Python中独立于平台且仅使用标准库找到本地IP地址(即192.168.x.x或10.0.x.x)?
对于Linux环境,读取/proc/net/tcp文件,第二列(本地地址)和第三列(远程地址)将以十六进制格式给出IP地址。
提示:如果第二列为零(00000000:0000),则表示它是一个监听端口 :)
https://github.com/romol0s/python/blob/master/general/functions/getTcpListenIpsByPort.py
https://www.kernel.org/doc/Documentation/networking/proc_net_tcp.txt
另一种与之前答案不同的变体,可以保存为可执行脚本,命名为my-ip-to
:
#!/usr/bin/env python
import sys, socket
if len(sys.argv) > 1:
for remote_host in sys.argv[1:]:
# determine local host ip by outgoing test to another host
# use port 9 (discard protocol - RFC 863) over UDP4
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
s.connect((remote_host, 9))
my_ip = s.getsockname()[0]
print(my_ip, flush=True)
else:
import platform
my_name = platform.node()
my_ip = socket.gethostbyname(my_name)
print(my_ip)
它可以接受任意数量的远程主机,并逐个打印出到达它们的本地IP地址:
$ my-ip-to z.cn g.cn localhost
192.168.11.102
192.168.11.102
127.0.0.1
$
当没有参数时,打印最佳结果。
$ my-ip-to
192.168.11.102
import socket
def get_ip():
"""
Idea from https://dev59.com/m3VC5IYBdhLWcg3w1E_w#28950776
"""
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.settimeout(0)
# Doesn’t even have to be reachable.
s.connect_ex(("10.254.254.254", 1))
ip = s.getsockname()[0]
ip = "127.0.0.1" if ip == "0.0.0.0" else ip
s.close()
return ip
IP = get_ip()
print(IP)
仅获取当前活动的无线局域网(WLAN)即计算机在WiFi路由器或网络交换机上的IP地址。
注意:这不是设备的公共IP地址,也不涉及任何外部请求、包或公共API。
核心思想是解析shell命令:ipconfig
或Linux上的ifconfig的输出。我们使用子进程来获取输出。
def wlan_ip():
import subprocess
result=subprocess.run('ipconfig',stdout=subprocess.PIPE,text=True).stdout.lower()
scan=0
for i in result.split('\n'):
if 'wireless' in i: #use "wireless" or wireless adapters and "ethernet" for wired connections
scan=1
if scan:
if 'ipv4' in i:
return i.split(':')[1].strip()
print(wlan_ip())
我们会得到以下输出,我们使用Python的subprocess output进行了捕获。
C:\Users\dell>ipconfig
Wireless LAN adapter Wi-Fi:
Connection-specific DNS Suffix . :
Link-local IPv6 Address . . . . . : fe80::f485:4a6a:e7d5:1b1c%4
IPv4 Address. . . . . . . . . . . : 192.168.0.131
Subnet Mask . . . . . . . . . . . : 255.255.255.0
Default Gateway . . . . . . . . . : 192.168.0.1
我们使用Python解析了字符串,以一种方式选择当前网络上无线适配器的IP。
scan
并将三个 if 语句替换为一个来简化: if 'wireless' in i and 'ipv4' in i:
- Georgypyroute2是一个非常好的库,可以用来获取不仅仅是IP地址,还可以获取网关信息和其他有用的信息。 以下代码可以获取任何接口的IPv4地址。
from pyroute2 import IPRoute
ip = IPRoute()
def get_ipv4_address(intf):
return dict(ip.get_addr(label=intf)[0]['attrs'])['IFA_LOCAL']
print(get_ipv4_address('eth0'))
简单而甜美!
def getip():
import socket
hostname= socket.gethostname()
ip=socket.gethostbyname(hostname)
return(ip)
import socket
print next(i[4][0] for i in socket.getaddrinfo(
socket.gethostname(), 80) if '127.' not in i[4][0] and '.' in i[4][0]);"
#!/usr/bin/env python3
from urllib.request import urlopen
def public_ip():
data = urlopen('https://api.ipify.org').read()
return str(data, encoding='utf-8')
print(public_ip())
响应还可以以 JSON 和 JSONP 格式获取。
Github 上有一个名为 ipify 的 Python 库。
import socket
print(socket.gethostbyname(socket.getfqdn()))
@fatal_error 的解决方案应该被接受为答案!这是他的解决方案在 Node.js 中的实现,以防有人需要:
const dgram = require('dgram');
async function get_local_ip() {
const s = new dgram.createSocket('udp4');
return new Promise((resolve, reject) => {
try {
s.connect(1, '8.8.8.8', function () {
const ip = s.address();
s.close();
resolve(ip.address)
});
} catch (e) {
console.error(e);
s.close();
reject(e);
}
})
}
ifconfig -a
命令并使用其输出... - Fredrik Pihlip addr
更加适合(而且更容易解析)。 - phihag