Python硬件检测CPU、内存、硬盘、显卡等组件检测实战步骤

52 阅读10分钟

在系统监控、硬件诊断、自动化运维和桌面应用开发中,获取硬件设备信息是高频需求。无论是排查硬件故障、监控系统资源占用,还是开发硬件适配的软件,都需要精准采集CPU、内存、硬盘、显卡等核心组件的信息。

一、准备工作:安装必备依赖库

Python检测硬件主要依赖跨平台的系统监控库和硬件信息解析库,不同系统(Windows/Linux)需安装的依赖略有差异。执行以下命令安装核心库,部分系统级工具需单独安装(如Linux的dmidecode)。

1.1 通用依赖安装

# Windows/Linux通用基础库
pip install psutil py-cpuinfo GPUtil netifaces

1.2 系统专属依赖

  • Windows系统:需安装pywin32调用Windows WMI(Windows Management Instrumentation)接口,获取主板、USB设备等底层信息:
    pip install pywin32
    
  • Linux系统:需安装pyudev解析硬件设备信息,同时通过包管理器安装系统工具(如dmidecode获取主板信息、smartmontools检测硬盘健康):
    pip install pyudev
    # Debian/Ubuntu系统安装系统工具
    sudo apt install dmidecode smartmontools
    

库功能说明

  • psutil:核心跨平台库,获取CPU、内存、硬盘、网络的基础资源信息;
  • py-cpuinfo:解析CPU型号、架构、指令集等详细信息;
  • GPUtil:专门检测NVIDIA显卡的型号、显存、使用率;
  • netifaces:获取网络适配器的IP、MAC地址等配置;
  • pywin32(Windows):调用WMI接口获取主板、BIOS、USB设备信息;
  • pyudev(Linux):通过udev子系统获取硬件设备的底层信息。

二、CPU检测:型号、核心数与实时状态

CPU是硬件核心,检测分为静态信息(型号、核心数、架构)和动态信息(使用率、温度)。

2.1 获取CPU静态信息

使用py-cpuinfo解析CPU的型号、架构等细节,psutil获取物理核心数和逻辑线程数(超线程):

import cpuinfo
import psutil

def get_cpu_static_info():
    """获取CPU静态信息:型号、架构、核心数等"""
    cpu_detail = cpuinfo.get_cpu_info()
    # 物理核心数与逻辑线程数
    physical_cores = psutil.cpu_count(logical=False)
    logical_cores = psutil.cpu_count(logical=True)
    
    cpu_info = {
        "CPU型号": cpu_detail.get("brand_raw", "未知"),
        "架构": cpu_detail.get("arch", "未知"),
        "指令集": ",".join(cpu_detail.get("flags", []))[:100] + "..." if cpu_detail.get("flags") else "未知",
        "物理核心数": physical_cores,
        "逻辑线程数": logical_cores,
        "标称主频": cpu_detail.get("hz_advertised_friendly", "未知"),
        "实际主频": cpu_detail.get("hz_actual_friendly", "未知")
    }
    return cpu_info

# 测试调用
if __name__ == "__main__":
    cpu_info = get_cpu_static_info()
    print("=== CPU静态信息 ===")
    for key, value in cpu_info.items():
        print(f"{key}: {value}")

2.2 监控CPU动态状态

psutil可实时获取CPU整体使用率和单核心使用率,温度检测需依赖系统传感器(Windows通过WMI,Linux读取系统文件):

import psutil
import time
import platform

# Windows温度检测依赖pywin32
try:
    import win32com.client
    WMI_AVAILABLE = True
except ImportError:
    WMI_AVAILABLE = False

def get_cpu_usage(interval=1):
    """获取CPU整体使用率(百分比),interval为采样间隔(秒)"""
    return psutil.cpu_percent(interval=interval)

def get_cpu_core_usage(interval=1):
    """获取每个CPU核心的使用率"""
    return psutil.cpu_percent(interval=interval, percpu=True)

def get_cpu_temperature():
    """跨平台获取CPU温度(℃)"""
    system = platform.system()
    if system == "Windows" and WMI_AVAILABLE:
        try:
            wmi = win32com.client.GetObject("winmgmts:")
            # 查询温度传感器
            temp_sensors = wmi.InstancesOf("Win32_PerfFormattedData_Counters_ThermalZoneInformation")
            for sensor in temp_sensors:
                # 转换为摄氏度(原始值为开尔文×10)
                temp = sensor.Temperature / 10 - 273.15
                return round(temp, 2)
        except Exception:
            return "无法获取"
    elif system == "Linux":
        try:
            # 读取Linux温度传感器文件(不同设备路径可能为thermal_zone1/2)
            with open("/sys/class/thermal/thermal_zone0/temp", "r") as f:
                temp = int(f.read()) / 1000
                return round(temp, 2)
        except FileNotFoundError:
            return "无温度传感器"
    else:
        return "暂不支持该系统"

# 测试动态监控
if __name__ == "__main__":
    print("=== CPU动态状态 ===")
    print(f"CPU整体使用率:{get_cpu_usage()}%")
    print(f"各核心使用率:{get_cpu_core_usage()}%")
    print(f"CPU温度:{get_cpu_temperature()}℃")

注意:CPU温度检测受硬件传感器和系统驱动限制,部分老旧设备或虚拟机可能无法获取温度数据。

三、内存检测:物理内存与交换分区

内存检测主要关注物理内存和**交换分区(虚拟内存)**的总容量、已用容量、可用容量及使用率,通过psutil可快速获取这些指标。

import psutil

def get_memory_info():
    """获取物理内存信息"""
    mem = psutil.virtual_memory()
    # 转换单位:字节→GB
    convert_to_gb = lambda x: round(x / (1024 ** 3), 2)
    
    mem_info = {
        "总物理内存(GB)": convert_to_gb(mem.total),
        "已用内存(GB)": convert_to_gb(mem.used),
        "空闲内存(GB)": convert_to_gb(mem.free),
        "可用内存(GB)": convert_to_gb(mem.available),  # 程序可直接使用的内存
        "内存使用率(%)": mem.percent
    }
    return mem_info

def get_swap_info():
    """获取交换分区(虚拟内存)信息"""
    swap = psutil.swap_memory()
    convert_to_gb = lambda x: round(x / (1024 ** 3), 2)
    
    swap_info = {
        "总交换分区(GB)": convert_to_gb(swap.total),
        "已用交换分区(GB)": convert_to_gb(swap.used),
        "空闲交换分区(GB)": convert_to_gb(swap.free),
        "交换分区使用率(%)": swap.percent
    }
    return swap_info

# 测试调用
if __name__ == "__main__":
    print("=== 物理内存信息 ===")
    for k, v in get_memory_info().items():
        print(f"{k}: {v}")
    print("\n=== 交换分区信息 ===")
    for k, v in get_swap_info().items():
        print(f"{k}: {v}")

关键指标available(可用内存)比free(空闲内存)更能反映实际可用资源,因为它包含了系统缓存可释放的内存。

四、硬盘检测:分区、容量与健康状态

硬盘检测包括分区信息容量使用率SMART健康状态(自我监测、分析与报告技术),前者通过psutil实现,后者需调用系统工具。

4.1 获取硬盘分区与容量信息

import psutil

def get_disk_partitions():
    """获取硬盘分区及容量使用信息"""
    partitions = []
    # 仅获取已挂载的非光驱分区
    for part in psutil.disk_partitions(all=False):
        if "cdrom" in part.opts or part.fstype == "":
            continue
        # 获取分区使用情况
        usage = psutil.disk_usage(part.mountpoint)
        convert_to_gb = lambda x: round(x / (1024 ** 3), 2)
        partitions.append({
            "设备名": part.device,
            "挂载点": part.mountpoint,
            "文件系统": part.fstype,
            "总容量(GB)": convert_to_gb(usage.total),
            "已用容量(GB)": convert_to_gb(usage.used),
            "空闲容量(GB)": convert_to_gb(usage.free),
            "使用率(%)": usage.percent
        })
    return partitions

# 测试调用
if __name__ == "__main__":
    print("=== 硬盘分区信息 ===")
    for idx, part in enumerate(get_disk_partitions(), 1):
        print(f"\n分区{idx}:")
        for k, v in part.items():
            print(f"  {k}: {v}")

4.2 检测硬盘SMART健康状态

SMART状态可反映硬盘的坏道、使用寿命等情况,Windows通过wmic命令,Linux通过smartctl工具:

import subprocess
import platform

def get_disk_smart_status(disk="C:" if platform.system() == "Windows" else "/dev/sda"):
    """获取硬盘SMART健康状态"""
    system = platform.system()
    try:
        if system == "Windows":
            # Windows通过wmic查询SMART状态
            cmd = 'wmic diskdrive get status /format:list'
            result = subprocess.check_output(cmd, shell=True, encoding="gbk").strip()
            return "正常" if "OK" in result else "异常"
        elif system == "Linux":
            # Linux需安装smartmontools,且需root权限
            cmd = f"smartctl -H {disk}"
            result = subprocess.check_output(cmd, shell=True, encoding="utf-8").strip()
            return "正常" if "PASSED" in result else "异常"
        else:
            return "暂不支持该系统"
    except Exception as e:
        return f"获取失败:{str(e)[:50]}"

# 测试调用
if __name__ == "__main__":
    print(f"硬盘SMART健康状态:{get_disk_smart_status()}")

注意:Linux系统需以root权限运行脚本(sudo python script.py)才能调用smartctl

五、显卡检测:型号、显存与使用率

显卡检测分NVIDIA显卡(用GPUtil)和AMD/集成显卡(通过系统接口),GPUtil仅支持NVIDIA显卡,AMD显卡需依赖系统工具。

5.1 NVIDIA显卡检测

import GPUtil

def get_nvidia_gpu_info():
    """获取NVIDIA显卡信息"""
    gpus = GPUtil.getGPUs()
    if not gpus:
        return "未检测到NVIDIA显卡"
    gpu_info = []
    for gpu in gpus:
        gpu_info.append({
            "显卡ID": gpu.id,
            "型号": gpu.name,
            "总显存(GB)": round(gpu.memoryTotal, 2),
            "已用显存(GB)": round(gpu.memoryUsed, 2),
            "空闲显存(GB)": round(gpu.memoryFree, 2),
            "显卡使用率(%)": round(gpu.load * 100, 2),
            "温度(℃)": gpu.temperature
        })
    return gpu_info

# 测试调用
if __name__ == "__main__":
    print("=== NVIDIA显卡信息 ===")
    gpu_info = get_nvidia_gpu_info()
    if isinstance(gpu_info, list):
        for idx, gpu in enumerate(gpu_info, 1):
            print(f"\n显卡{idx}:")
            for k, v in gpu.items():
                print(f"  {k}: {v}")
    else:
        print(gpu_info)

5.2 AMD/集成显卡检测

import subprocess
import platform

def get_amd_integrated_gpu_info():
    """获取AMD/集成显卡信息"""
    system = platform.system()
    if system == "Windows" and WMI_AVAILABLE:
        try:
            wmi = win32com.client.GetObject("winmgmts:")
            gpus = wmi.InstancesOf("Win32_VideoController")
            gpu_info = []
            for gpu in gpus:
                gpu_info.append({
                    "显卡名称": gpu.Name,
                    "显存容量(MB)": round(gpu.AdapterRAM / (1024 ** 2), 2) if gpu.AdapterRAM else "未知",
                    "驱动版本": gpu.DriverVersion
                })
            return gpu_info
        except Exception:
            return "获取失败"
    elif system == "Linux":
        try:
            # Linux通过lspci查询显卡信息
            cmd = "lspci | grep -E 'VGA|3D controller'"
            result = subprocess.check_output(cmd, shell=True, encoding="utf-8").strip()
            return [line for line in result.split("\n")]
        except Exception:
            return "获取失败"
    else:
        return "暂不支持该系统"

# 测试调用
if __name__ == "__main__":
    print("=== AMD/集成显卡信息 ===")
    print(get_amd_integrated_gpu_info())

六、主板与BIOS信息检测

主板和BIOS信息需通过系统底层接口获取,Windows用WMI,Linux用dmidecode工具。

6.1 Windows系统获取主板/BIOS信息

def get_motherboard_bios_windows():
    """Windows获取主板与BIOS信息"""
    if not WMI_AVAILABLE:
        return "未安装pywin32,无法获取"
    try:
        wmi = win32com.client.GetObject("winmgmts:")
        # 主板信息
        board = wmi.InstancesOf("Win32_BaseBoard")[0]
        # BIOS信息
        bios = wmi.InstancesOf("Win32_BIOS")[0]
        return {
            "主板制造商": board.Manufacturer,
            "主板型号": board.Product,
            "主板序列号": board.SerialNumber,
            "BIOS制造商": bios.Manufacturer,
            "BIOS版本": bios.Version,
            "BIOS发布日期": bios.ReleaseDate
        }
    except Exception as e:
        return f"获取失败:{str(e)[:50]}"

6.2 Linux系统获取主板/BIOS信息

def get_motherboard_bios_linux():
    """Linux获取主板与BIOS信息(需安装dmidecode)"""
    try:
        # 主板信息
        board_cmd = "dmidecode -t baseboard | grep -E 'Manufacturer|Product Name|Serial Number'"
        board_info = subprocess.check_output(board_cmd, shell=True, encoding="utf-8").strip()
        # BIOS信息
        bios_cmd = "dmidecode -t bios | grep -E 'Manufacturer|Version|Release Date'"
        bios_info = subprocess.check_output(bios_cmd, shell=True, encoding="utf-8").strip()
        return {
            "主板信息": board_info,
            "BIOS信息": bios_info
        }
    except Exception as e:
        return f"获取失败:{str(e)[:50]}"

# 测试调用
if __name__ == "__main__":
    print("=== 主板与BIOS信息 ===")
    if platform.system() == "Windows":
        print(get_motherboard_bios_windows())
    elif platform.system() == "Linux":
        print(get_motherboard_bios_linux())

七、网络适配器检测

通过netifacespsutil获取网络适配器的名称、IP、MAC地址及连接状态:

import netifaces
import psutil

def get_network_interfaces():
    """获取网络适配器信息"""
    interfaces = []
    for iface in netifaces.interfaces():
        # 跳过回环接口
        if iface == "lo" or "Loopback" in iface:
            continue
        iface_info = {"适配器名称": iface}
        # 获取MAC地址
        try:
            iface_info["MAC地址"] = netifaces.ifaddresses(iface)[netifaces.AF_LINK][0]["addr"]
        except KeyError:
            iface_info["MAC地址"] = "未知"
        # 获取IPv4地址
        try:
            ipv4_info = netifaces.ifaddresses(iface)[netifaces.AF_INET][0]
            iface_info["IPv4地址"] = ipv4_info["addr"]
            iface_info["子网掩码"] = ipv4_info["netmask"]
        except KeyError:
            iface_info["IPv4地址"] = "未分配"
            iface_info["子网掩码"] = "未分配"
        # 检测连接状态
        iface_info["连接状态"] = "已连接" if psutil.net_if_stats()[iface].isup else "未连接"
        interfaces.append(iface_info)
    return interfaces

# 测试调用
if __name__ == "__main__":
    print("=== 网络适配器信息 ===")
    for idx, iface in enumerate(get_network_interfaces(), 1):
        print(f"\n适配器{idx}:")
        for k, v in iface.items():
            print(f"  {k}: {v}")

八、外设检测:USB设备

USB外设检测分Windows(WMI)和Linux(pyudev),可获取连接的U盘、鼠标、键盘等设备信息。

8.1 Windows系统检测USB设备

def get_usb_devices_windows():
    """Windows获取USB设备信息"""
    if not WMI_AVAILABLE:
        return "未安装pywin32,无法获取"
    try:
        wmi = win32com.client.GetObject("winmgmts:")
        usb_devices = wmi.InstancesOf("Win32_USBControllerDevice")
        devices = set()  # 去重
        for dev in usb_devices:
            try:
                device_name = dev.Dependent.Description
                devices.add(device_name)
            except Exception:
                continue
        return list(devices)
    except Exception as e:
        return f"获取失败:{str(e)[:50]}"

8.2 Linux系统检测USB设备

def get_usb_devices_linux():
    """Linux获取USB设备信息(需安装pyudev)"""
    try:
        import pyudev
        context = pyudev.Context()
        usb_devices = []
        for device in context.list_devices(subsystem="usb", DEVTYPE="usb_device"):
            usb_devices.append({
                "设备名称": device.get("PRODUCT"),
                "制造商": device.get("MANUFACTURER"),
                "产品名": device.get("PRODUCT_NAME")
            })
        return usb_devices
    except ImportError:
        return "未安装pyudev,无法获取"
    except Exception as e:
        return f"获取失败:{str(e)[:50]}"

# 测试调用
if __name__ == "__main__":
    print("=== USB外设信息 ===")
    if platform.system() == "Windows":
        print(get_usb_devices_windows())
    elif platform.system() == "Linux":
        print(get_usb_devices_linux())

九、综合硬件检测脚本

将上述功能整合为一个完整的脚本,一键输出硬件检测报告,方便实际使用:

import platform
import psutil
import cpuinfo
import GPUtil
import netifaces

# 导入前文定义的所有函数(实际使用时需将前文函数复制到此处)
# ...

def comprehensive_hardware_detection():
    """综合硬件检测报告"""
    print("="*60)
    print("Python硬件检测综合报告")
    print("="*60)
    
    # CPU信息
    print("\n【1. CPU信息】")
    for k, v in get_cpu_static_info().items():
        print(f"  {k}: {v}")
    print(f"  CPU使用率: {get_cpu_usage()}%")
    print(f"  CPU温度: {get_cpu_temperature()}℃")
    
    # 内存信息
    print("\n【2. 内存信息】")
    for k, v in get_memory_info().items():
        print(f"  {k}: {v}")
    
    # 硬盘信息
    print("\n【3. 硬盘信息】")
    for idx, part in enumerate(get_disk_partitions(), 1):
        print(f"  分区{idx}: {part['设备名']} | 使用率: {part['使用率(%)']}%")
    print(f"  硬盘健康状态: {get_disk_smart_status()}")
    
    # 显卡信息
    print("\n【4. 显卡信息】")
    nvidia_gpu = get_nvidia_gpu_info()
    if isinstance(nvidia_gpu, list):
        for gpu in nvidia_gpu:
            print(f"  NVIDIA显卡: {gpu['型号']} | 显存使用率: {gpu['显卡使用率(%)']}%")
    else:
        print(f"  {nvidia_gpu}")
    print(f"  AMD/集成显卡: {get_amd_integrated_gpu_info()}")
    
    # 主板与BIOS
    print("\n【5. 主板与BIOS】")
    if platform.system() == "Windows":
        print(get_motherboard_bios_windows())
    elif platform.system() == "Linux":
        print(get_motherboard_bios_linux())
    
    # 网络适配器
    print("\n【6. 网络适配器】")
    for iface in get_network_interfaces():
        print(f"  {iface['适配器名称']}: {iface['IPv4地址']} ({iface['连接状态']})")
    
    # USB外设
    print("\n【7. USB外设】")
    if platform.system() == "Windows":
        print(get_usb_devices_windows())
    elif platform.system() == "Linux":
        print(get_usb_devices_linux())
    
    print("\n" + "="*60)

if __name__ == "__main__":
    comprehensive_hardware_detection()