Python實現(xiàn)獲取本機(jī)網(wǎng)卡的MAC地址,IP地址和路由表
一、獲取Mac地址
1、單個網(wǎng)卡
>>> import uuid >>> address = hex(uuid.getnode())[2:] >>> '-'.join(address[i:i+2] for i in range(0, len(address), 2)) 'f0-03-8c-09-8c-34'
2、獲取多網(wǎng)卡MAC地址
使用pip安裝Python擴(kuò)展庫psutil,運(yùn)行以下的代碼:
from psutil import net_if_addrs
for k, v in net_if_addrs().items():
for item in v:
address = item[1]
if '-' in address and len(address)==17:
print(address)二、獲取本機(jī)IP地址
1、windows下:
Python標(biāo)準(zhǔn)庫socket中有可以獲取本機(jī)IPV4地址的方法,下面是網(wǎng)上非常常見的一種用法:
>>> import socket >>> hostname = socket.gethostname() >>> hostname 'DESKTOP-I734J3O' >>> socket.gethostbyname(hostname) '192.168.0.103'
2、Mac下:
上面的代碼在Windows下運(yùn)行良好,但是無意中發(fā)現(xiàn)在Mac系統(tǒng)下運(yùn)行不正常,返回的是本機(jī)回環(huán)地址127.0.0.1,而不是真正的IP地址。經(jīng)過查閱大量資料,終于發(fā)現(xiàn)socket模塊中另一個函數(shù)的妙用,那就是getaddrinfo()函數(shù),該函數(shù)用法為getaddrinfo(host, port, family=0, type=0, proto=0, flags=0),返回值是一個五元組的列表,該五元組形式為(family, type, proto, canonname, sockaddr),其中最后一個元素sockaddr對于IPV4協(xié)議是(IP address, port)形式的元組,而對于IPV6協(xié)議是(address, port, flow info, scope id)形式的元組,也就是說,不管是IPV4還是IPV6,上面的函數(shù)都可以正確地獲取IP地址。
于是,繼續(xù)上面的代碼:
>>> addrs = socket.getaddrinfo(hostname,None)
>>> for item in addrs:
print(item)
(, 0, 0, '', ('fe80::b976:b065:27d:3747%10', 0, 0, 10))
(, 0, 0, '', ('fe80::1456:951:2418:27cf%7', 0, 0, 7))
(, 0, 0, '', ('192.168.0.103', 0))
(, 0, 0, '', ('2001:0:9d38:6ab8:1456:951:2418:27cf', 0, 0, 0))如此便可以獲取本機(jī)所有IPV4和IPV6地址,如果只想獲取IPV4地址,再繼續(xù)執(zhí)行下面的代碼:
>>> [item[4][0] for item in addrs if ':' not in item[4][0]][0] '192.168.0.103'
三、路由表
方法:采用ARP協(xié)議獲取局域網(wǎng)內(nèi)所有計算機(jī)的IP地址與MAC地址,思路是使用系統(tǒng)命令arp獲取ARP表并生成文本文件,然后從文件中讀取和解析信息。
import os from socket import gethostbyname, gethostname
獲取本機(jī)IP地址
host = gethostbyname(gethostname())
獲取ARP表
os.system('arp -a > temp.txt')
with open('temp.txt') as fp:
for line in fp:
line = line.split()[:2]
if line and\
line[0].startswith(host[:4]) and\
(not line[0].endswith('255')):
print(':'.join(line))四、方法補(bǔ)充
在 Python 中獲取本機(jī)網(wǎng)卡的 MAC 地址、IP 地址和路由表,可以使用跨平臺庫 psutil 和 netifaces,同時結(jié)合系統(tǒng)命令作為備選方案。下面給出完整的實現(xiàn)示例。
安裝所需庫
pip install psutil netifaces
psutil用于獲取網(wǎng)卡信息(MAC、IP),netifaces用于獲取路由表(網(wǎng)關(guān)等)。
獲取所有網(wǎng)卡的 MAC 地址和 IP 地址
使用 psutil.net_if_addrs() 可以獲取每個網(wǎng)卡的所有地址(包括 IPv4、IPv6、MAC 等)。
import psutil
def get_network_interfaces():
"""獲取所有網(wǎng)卡的 MAC 地址和 IPv4 地址"""
interfaces = {}
for iface, addrs in psutil.net_if_addrs().items():
# 跳過虛擬、回環(huán)等無用網(wǎng)卡(可根據(jù)需要調(diào)整)
if iface.startswith(('lo', 'Loopback', 'vEthernet', 'docker', 'vboxnet')):
continue
mac = None
ipv4 = None
for addr in addrs:
if addr.family == psutil.AF_LINK: # MAC 地址
mac = addr.address
elif addr.family == socket.AF_INET: # IPv4 地址
ipv4 = addr.address
if mac or ipv4:
interfaces[iface] = {'mac': mac, 'ipv4': ipv4}
return interfaces
if __name__ == '__main__':
import socket
for name, info in get_network_interfaces().items():
print(f"網(wǎng)卡: {name}")
print(f" MAC地址: {info['mac']}")
print(f" IPv4地址: {info['ipv4']}")輸出示例:
網(wǎng)卡: eth0
MAC地址: 00:15:5d:01:02:03
IPv4地址: 192.168.1.100
獲取路由表
獲取路由表在不同操作系統(tǒng)上的方法不同。推薦使用 netifaces 獲取默認(rèn)網(wǎng)關(guān),或調(diào)用系統(tǒng)命令獲取詳細(xì)路由表。
方法1:使用 netifaces 獲取默認(rèn)網(wǎng)關(guān)及路由條目
import netifaces
def get_gateways():
"""獲取默認(rèn)網(wǎng)關(guān)"""
gateways = netifaces.gateways()
default = gateways['default']
print("默認(rèn)網(wǎng)關(guān):")
for family, (gw, iface) in default.items():
print(f" 協(xié)議: {family}, 網(wǎng)關(guān): {gw}, 網(wǎng)卡: {iface}")
def get_routing_table():
"""獲取路由表(Linux/Unix 使用 /proc/net/route,Windows 調(diào)用 route print)"""
import platform
import subprocess
system = platform.system()
if system == 'Linux':
# 解析 /proc/net/route
with open('/proc/net/route', 'r') as f:
lines = f.readlines()[1:] # 跳過標(biāo)題行
print("路由表 (Linux):")
for line in lines:
parts = line.strip().split()
if len(parts) >= 4:
iface = parts[0]
dest = int(parts[1], 16)
gateway = int(parts[2], 16)
# 轉(zhuǎn)換 IP 格式
import socket, struct
dest_ip = socket.inet_ntoa(struct.pack('<L', dest))
gw_ip = socket.inet_ntoa(struct.pack('<L', gateway))
print(f" {iface} -> 目標(biāo): {dest_ip}, 網(wǎng)關(guān): {gw_ip}")
elif system == 'Windows':
# 調(diào)用 route print 命令
result = subprocess.run(['route', 'print'], capture_output=True, text=True)
print(result.stdout)
else:
print("不支持的系統(tǒng),請使用 netstat -rn 命令查看")
if __name__ == '__main__':
get_gateways()
get_routing_table()注意:在 Windows 上,netifaces.gateways() 可能返回空字典,需要管理員權(quán)限才能獲取真實路由表。上面的 get_routing_table() 通過調(diào)用 route print 命令解決。
完整示例(跨平臺)
以下代碼整合了獲取 MAC/IP 以及路由信息(簡單顯示默認(rèn)網(wǎng)關(guān)和部分路由):
import psutil
import netifaces
import socket
import platform
import subprocess
def get_network_interfaces():
"""返回所有活動網(wǎng)卡的名稱、MAC、IPv4"""
interfaces = {}
for iface, addrs in psutil.net_if_addrs().items():
# 跳過常見虛擬/回環(huán)設(shè)備
skip = ('lo', 'Loopback', 'vEthernet', 'docker', 'vboxnet', 'VMware', 'Virtual')
if iface.startswith(skip):
continue
mac = None
ipv4 = None
for addr in addrs:
if addr.family == psutil.AF_LINK:
mac = addr.address
elif addr.family == socket.AF_INET:
ipv4 = addr.address
if mac or ipv4:
interfaces[iface] = {'mac': mac, 'ipv4': ipv4}
return interfaces
def get_default_gateway():
"""獲取默認(rèn)網(wǎng)關(guān)(跨平臺)"""
try:
gateways = netifaces.gateways()
default = gateways.get('default', {})
if default:
# 典型結(jié)構(gòu):{2: ('192.168.1.1', 'eth0')}
for family, (gw, iface) in default.items():
if family == socket.AF_INET:
return gw, iface
except Exception:
pass
# 備選方案:調(diào)用系統(tǒng)命令
system = platform.system()
if system == 'Windows':
result = subprocess.run(['route', 'print', '0.0.0.0'], capture_output=True, text=True)
# 簡單解析(實際可以更嚴(yán)謹(jǐn))
for line in result.stdout.splitlines():
if '0.0.0.0' in line and '255.255.255.0' in line:
parts = line.split()
if len(parts) >= 3:
return parts[2], parts[-1]
elif system == 'Linux':
with open('/proc/net/route', 'r') as f:
for line in f:
parts = line.strip().split()
if len(parts) >= 4 and parts[1] == '00000000': # 目標(biāo) 0.0.0.0
import struct, socket
gateway = socket.inet_ntoa(struct.pack('<L', int(parts[2], 16)))
return gateway, parts[0]
return None, None
if __name__ == '__main__':
print("=== 網(wǎng)卡信息 ===")
ifaces = get_network_interfaces()
for name, info in ifaces.items():
print(f"{name}: MAC={info['mac']}, IPv4={info['ipv4']}")
print("\n=== 默認(rèn)網(wǎng)關(guān) ===")
gw, iface = get_default_gateway()
print(f"網(wǎng)關(guān): {gw}, 網(wǎng)卡: {iface}")
print("\n=== 完整路由表(簡要) ===")
# 直接調(diào)用系統(tǒng)路由表顯示命令
if platform.system() == 'Windows':
subprocess.run(['route', 'print'], shell=True)
else:
subprocess.run(['route', '-n'], shell=True)注意事項
- 權(quán)限問題:在 Windows 上獲取完整路由表可能需要以管理員身份運(yùn)行 Python 腳本。
- 虛擬網(wǎng)卡:自動跳過了常見虛擬設(shè)備(如 Docker、VMware),如需獲取可刪除
skip判斷。 - IPv6 地址:上述代碼只獲取 IPv4,需要 IPv6 可增加
addr.family == socket.AF_INET6判斷。 - 跨平臺:
psutil和netifaces在 Linux/Windows/macOS 上均可工作,但路由表解析部分需要區(qū)分系統(tǒng)。
到此這篇關(guān)于Python實現(xiàn)獲取本機(jī)網(wǎng)卡的MAC地址,IP地址和路由表的文章就介紹到這了,更多相關(guān)Python獲取網(wǎng)卡MAC地址內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
django 自定義filter 判斷if var in list的例子
今天小編就為大家分享一篇django 自定義filter 判斷if var in list的例子,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-08-08
Python實現(xiàn)數(shù)通設(shè)備端口使用情況監(jiān)控實例
這篇文章主要介紹了Python實現(xiàn)數(shù)通設(shè)備端口使用情況監(jiān)控的方法,涉及Python針對設(shè)備監(jiān)控的操作技巧,具有一定參考借鑒價值,需要的朋友可以參考下2015-07-07
python編程matplotlib交互繪制Julia集示例解析
matplotlib的Show面板中提供了放大、移動等交互式操作,但也未能涵蓋所有的交互需求,比如希望通過mandelbrot集上的一點(diǎn)來生成對應(yīng)的Julia集2021-10-10
python通過curl實現(xiàn)訪問deepseek的API
這篇文章主要為大家詳細(xì)介紹了python如何通過curl實現(xiàn)訪問deepseek的API,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2025-05-05
Python實現(xiàn)對比Word文檔差異的三種方式小結(jié)
在日常工作中,Word 文檔對比功能就尤為重要,這篇文章主要來和大家探討如何使用?Python 實現(xiàn)對比 Word 文檔差異,感興趣的小伙伴可以了解下2025-08-08
python實現(xiàn)隨機(jī)調(diào)用一個瀏覽器打開網(wǎng)頁
下面小編就為大家分享一篇python實現(xiàn)隨機(jī)調(diào)用一個瀏覽器打開網(wǎng)頁,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-04-04

