Python硬件检测CPU、内存、显卡、硬盘等硬件信息获取

在系统监控、硬件诊断、自动化运维和桌面应用开发中,获取硬件设备信息是核心需求——比如检测CPU型号与使用率、内存容量与占用、硬盘分区与健康状态、显卡型号与性能等。Python凭借丰富的跨平台库,能快速实现硬件信息的采集与监控,无需依赖系统原生工具的复杂解析。

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

本文涉及的硬件检测功能依赖多个Python第三方库,部分为跨平台通用库,部分针对特定系统(Windows/Linux)。执行以下命令安装核心依赖:

pip install psutil py-cpuinfo gputil netifaces pywin32  # Windows
pip install psutil py-cpuinfo gputil netifaces pyudev   # Linux

库功能说明:

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

注意:Linux系统下获取部分硬件信息(如主板)需安装dmidecode工具(sudo apt install dmidecode),且需root权限运行脚本;macOS系统部分硬件信息检测需依赖IOKit,本文主要聚焦Windows和Linux平台。

二、CPU检测:型号、核心数与使用率

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

2.1 获取CPU静态信息(型号、核心数)

使用py-cpuinfo获取CPU详细型号,psutil获取核心数与线程数:

import cpuinfo
import psutil

def get_cpu_static_info():
    """
    获取CPU静态信息(型号、核心数、架构等)
    :return: 字典包含CPU静态信息
    """
    cpu_info = cpuinfo.get_cpu_info()
    # 获取核心数与线程数
    physical_cores = psutil.cpu_count(logical=False)  # 物理核心数
    logical_cores = psutil.cpu_count(logical=True)    # 逻辑线程数(超线程)
    
    result = {
        "CPU型号": cpu_info.get("brand_raw", "未知"),
        "架构": cpu_info.get("arch", "未知"),
        "指令集": cpu_info.get("flags", "未知"),
        "物理核心数": physical_cores,
        "逻辑线程数": logical_cores,
        "主频": f"{cpu_info.get('hz_advertised_friendly', '未知')}"
    }
    return result

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

2.2 监控CPU动态信息(使用率、温度)

psutil可实时获取CPU使用率,温度检测需依赖系统底层接口(Windows通过WMI,Linux通过/sys/class/thermal):

import psutil
import time

# Windows温度检测:依赖pywin32的WMI
try:
    import win32com.client
except ImportError:
    win32com = None

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

def get_cpu_core_usage(interval=1):
    """
    获取每个CPU核心的使用率
    :param interval: 采样间隔(秒)
    :return: 列表,每个元素为对应核心的使用率(%)
    """
    return psutil.cpu_percent(interval=interval, percpu=True)

def get_cpu_temperature():
    """
    获取CPU温度(跨平台)
    :return: CPU温度(℃),获取失败返回None
    """
    if win32com:  # Windows系统
        try:
            wmi = win32com.client.GetObject("winmgmts:")
            # 查询CPU温度传感器
            temperature_info = wmi.InstancesOf("Win32_PerfFormattedData_Counters_ThermalZoneInformation")
            for sensor in temperature_info:
                temp = sensor.Temperature / 10 - 273.15  # 转换为℃
                return round(temp, 2)
        except Exception:
            return None
    else:  # Linux系统
        try:
            # 读取thermal_zone的温度(不同设备路径可能不同)
            with open("/sys/class/thermal/thermal_zone0/temp", "r") as f:
                temp = int(f.read()) / 1000
                return round(temp, 2)
        except FileNotFoundError:
            return None

# 测试CPU动态监控
if __name__ == "__main__":
    print("=== CPU动态信息 ===")
    print(f"CPU整体使用率:{get_cpu_usage()}%")
    print(f"各核心使用率:{get_cpu_core_usage()}%")
    cpu_temp = get_cpu_temperature()
    print(f"CPU温度:{cpu_temp}℃" if cpu_temp else "CPU温度:无法获取")

说明:CPU温度检测受硬件传感器和系统驱动限制,部分设备可能无法获取;Linux系统中thermal_zone0为常见的温度传感器路径,若不存在可尝试thermal_zone1等。

三、内存检测:容量、使用率与交换分区

内存检测主要关注物理内存交换分区(虚拟内存)的总容量、已用容量、使用率。

import psutil

def get_memory_info():
    """
    获取物理内存信息
    :return: 字典包含总容量、已用容量、使用率等
    """
    mem = psutil.virtual_memory()
    # 转换单位:字节→GB
    total = round(mem.total / (1024 ** 3), 2)
    used = round(mem.used / (1024 ** 3), 2)
    free = round(mem.free / (1024 ** 3), 2)
    available = round(mem.available / (1024 ** 3), 2)
    
    return {
        "总物理内存(GB)": total,
        "已用内存(GB)": used,
        "空闲内存(GB)": free,
        "可用内存(GB)": available,
        "内存使用率(%)": mem.percent
    }

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

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

关键指标available(可用内存)指程序可直接使用的内存,比free(空闲内存)更能反映实际内存状态。

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

硬盘检测包括分区信息容量使用率健康状态(SMART)

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

import psutil

def get_disk_partitions():
    """
    获取本地硬盘分区信息
    :return: 列表,每个元素为分区的详细信息
    """
    partitions = []
    for part in psutil.disk_partitions(all=False):  # all=False仅显示已挂载分区
        if "cdrom" in part.opts or part.fstype == "":
            continue  # 跳过光驱和无效分区
        # 获取分区使用情况
        usage = psutil.disk_usage(part.mountpoint)
        partitions.append({
            "设备名": part.device,
            "挂载点": part.mountpoint,
            "文件系统": part.fstype,
            "总容量(GB)": round(usage.total / (1024 ** 3), 2),
            "已用容量(GB)": round(usage.used / (1024 ** 3), 2),
            "空闲容量(GB)": round(usage.free / (1024 ** 3), 2),
            "使用率(%)": usage.percent
        })
    return partitions

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

4.2 检测硬盘健康状态(SMART)

硬盘SMART(自我监测、分析与报告技术)可反映硬盘的健康状态,需借助第三方工具或系统接口:

  • Windows:使用wmic命令调用WMI接口;
  • Linux:安装smartmontoolssudo apt install smartmontools),通过smartctl命令获取。
import subprocess
import platform

def get_disk_smart_status(disk_device="C:"):
    """
    获取硬盘SMART健康状态(仅支持Windows/Linux)
    :param disk_device: 硬盘设备名(Windows为盘符,Linux为/dev/sda)
    :return: 健康状态(正常/警告/故障),获取失败返回None
    """
    system = platform.system()
    try:
        if system == "Windows":
            # Windows通过wmic查询SMART状态
            cmd = f'wmic diskdrive get status /format:list'
            result = subprocess.check_output(cmd, shell=True, encoding="gbk").strip()
            if "OK" in result:
                return "正常"
            else:
                return "故障"
        elif system == "Linux":
            # Linux通过smartctl查询(需root权限)
            cmd = f"smartctl -H {disk_device}"
            result = subprocess.check_output(cmd, shell=True, encoding="utf-8").strip()
            if "PASSED" in result:
                return "正常"
            else:
                return "警告/故障"
        else:
            return None
    except Exception as e:
        print(f"获取SMART状态失败:{e}")
        return None

# 测试
if __name__ == "__main__":
    if platform.system() == "Windows":
        status = get_disk_smart_status("C:")
    else:
        status = get_disk_smart_status("/dev/sda")  # Linux需替换为实际设备名
    print(f"\n硬盘SMART健康状态:{status}")

注意:Linux系统需以root权限运行脚本(sudo python script.py),否则无法调用smartctl

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

显卡检测分NVIDIA显卡(用GPUtil)、AMD显卡(需调用系统接口)和集成显卡(通过主板信息获取)。

5.1 NVIDIA显卡检测(GPUtil)

import GPUtil

def get_nvidia_gpu_info():
    """
    获取NVIDIA显卡信息(型号、显存、使用率)
    :return: 列表,每个元素为显卡的详细信息
    """
    gpus = GPUtil.getGPUs()
    if not gpus:
        return None
    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),
            "显卡使用率(%)": gpu.load * 100,
            "温度(℃)": gpu.temperature
        })
    return gpu_info

# 测试
if __name__ == "__main__":
    print("=== NVIDIA显卡信息 ===")
    nvidia_gpu = get_nvidia_gpu_info()
    if nvidia_gpu:
        for idx, gpu in enumerate(nvidia_gpu, 1):
            print(f"\n显卡{idx}:")
            for key, value in gpu.items():
                print(f"  {key}: {value}")
    else:
        print("未检测到NVIDIA显卡")

5.2 AMD/集成显卡检测

AMD显卡和集成显卡的检测需依赖系统接口:

  • Windows:通过pywin32调用WMI查询显卡信息;
  • Linux:读取/sys/class/drm目录或调用lspci命令。
import platform
import subprocess

# Windows显卡检测依赖pywin32
if platform.system() == "Windows" and win32com:
    def get_amd_gpu_info_windows():
        """Windows获取AMD/集成显卡信息"""
        wmi = win32com.client.GetObject("winmgmts:")
        gpus = wmi.InstancesOf("Win32_VideoController")
        gpu_info = []
        for gpu in gpus:
            gpu_info.append({
                "显卡名称": gpu.Name,
                "显存容量(MB)": gpu.AdapterRAM / (1024 ** 2) if gpu.AdapterRAM else "未知",
                "驱动版本": gpu.DriverVersion
            })
        return gpu_info
else:
    def get_amd_gpu_info_linux():
        """Linux获取AMD/集成显卡信息(通过lspci)"""
        try:
            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 as e:
            print(f"获取AMD显卡信息失败:{e}")
            return None

# 测试
if __name__ == "__main__":
    print("=== AMD/集成显卡信息 ===")
    if platform.system() == "Windows" and win32com:
        amd_gpu = get_amd_gpu_info_windows()
    else:
        amd_gpu = get_amd_gpu_info_linux()
    if amd_gpu:
        for gpu in amd_gpu:
            print(gpu)
    else:
        print("未检测到AMD/集成显卡或无法获取信息")

六、网络适配器检测:IP、MAC与状态

使用netifacespsutil获取网络适配器的硬件信息和连接状态:

import netifaces
import psutil

def get_network_interfaces():
    """
    获取网络适配器信息(名称、IP、MAC、状态)
    :return: 列表,每个元素为适配器的详细信息
    """
    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:
            iface_info["IPv4地址"] = netifaces.ifaddresses(iface)[netifaces.AF_INET][0]["addr"]
            iface_info["子网掩码"] = netifaces.ifaddresses(iface)[netifaces.AF_INET][0]["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 key, value in iface.items():
            print(f"  {key}: {value}")

七、主板与BIOS信息检测

主板和BIOS信息需通过系统底层接口获取,Windows和Linux实现方式不同:

7.1 Windows系统(WMI)

def get_motherboard_info_windows():
    """Windows获取主板与BIOS信息"""
    if not win32com:
        return None
    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
    }

7.2 Linux系统(dmidecode)

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

# 测试
if __name__ == "__main__":
    print("=== 主板与BIOS信息 ===")
    if platform.system() == "Windows" and win32com:
        mb_info = get_motherboard_info_windows()
    else:
        mb_info = get_motherboard_info_linux()
    if mb_info:
        for key, value in mb_info.items():
            print(f"{key}: {value}")

八、USB外设检测

8.1 Windows系统(WMI)

def get_usb_devices_windows():
    """Windows获取USB外设信息"""
    if not win32com:
        return None
    wmi = win32com.client.GetObject("winmgmts:")
    usb_devices = wmi.InstancesOf("Win32_USBControllerDevice")
    devices = []
    for dev in usb_devices:
        try:
            device_name = dev.Dependent.Description
            if device_name not in devices:
                devices.append(device_name)
        except Exception:
            continue
    return devices

8.2 Linux系统(pyudev)

import pyudev

def get_usb_devices_linux():
    """Linux获取USB外设信息"""
    context = pyudev.Context()
    devices = []
    for device in context.list_devices(subsystem="usb", DEVTYPE="usb_device"):
        devices.append({
            "设备名称": device.get("PRODUCT"),
            "制造商": device.get("MANUFACTURER"),
            "产品名": device.get("PRODUCT_NAME")
        })
    return devices

九、综合硬件检测脚本

将上述功能整合为一个完整的硬件检测脚本,一键输出所有硬件信息:

import platform
import psutil
import cpuinfo
import GPUtil
import netifaces

# 导入前文定义的所有函数
# ...(此处省略前文函数,实际使用时需包含)

def comprehensive_hardware_detection():
    """综合硬件检测"""
    print("="*50)
    print("          Python硬件检测报告")
    print("="*50)
    
    # CPU信息
    print("\n【1. CPU信息】")
    cpu_static = get_cpu_static_info()
    for key, value in cpu_static.items():
        print(f"  {key}: {value}")
    print(f"  CPU使用率: {get_cpu_usage()}%")
    cpu_temp = get_cpu_temperature()
    print(f"  CPU温度: {cpu_temp}℃" if cpu_temp else "  CPU温度: 无法获取")
    
    # 内存信息
    print("\n【2. 内存信息】")
    mem_info = get_memory_info()
    for key, value in mem_info.items():
        print(f"  {key}: {value}")
    
    # 硬盘信息
    print("\n【3. 硬盘信息】")
    disk_partitions = get_disk_partitions()
    for idx, part in enumerate(disk_partitions, 1):
        print(f"  分区{idx}: {part['设备名']} ({part['挂载点']})")
        print(f"    总容量: {part['总容量(GB)']}GB, 使用率: {part['使用率(%)']}%")
    disk_smart = get_disk_smart_status("C:" if platform.system() == "Windows" else "/dev/sda")
    print(f"  硬盘健康状态: {disk_smart}")
    
    # 显卡信息
    print("\n【4. 显卡信息】")
    nvidia_gpu = get_nvidia_gpu_info()
    if nvidia_gpu:
        for gpu in nvidia_gpu:
            print(f"  NVIDIA显卡: {gpu['型号']}, 显存使用率: {gpu['显卡使用率(%)']}%")
    else:
        if platform.system() == "Windows" and win32com:
            amd_gpu = get_amd_gpu_info_windows()
        else:
            amd_gpu = get_amd_gpu_info_linux()
        if amd_gpu:
            print(f"  AMD/集成显卡: {amd_gpu}")
    
    # 网络适配器
    print("\n【5. 网络适配器】")
    net_ifaces = get_network_interfaces()
    for iface in net_ifaces:
        print(f"  {iface['名称']}: {iface['IPv4地址']} ({iface['状态']})")
    
    # 主板与BIOS
    print("\n【6. 主板与BIOS】")
    if platform.system() == "Windows" and win32com:
        mb_info = get_motherboard_info_windows()
    else:
        mb_info = get_motherboard_info_linux()
    if mb_info:
        for key, value in mb_info.items():
            print(f"  {key}: {value}")
    
    print("\n" + "="*50)

if __name__ == "__main__":
    comprehensive_hardware_detection()
posted @ 2025-12-21 14:55  小宇无敌  阅读(33)  评论(0)    收藏  举报