Python實(shí)現(xiàn)獲取Windows設(shè)備信息
1. 基礎(chǔ)實(shí)現(xiàn)(常用但有局限)
在 Python 中,我們通常使用 uuid 和 socket 庫(kù)來(lái)快速獲取設(shè)備網(wǎng)絡(luò)標(biāo)識(shí)。
import uuid
import socket
# 獲取 MAC 地址 (基于 getnode)
mac = uuid.UUID(int=uuid.getnode()).hex[-12:].upper()
# 獲取主機(jī)名與 IP
hostname = socket.getfqdn(socket.gethostname())
ip_addr = socket.gethostbyname(hostname)
print(f"MAC: {mac}")
print(f"Host: {hostname}")
print(f"IP: {ip_addr}")
2. 核心問(wèn)題:為什么 MAC 地址會(huì)變化?
在安裝了 VMware 或 VirtualBox 等虛擬機(jī)軟件后,原本穩(wěn)定的腳本可能會(huì)輸出不同的 MAC 地址。原因如下:
虛擬網(wǎng)卡的干擾
uuid.getnode() 的原理是獲取硬件地址。安裝虛擬機(jī)后,系統(tǒng)會(huì)增加多個(gè)虛擬網(wǎng)卡(如 VMnet1, VMnet8)。
- 多網(wǎng)卡競(jìng)爭(zhēng):腳本可能會(huì)隨機(jī)抓取到虛擬網(wǎng)卡的 MAC 地址,而非物理網(wǎng)卡(WiFi/以太網(wǎng))的地址。
- 優(yōu)先級(jí)變動(dòng):當(dāng)物理網(wǎng)卡斷開(kāi)(如拔掉網(wǎng)線(xiàn))時(shí),系統(tǒng)可能會(huì)將虛擬網(wǎng)卡作為默認(rèn)接口返回。
隨機(jī)地址回退機(jī)制
根據(jù) RFC 4122 協(xié)議,如果 uuid.getnode() 無(wú)法獲取到真實(shí)硬件地址,它會(huì)隨機(jī)生成一個(gè) 48 位的值。
識(shí)別方法:檢查 MAC 地址的第一個(gè)字節(jié)。如果其最低有效位為 1(即第二個(gè)字符為 1, 3, 5, 7, 9, B, D, F 之一),說(shuō)明這是一個(gè)隨機(jī)地址。
3. 更穩(wěn)定的替代方案:硬件 UUID
如果目的是為了唯一識(shí)別設(shè)備(如軟件授權(quán)、指紋識(shí)別),建議獲取 Windows 主板的 UUID,這不會(huì)受網(wǎng)卡變動(dòng)或虛擬機(jī)的影響。
推薦方案 (Python 調(diào)用 WMIC)
import subprocess
def get_windows_uuid():
try:
# 執(zhí)行 wmic 命令獲取主板唯一標(biāo)識(shí)
cmd = 'wmic path win32_computersystemproduct get uuid'
uuid_str = subprocess.check_output(cmd, shell=True).decode().split('\n')[1].strip()
return uuid_str
except Exception as e:
return f"Error: {e}"
print(f"設(shè)備硬件 UUID: {get_windows_uuid()}")
4. 總結(jié)與建議
| 標(biāo)識(shí)符 | 穩(wěn)定性 | 適用場(chǎng)景 | 風(fēng)險(xiǎn) |
|---|---|---|---|
| MAC 地址 | 一般 | 網(wǎng)絡(luò)通信、局域網(wǎng)識(shí)別 | 易受虛擬機(jī)、多網(wǎng)卡、隨機(jī)化影響 |
| 主機(jī)名 | 低 | 內(nèi)部網(wǎng)絡(luò)標(biāo)識(shí) | 用戶(hù)可隨時(shí)更改 |
| 硬件 UUID | 極高 | 軟件授權(quán)、設(shè)備指紋 | 需系統(tǒng)權(quán)限(通常 cmd 即可) |
筆記提示:
- 在 Windows 上運(yùn)行 Python 腳本時(shí),確保已將 Python 添加至系統(tǒng)變量
PATH。 - 如果必須獲取物理網(wǎng)卡的 MAC,建議使用
psutil庫(kù)遍歷所有網(wǎng)卡并過(guò)濾掉包含 "VMware" 或 "Virtual" 字樣的接口。
5.知識(shí)擴(kuò)展
在 Windows 上,獲取設(shè)備信息最高效的方式是使用 WMI,它能直接訪(fǎng)問(wèn)系統(tǒng)底層的硬件和軟件配置。同時(shí),Python 的 platform 和 psutil 模塊可以作為補(bǔ)充,獲取一些基礎(chǔ)的系統(tǒng)信息。
下面是一個(gè)結(jié)構(gòu)化對(duì)比,幫助你快速定位最適合的方法:
主要實(shí)現(xiàn)方法對(duì)比
| 方法/工具 | 核心原理 | 主要優(yōu)勢(shì) | 潛在限制 | 使用建議 |
|---|---|---|---|---|
| WMI (wmi庫(kù)) | 通過(guò)封裝好的 API 訪(fǎng)問(wèn) Windows 原生管理接口。 | 功能最強(qiáng)大,能獲取幾乎所有系統(tǒng)信息(軟件/硬件/配置)。 | 需要安裝第三方庫(kù)。 | 首選,用于獲取CPU、主板、硬盤(pán)等底層硬件信息。 |
| Win32 API (pywin32庫(kù)) | 直接調(diào)用 Windows API,交互層級(jí)更低。 | 靈活,能實(shí)現(xiàn)一些 WMI 不便或無(wú)法完成的操作。 | 安裝相對(duì)復(fù)雜,需要pywin32庫(kù)。 | 高級(jí)或特定場(chǎng)景的補(bǔ)充。 |
| 系統(tǒng)組件 (platform模塊) | Python 內(nèi)置,跨平臺(tái),無(wú)需安裝。 | 無(wú)額外依賴(lài),代碼簡(jiǎn)單。 | 功能有限,主要用于操作系統(tǒng)版本、計(jì)算機(jī)名、處理器架構(gòu)等基礎(chǔ)信息。 | 獲取通用系統(tǒng)信息,或用于跨平臺(tái)代碼中判斷操作系統(tǒng)類(lèi)型。 |
| subprocess + WMIC | 調(diào)用 Windows 命令行工具 wmic,解析其輸出。 | 零額外依賴(lài)(除 subprocess)。 | 輸出為文本,需要解析,且 wmic 可能在未來(lái)的 Windows 版本中被棄用。 | 需要基本的系統(tǒng)信息,但不能或不想安裝 wmi 庫(kù)的輕量級(jí)場(chǎng)景。 |
| 跨平臺(tái)庫(kù) (psutil等) | 第三方庫(kù),提供跨平臺(tái)的系統(tǒng)信息獲取功能。 | 跨平臺(tái)(Windows/Linux/macOS),API 統(tǒng)一,獲取實(shí)時(shí)數(shù)據(jù)能力強(qiáng)。 | 可能獲取不到某些特定硬件的底層序列號(hào)。 | 需要監(jiān)控CPU、內(nèi)存、磁盤(pán)、網(wǎng)絡(luò)等實(shí)時(shí)資源時(shí)作為重要補(bǔ)充。 |
詳細(xì)代碼示例及解析
準(zhǔn)備工作:安裝依賴(lài)庫(kù)
對(duì)于非 Python 內(nèi)置的模塊,你需要先進(jìn)行安裝。建議使用 pip 在命令行中進(jìn)行安裝。
# 建議使用 python -m pip 來(lái)確保安裝到正確的 Python 環(huán)境 python -m pip install wmi pywin32 psutil
下面是兩種主流的實(shí)現(xiàn)方式及核心代碼示例。
方式一:使用 wmi 模塊(獲取CPU、主板、硬盤(pán)信息)
這是獲取 Windows 硬件信息最常用、最強(qiáng)大的方法。
import wmi
try:
# 初始化WMI客戶(hù)端
c = wmi.WMI()
except wmi.x_wmi as e:
print(f"初始化WMI失敗: {e}")
exit()
# 1. 獲取CPU信息
print("\n[CPU信息]")
for cpu in c.Win32_Processor():
# .Caption 或 .Name 通常包含CPU的完整型號(hào)
print(f" 型號(hào): {cpu.Name.strip()}")
print(f" 核心數(shù): {cpu.NumberOfCores}")
print(f" 線(xiàn)程數(shù): {cpu.NumberOfLogicalProcessors}")
# 2. 獲取主板信息
print("\n[主板信息]")
for board in c.Win32_BaseBoard():
# .Product 通常是主板的型號(hào)
print(f" 型號(hào): {board.Product}")
# .Manufacturer 是制造商
print(f" 制造商: {board.Manufacturer}")
# 3. 獲取硬盤(pán)信息
print("\n[硬盤(pán)信息]")
for disk in c.Win32_DiskDrive():
# .Model 是硬盤(pán)型號(hào),.SerialNumber 是唯一的序列號(hào)
print(f" 型號(hào): {disk.Model}")
print(f" 序列號(hào): {disk.SerialNumber}")
print(f" 大小: {int(disk.Size) // (1024**3)} GB")代碼解析:
c = wmi.WMI()這條語(yǔ)句建立與 Windows 管理規(guī)范的連接,是后續(xù)所有查詢(xún)的基礎(chǔ)。Win32_Processor,Win32_BaseBoard,Win32_DiskDrive是 WMI 中用于查詢(xún)CPU、主板和硬盤(pán)信息的類(lèi)。- 你可以通過(guò)修改類(lèi)名來(lái)獲取其他硬件信息,例如
Win32_PhysicalMemory可以查詢(xún)內(nèi)存條信息。
方式二:結(jié)合 platform 和 psutil 獲取系統(tǒng)概況
這兩個(gè)庫(kù)主要用于獲取系統(tǒng)概要信息和系統(tǒng)級(jí)的運(yùn)行狀態(tài),是跨平臺(tái)信息獲取的得力助手。
import psutil
import platform
print("[操作系統(tǒng)信息]")
# platform.system() 獲取操作系統(tǒng)名稱(chēng),如 'Windows', 'Linux'[reference:12]
print(f" 系統(tǒng): {platform.system()}")
# platform.release() 獲取操作系統(tǒng)的主版本號(hào)[reference:13]
print(f" 版本: {platform.release()}")
# platform.processor() 獲取處理器的信息字符串
print(f" 處理器標(biāo)識(shí): {platform.processor()}")
print(f" 計(jì)算機(jī)名: {platform.node()}")
print(f" 系統(tǒng)架構(gòu): {platform.machine()}")
print("\n[系統(tǒng)運(yùn)行狀態(tài)]")
# psutil.virtual_memory().total 獲取系統(tǒng)總內(nèi)存,單位是字節(jié),需要轉(zhuǎn)換為合適的單位。
total_memory = psutil.virtual_memory().total
print(f" 總內(nèi)存: {total_memory // (1024**3)} GB")
# psutil.disk_usage('/') 獲取根目錄的磁盤(pán)使用情況。你可以改變路徑來(lái)查看其他盤(pán)符。
disk = psutil.disk_usage('/')
print(f" 磁盤(pán) (C:): 總計(jì) {disk.total // (1024**3)}GB, 已用 {disk.used // (1024**3)}GB")關(guān)鍵點(diǎn):
platform模塊的相關(guān)函數(shù)是獲取跨平臺(tái)系統(tǒng)信息的基礎(chǔ)。psutil在獲取動(dòng)態(tài)系統(tǒng)數(shù)據(jù)時(shí)非常強(qiáng)大,例如psutil.virtual_memory()和psutil.disk_usage()能提供實(shí)時(shí)的內(nèi)存和磁盤(pán)使用情況。
方式三:使用 uuid 模塊生成唯一設(shè)備標(biāo)識(shí)符
這個(gè)技術(shù)與前兩種不同,它不是為了獲取硬件清單,而是為了生成一個(gè)相對(duì)穩(wěn)定的設(shè)備唯一碼,常用于軟件授權(quán)等場(chǎng)景。
import uuid
# 獲取計(jì)算機(jī)的MAC地址并生成一個(gè)UUID[reference:16]
node_uuid = uuid.UUID(int=uuid.getnode())
# 取UUID的后12位作為機(jī)器碼
machine_code = node_uuid.hex[-12:]
print(f"\n[生成的機(jī)器碼]")
print(f" 唯一ID: {machine_code}")核心要點(diǎn):這種方法依賴(lài)MAC地址,如果網(wǎng)卡變更或MAC地址被修改,這個(gè)ID也會(huì)隨之改變。此外,也可以調(diào)用系統(tǒng)工具(如 wmic csproduct get uuid)獲取更穩(wěn)定的主板UUID。
注意事項(xiàng)與安全警示
在編寫(xiě)代碼時(shí),做好錯(cuò)誤處理和權(quán)限管理,能讓你的程序更健壯。
- 管理員權(quán)限:訪(fǎng)問(wèn)某些硬件信息(如硬盤(pán)序列號(hào))可能需要程序以管理員權(quán)限運(yùn)行,否則可能會(huì)返回
None或拋出異常。 - 虛擬機(jī)環(huán)境:在虛擬機(jī)中,獲取到的硬件信息(特別是序列號(hào))可能是虛擬化軟件模擬的固定值,多臺(tái)機(jī)器可能相同。
- 錯(cuò)誤處理:務(wù)必使用
try...except語(yǔ)句塊來(lái)處理wmi初始化失敗、注冊(cè)表鍵值找不到等異常情況。 - 隱私合規(guī):在收集和傳輸任何硬件信息前,請(qǐng)務(wù)必告知用戶(hù)并獲得其同意,遵守相關(guān)的隱私法規(guī)。
- 兼容性預(yù)案:
wmic命令行工具可能在未來(lái)的 Windows 版本中被移除。如有需要,你可以將代碼中的wmic調(diào)用封裝成函數(shù),以便將來(lái)平滑遷移到Get-WmiObject等 PowerShell 命令。
你對(duì)哪部分的實(shí)現(xiàn),或是針對(duì)特定硬件的查詢(xún)更感興趣呢?我可以進(jìn)一步為你提供更詳細(xì)的代碼示例。
到此這篇關(guān)于Python實(shí)現(xiàn)獲取Windows設(shè)備信息的文章就介紹到這了,更多相關(guān)Python獲取Windows設(shè)備信息內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 使用python查找windows系統(tǒng)中所有程序的安裝信息
- python使用wmi模塊獲取windows下的系統(tǒng)信息 監(jiān)控系統(tǒng)
- python使用wmi模塊獲取windows下硬盤(pán)信息的方法
- python使用WMI檢測(cè)windows系統(tǒng)信息、硬盤(pán)信息、網(wǎng)卡信息的方法
- python在windows下實(shí)現(xiàn)ping操作并接收返回信息的方法
- Python獲取本機(jī)所有網(wǎng)卡IP/MAC地址的三種方法
- 如何用Python獲取計(jì)算機(jī)名,ip地址,mac地址
- Python3獲取電腦IP、主機(jī)名、Mac地址的方法示例
- python獲取本機(jī)mac地址和ip地址的方法
相關(guān)文章
Python基于回溯法子集樹(shù)模板解決取物搭配問(wèn)題實(shí)例
這篇文章主要介紹了Python基于回溯法子集樹(shù)模板解決取物搭配問(wèn)題,簡(jiǎn)單描述了搭配問(wèn)題并結(jié)合實(shí)例形式分析了Python使用回溯法子集樹(shù)模板解決取物搭配問(wèn)題的具體步驟與相關(guān)操作技巧,需要的朋友可以參考下2017-09-09
Python獲取時(shí)間范圍內(nèi)日期列表和周列表的函數(shù)
這篇文章主要介紹了Python獲取時(shí)間范圍內(nèi)日期列表和周列表的函數(shù),文中給大家提到了python獲取日期的周數(shù) ,需要的朋友可以參考下2019-08-08
通過(guò)Python掃描代碼關(guān)鍵字并進(jìn)行預(yù)警的實(shí)現(xiàn)方法
這篇文章主要介紹了通過(guò)Python掃描代碼關(guān)鍵字并進(jìn)行預(yù)警的實(shí)現(xiàn)方法,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-05-05
Python抓取框架Scrapy爬蟲(chóng)入門(mén):頁(yè)面提取
Scrapy吸引人的地方在于它是一個(gè)框架,任何人都可以根據(jù)需求方便的修改,下面這篇文章主要給大家介紹了關(guān)于Python抓取框架Scrapy爬蟲(chóng)入門(mén)之頁(yè)面提取的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下。2017-12-12
django admin管理工具自定義時(shí)間區(qū)間篩選器DateRangeFilter介紹
這篇文章主要介紹了django admin管理工具自定義時(shí)間區(qū)間篩選器DateRangeFilter介紹,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-05-05

