电子科大成都学院电费自动化查询

1655 字
8 分钟
电子科大成都学院电费自动化查询

学校电费查询需要通过网页进入电表页面查看。

如果只是偶尔查询没有什么问题,但如果想实现定时查询、低电量提醒或者接入自己的机器人,每次手动打开网页就比较麻烦。

本文记录通过浏览器开发者工具分析电表查询请求,并使用 Node.js 直接获取电表剩余数据的方法。

说明

本文仅记录本人正常使用的电表信息查询过程,用于学习和个人自动化。请勿对学校服务器进行高频请求、批量扫描或查询无权访问的数据。


一、分析电费查询请求#

首先正常进入学校的电费查询页面,然后打开浏览器开发者工具:

F12 → Network → Fetch/XHR

刷新页面或者重新查询一次电费。

可以观察到浏览器向以下接口发送了一个 POST 请求:

https://www.cduestc.cn/sfxq//kddz/electricmeterpost/electricMeterQuery

请求类型:

POST

请求的 Content-Type 为:

application/x-www-form-urlencoded

二、分析 POST 参数#

在浏览器 Network 中查看请求的 Payload / Form Data,可以看到查询主要使用两个参数:

wechatUserId
electricUserUid

例如:

wechatUserId=你的用户ID
electricUserUid=你的电表ID

其中:

  • wechatUserId:当前用户对应的 ID
  • electricUserUid:电表对应的 ID

这两个值可以通过浏览器开发者工具查看自己的正常查询请求获得。

注意

不建议在公开的 GitHub 仓库或博客中直接发布自己的真实用户标识。本文示例统一使用占位值。


三、接口返回数据#

正常查询后,服务器返回 JSON,例如:

{
"msg": "操作成功",
"code": 0,
"data": {
"querycode": "1",
"shengyu": "93.21",
"zhuangtai": "合闸",
"leiji": "6668.51",
"querymsg": "双回路表状态查询成功"
}
}

主要字段含义:

字段说明
code接口请求状态
shengyu电表剩余值
zhuangtai当前电表状态
leiji累计值
querymsg查询结果说明

例如:

剩余:93.21
状态:合闸
累计:6668.51

四、关于 H32C6TIi 参数#

在浏览器 Network 中观察实际请求时,可以发现 URL 后面还可能自动出现一个很长的参数:

?H32C6TIi=xxxxxxxxxxxxxxxx

而且多次刷新页面后,该参数的内容可能发生变化。

最开始我以为查询接口必须携带这个参数,因此尝试分析它的来源。

页面 HTML 中存在额外的安全脚本以及类似:

<meta id="..." content="..." r="m">

和:

$_ts = window["$_ts"];
$_ts.nsd = ...;
$_ts.cd = "...";

这样的代码。

同时页面还会加载额外的混淆 JavaScript。

因此,H32C6TIi 更像是网页安全防护层在浏览器请求过程中附加的参数,而不是电表查询业务本身的普通参数。

实际测试#

后来尝试完全删除:

H32C6TIi

直接向原始接口发送 POST:

POST /sfxq//kddz/electricmeterpost/electricMeterQuery

仍然能够正常返回:

{
"msg": "操作成功",
"code": 0
}

因此对于当前的电表查询接口,实际测试发现 无需携带 H32C6TIi 也可以完成正常查询

这样 Node.js 的实现就简单很多,不需要执行浏览器 JavaScript,也不需要使用 Playwright 模拟完整浏览器。

该行为属于当前测试结果,学校网站后续如果修改接口或安全策略,可能会发生变化。


五、使用 Node.js 查询#

Node.js 18+ 已经内置 fetch,因此不需要额外安装 Axios 等 HTTP 库。

新建文件:

electric.mjs

写入:

const url =
"https://www.cduestc.cn/sfxq//kddz/electricmeterpost/electricMeterQuery";
const response = await fetch(url, {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
},
body: new URLSearchParams({
wechatUserId: process.env.WECHAT_USER_ID,
electricUserUid: process.env.ELECTRIC_USER_UID,
}),
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
const result = await response.json();
if (result.code !== 0) {
throw new Error(result.msg || "电表查询失败");
}
console.log(result);

六、配置自己的电表信息#

为了避免把自己的 ID 直接写进代码,可以通过环境变量传入。

Linux / macOS:

Terminal window
export WECHAT_USER_ID="你的用户ID"
export ELECTRIC_USER_UID="你的电表ID"

然后运行:

Terminal window
node electric.mjs

正常情况下会得到类似:

{
"msg": "操作成功",
"code": 0,
"data": {
"querycode": "1",
"shengyu": "93.21",
"zhuangtai": "合闸",
"leiji": "6668.51",
"querymsg": "双回路表状态查询成功"
}
}

七、只输出需要的数据#

如果不需要完整 JSON,可以进一步处理返回结果:

const url =
"https://www.cduestc.cn/sfxq//kddz/electricmeterpost/electricMeterQuery";
const response = await fetch(url, {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
},
body: new URLSearchParams({
wechatUserId: process.env.WECHAT_USER_ID,
electricUserUid: process.env.ELECTRIC_USER_UID,
}),
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
const result = await response.json();
if (result.code !== 0) {
throw new Error(result.msg || "查询失败");
}
const {
shengyu,
zhuangtai,
leiji,
querymsg,
} = result.data;
console.log(`剩余:${shengyu}`);
console.log(`状态:${zhuangtai}`);
console.log(`累计:${leiji}`);
console.log(`结果:${querymsg}`);

运行:

Terminal window
node electric.mjs

输出类似:

剩余:93.21
状态:合闸
累计:6668.51
结果:双回路表状态查询成功

八、封装成函数#

如果后续还需要接入其他程序,可以进一步封装:

async function queryElectricity(wechatUserId, electricUserUid) {
const url =
"https://www.cduestc.cn/sfxq//kddz/electricmeterpost/electricMeterQuery";
const response = await fetch(url, {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
},
body: new URLSearchParams({
wechatUserId,
electricUserUid,
}),
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
const result = await response.json();
if (result.code !== 0) {
throw new Error(result.msg || "查询失败");
}
return result.data;
}
const data = await queryElectricity(
process.env.WECHAT_USER_ID,
process.env.ELECTRIC_USER_UID
);
console.log(`剩余:${data.shengyu}`);
console.log(`状态:${data.zhuangtai}`);
console.log(`累计:${data.leiji}`);

这样后续无论是接入网页、Telegram Bot,还是其他自己的程序,都可以直接调用 queryElectricity()


九、实现低电量提醒#

既然已经可以自动获取剩余数据,就可以进一步判断剩余值。

例如低于 20 时输出警告:

const remaining = Number(data.shengyu);
if (remaining < 20) {
console.log(`⚠️ 电量不足,当前剩余:${remaining}`);
}

后续可以结合:

Cron
Node.js
Telegram Bot
邮件
Webhook

实现每天自动查询一次,并在剩余值较低时发送提醒。


十、总结#

整个实现过程实际上可以简化成:

学校电费查询页面
浏览器 Network 抓取请求
找到 electricMeterQuery
确认请求方式为 POST
提取自己的查询参数
测试移除 H32C6TIi
接口仍然正常返回
Node.js fetch 直接查询
解析 JSON
定时查询 / 低电量提醒

最终并不需要模拟整个浏览器,只需要通过 Node.js 向查询接口发送正常的 POST 表单即可。

对于个人使用来说,这种方式比使用浏览器自动化工具更加轻量,也更方便部署在自己的服务器上。


免责声明#

本文内容仅用于个人学习、接口分析以及本人电表信息的自动化查询。

请合理控制查询频率,不要对服务器进行高频请求、批量枚举、扫描或查询未经授权的数据。

学校系统接口及参数可能随时调整,本文仅记录编写时的实际测试结果。

文章分享

如果这篇文章对你有帮助,欢迎分享给更多人!

电子科大成都学院电费自动化查询
https://blog.5iwy.com/posts/notes/uestc-chengdu-df/
作者
Suki
发布于
2026-08-19
许可协议
CC BY-NC-SA 4.0
分类
站点信息
构建平台
ESA Pages
文章许可
CC BY-NC-SA 4.0