直接调用家用路由器api常失败,因多数厂商不开放标准rest接口;可行方案仅snmp(需启用并设community)或ssh执行命令(如tc限速、cat流量),但均受限于固件支持。

为什么直接调用路由器API往往失败
多数家用路由器(如TP-Link、华为HG8245、小米R3G)不开放标准REST API,或仅提供未文档化的私有接口,且默认关闭。强行抓包还原登录+操作流程,会遇到CSRF token动态生成、Referer校验、Session过期快等问题。requests.post("http://192.168.1.1/userRpm/StatusRpm.htm") 这类请求在新固件上大概率返回403或空响应。
真正可行的路径只有两条:走SNMP协议(需路由器开启SNMP v2c/v3)、或通过SSH执行内置命令(如cat /proc/net/dev 或 ifconfig)。前者兼容性好但权限粒度粗;后者更精准但要求路由器启用SSH且固件含busybox工具集。
用SNMP读取实时流量数据的实操要点
先确认路由器是否开启SNMP:登录管理页 → 高级设置 → 管理控制 → SNMP(部分型号叫“网络管理”),启用并设community为public(测试用,生产环境务必改密)。
Python端用pysnmp读取网口收发字节数(OID:1.3.6.1.2.1.2.2.1.10.x 和 1.3.6.1.2.1.2.2.1.16.x,x为接口索引):
仅使用 Python 将 Claw Code 虚拟化框架与 OpenClaw 集成,提供 184 种工具和 200 多条命令,用于安全分析和代码质量...
from pysnmp.hlapi import *
errorIndication, errorStatus, errorIndex, varBinds = next(
getCmd(SnmpEngine(),
CommunityData('public', mpModel=0),
UdpTransportTarget(('192.168.1.1', 161)),
ContextData(),
ObjectType(ObjectIdentity('IF-MIB', 'ifInOctets', 2)),
ObjectType(ObjectIdentity('IF-MIB', 'ifOutOctets', 2)))
)
if not errorIndication and not errorStatus:
in_bytes = int(varBinds[0][1])
out_bytes = int(varBinds[1][1])
- 接口索引
2通常对应WAN口,但需先用ifDescrOID遍历确认,不同品牌差异大 - SNMP v2c无加密,切勿在公网暴露;v3配置复杂,家用场景收益低
- 两次读数间隔建议≥30秒——太短会导致计数器未更新,差值为0
通过SSH执行限流命令的硬核方式
仅适用于OpenWrt、Padavan、梅林等支持自定义脚本的固件。核心思路是用tc(traffic control)在出口网卡(如br0)上建HTB队列,再对目标IP加sfq子类限速。
示例Python片段(使用paramiko):
import paramiko
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('192.168.1.1', username='root', password='xxx')
# 清除旧规则
ssh.exec_command('tc qdisc del dev br0 root 2>/dev/null')
# 新建HTB根队列(总带宽100Mbit)
ssh.exec_command('tc qdisc add dev br0 root handle 1: htb default 30')
# 为某设备限速512kbit/s
ssh.exec_command('tc class add dev br0 parent 1: classid 1:1 htb rate 512kbit')
ssh.exec_command('tc filter add dev br0 protocol ip parent 1:0 u32 match ip src 192.168.1.100 flowid 1:1')
-
tc命令在部分精简固件中被阉割,执行前先ssh.exec_command('tc -h')验证是否存在 - 限速生效后,目标设备ping延迟会明显升高,但不会断连——这是正常现象
- 规则不持久:路由器重启即失效,需写入
/etc/firewall.user或定时任务重载
统计结果存本地还是推远程?别踩时间戳陷阱
流量统计本质是“差值计算”,必须保证两次采样时间点精确对齐。常见错误是把Python脚本的time.time()当作采样时刻,而实际SNMP/SSH往返有几十到几百毫秒延迟。
- 正确做法:每次获取数据时,同步记录路由器系统时间(SNMP查
sysUpTime+sysContact,或SSH执行date +%s) - 存储选SQLite比CSV更可靠——避免多进程写入冲突,且能建索引加速按时间范围查询
- 若推送到InfluxDB,注意字段类型:流量值必须为整型(
in_bytes::integer),否则Grafana绘图会异常
真正的难点不在代码,而在确认你手里的路由器到底支持哪条路——先SSH登录敲tc -h和snmpd -v,比写一百行Python都管用。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










