You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python计算互联网数据用量?psutil等工具适用性疑问

用Python计算互联网数据用量的实现方案

一、psutil是否合适?完全合适

psutil是跨平台的系统监控库,专门用于获取系统资源使用数据,其中就包含网络收发字节数的统计功能。它封装了底层系统调用,无需你处理复杂的系统细节,代码简洁且可靠性高,非常适合快速实现网络数据用量统计的需求。

具体使用方法

通过psutil.net_io_counters()可以获取网络接口的收发字节统计,计算不同时间点的差值就能得到某段时间内的数据用量:

import psutil
import time

def calculate_network_usage(monitor_interval=1):
    # 获取初始统计值
    initial_stats = psutil.net_io_counters()
    start_sent = initial_stats.bytes_sent
    start_recv = initial_stats.bytes_recv
    
    time.sleep(monitor_interval)
    
    # 获取结束统计值
    final_stats = psutil.net_io_counters()
    end_sent = final_stats.bytes_sent
    end_recv = final_stats.bytes_recv
    
    # 计算用量差值
    sent_mb = (end_sent - start_sent) / 1024 / 1024
    recv_mb = (end_recv - start_recv) / 1024 / 1024
    
    return f"发送流量: {sent_mb:.2f} MB, 接收流量: {recv_mb:.2f} MB"

# 示例:统计10秒内的网络用量
print(calculate_network_usage(10))

如果需要单独统计某块网卡(比如WiFi或以太网)的用量,可以给net_io_counters()传入pernic=True,然后指定对应网卡名称(Windows下如"以太网",Linux下如"eth0")。

二、用socket实现的可行性

socket是网络通信的底层API,可以实现,但工作量极大,不推荐。

原理是创建原始套接字捕获所有经过网卡的IP数据包,然后累加每个数据包的大小。但这种方式需要管理员权限,还要自行处理不同协议(TCP/UDP/ICMP等)的数据包解析,甚至要区分本地与互联网流量(避免统计局域网内传输数据),实现逻辑繁琐且容易出错,远不如psutil高效可靠。

仅做思路演示(代码不完整,无法直接用于生产):

import socket

# 需管理员权限运行
raw_socket = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_IP)
raw_socket.bind(("0.0.0.0", 0))
raw_socket.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)
raw_socket.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON)

total_traffic = 0
try:
    while True:
        packet = raw_socket.recvfrom(65565)[0]
        total_traffic += len(packet)
        print(f"累计流量: {total_traffic/1024/1024:.2f} MB")
except KeyboardInterrupt:
    raw_socket.ioctl(socket.SIO_RCVALL, socket.RCVALL_OFF)
    raw_socket.close()

该代码仅能捕获接收数据包,还需额外处理发送数据包,且无法区分公网/内网流量,实际使用需大量补充逻辑。

三、用Scapy实现的方案

Scapy是专门的数据包处理库,比socket更易用,可以实现精准的互联网数据用量统计,适合需要自定义过滤规则的场景。

原理是用Scapy的sniff功能捕获数据包,通过判断IP地址是否为公网地址,过滤出互联网流量并累加数据包大小。

示例代码:

from scapy.all import sniff, IP
import ipaddress

total_sent = 0
total_recv = 0

def is_public_ip(ip_str):
    try:
        ip = ipaddress.ip_address(ip_str)
        return not (ip.is_private or ip.is_loopback or ip.is_link_local)
    except ValueError:
        return False

def process_packet(packet):
    global total_sent, total_recv
    if IP in packet:
        src_ip = packet[IP].src
        dst_ip = packet[IP].dst
        packet_size = len(packet)
        
        if is_public_ip(dst_ip):
            total_sent += packet_size
        if is_public_ip(src_ip):
            total_recv += packet_size
        
        print(f"累计发送: {total_sent/1024/1024:.2f} MB | 累计接收: {total_recv/1024/1024:.2f} MB")

# 开始嗅探,需管理员权限
sniff(prn=process_packet, store=0)

这个方案可以精准区分公网与内网流量,但同样需要管理员权限,且嗅探过程会占用一定系统资源,适合有精细化统计需求的场景。

总结

  • 优先选择psutil:简单、跨平台、无需特殊权限(多数系统),适合快速实现通用网络用量统计。
  • Scapy适合精细化场景:需要区分公网/内网流量、自定义过滤规则时使用,但依赖管理员权限。
  • socket不推荐:底层实现繁琐,开发成本高,除非有特殊底层需求,否则没必要使用。

内容的提问来源于stack exchange,提问作者Esra Issam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 08:33:35