宿舍电费查询——以ZUA为例

宿舍电费查询——以ZUA为例

  • 0. 安装抓包环境
    • 手机端
    • 桌面端
  • 1. 登录
    • 1.1 开启抓包后进入缴费页面:
    • 1.2 分析请求
    • 1.3 编写登录代码
  • 2. 获取楼栋及房间ID
    • 2.1 获取楼栋ID
    • 2.2 编写获取楼栋ID代码
    • 2.3 获取房间ID
    • 2.4 编写获取房间ID代码
  • 3. 获取剩余电费:
    • 3.1 选择房间号
    • 3.2 获取指定房间剩余电量
  • 4. 完整python代码
  • 免责声明

0. 安装抓包环境

按需选择HTTPCanaryWireSharkFidder等抓包软件,这里建议使用HTTPCanary

手机端

参考这篇文章小黄鸟(HTTPCanary)安装及Android高版本CA证书配置

桌面端

浏览并参考Fidder或WireShark

1. 登录

首先参考小黄鸟抓包实战之完美校园报平安选择微信为目标应用,过滤掉不需要的网络请求

1.1 开启抓包后进入缴费页面:

缴费页面

1.2 分析请求

输入信息登录后,返回HTTPCanary,根据Url关键词查找带Login的请求:

登录请求

点击请求下面的Text可以看到登录的请求数据,几个比较重要的参数xh/sfzpwdxhItyp

请求数据

1.3 编写登录代码

import requestsdef login():login_url = 'http://cwcfw.zua.edu.cn/xysf/api/User/App/Login'login_data = { #这里填入你获取到的data信息, 由于密码采用 证书加密, 这里暂时不支持直接输入密码"xh": "xh","pwd": "pwd","rsaStr": "8983124","ltyp": "id"}session.post(login_url, cookies=cookie, json=login_data)# 可使用下面代码查看登录状态# response = requests.post(login_url, headers=headers, json=login_data)# print(response.text)cookie = {"ASP.NET_SessionId": "",# 这里面填入登录时抓取到的cookie
}
login()

2. 获取楼栋及房间ID

2.1 获取楼栋ID

登录进来后继续打开HTTPCanary并抓包,点击电费充值,页面此时会跳转到楼栋选择页面

电费充值

此时返回HTTPCanary并根据Url关键词查找带GetOption的Url:

楼栋请求
请求结果

此时在请求->Raw下我们可以看到一个Post请求地址和请求的Data数据,而在响应->Text下可以看到返回的json数据

2.2 编写获取楼栋ID代码

随后,我们模拟这个请求获取各楼层ID:

import json
import requestsdef get_floors():url = 'https://cwcfw.zua.edu.cn/xysf/api/user/ElecRoomIs/GetOption'data = { # 请求中的数据包"key": "build","option": {"areaid": "1","buildid": "-1","roomid": "-1","IsLxr": False,"IsDefault": False,"IsFirst": False,"Cxid": ""}}response = session.post(url, cookies=cookie, json=data)# print(response.text)floors = {} # 将楼栋号和其对应的楼栋ID存入字典for floor in response.json().get('Content')[1:]:if not floor.get('selected'):continuename = floor.get('label').strip()[:-2]num = floor.get('value').strip()floors[name] = num# pprint(floors)return floorscookie = {"ASP.NET_SessionId": "",# 这里面填入登录时抓取到的cookie
}
session = requests.session()
login()
floors = get_floors()
print(floors) # 查看获取到的楼栋号及ID

这里请求采用的是session而不是requests是由于系统的登录策略,这个系统在每次登录后激活一段时间的账号使用权限,过后就会失去权限。使用login()登录后session保持住会话可以避免请求不到楼层信息。

2.3 获取房间ID

保持HTTPCanary运行,这里先选择你所在的楼号:
楼号选择

点击选择楼号后,离开返回HTTPCanary,查找关键词为GetOption的Url:

房间请求
房间响应

我们可以从响应中看到我们选择的数据包可以获取到房间号,以及请求所需的Post地址Data

2.4 编写获取房间ID代码

根据Post地址Data,模拟这个请求获取各楼层ID:

def get_rooms(floor):url = 'https://cwcfw.zua.edu.cn/xysf/api/user/ElecRoomIs/GetOption'data = {"key": "room","option": {"areaid": "1","buildid": floor,"roomid": "-1","IsLxr": False,"IsDefault": False,"IsFirst": False,"Cxid": ""}}response = session.post(url, cookies=cookie, json=data)# print(response.json())rooms = {}for room in response.json().get('Content')[1:]:if not room.get('selected'):continuename = room.get('label').strip()[:-2]num = room.get('value').strip()rooms[name] = num# pprint(rooms)return roomscookie = {"ASP.NET_SessionId": "",# 这里面填入登录时抓取到的cookie
}
session = requests.session()
login()
floor_id= 78 # 直接手动选择楼栋ID
rooms = get_rooms(floor_id)
print(rooms)

3. 获取剩余电费:

3.1 选择房间号

保持HTTPCanary运行,选择房间号后点击确认按钮查询该房间剩余电费:
选择房间号

此时返回HTTPCanary并根据Url关键词查找带Recharge的Url:
电费请求
电费响应

Balance即为所需房间的剩余电量

3.2 获取指定房间剩余电量

def get_balance(floor, room_id):url = "http://cwcfw.zua.edu.cn/xysf/aAppPage/index.aspx/GetRechargeInfo"data = {"rybh": json.dumps({"areaid": "1","buildid": floor,"roomid": room_id,"IsLxr": False,"IsDefault": False,"IsFirst": False,"Cxid": ""}),"category": "ElecRoomIs"}response = session.post(url, cookies=cookie, json=data)# response.encoding = 'utf-8'# print(response.json())Content = response.json().get('d').get('Content')address = Content.get('CzThirdInfo').get('Czxm').split('/')[-1].split('空调')[0]balance = Content.get('CzThirdInfo').get('Balance')return f'{room_id}\t{address}: {balance} kWh'cookie = {"ASP.NET_SessionId": "",# 这里面填入登录时抓取到的cookie
}
session = requests.session()
login()
floor_id = 78 # 直接手动选择楼栋ID
room_id = 24245
info = get_rooms(floor_id, room_id)
print(info)

4. 完整python代码

#!/usr/bin/python3
# -*- coding:utf-8 -*-
# @author  : xiao6ming6
# @time    : 2025/7/11 20:45
# @function: the script is used to do ...
# @version : V1
import json
import requestsdef login():login_url = 'http://cwcfw.zua.edu.cn/xysf/api/User/App/Login'login_data = { #这里填入你获取到的data信息, 由于密码采用 证书加密, 这里暂时不支持直接输入密码,信息需通过抓包填入"xh": "xh","pwd": "pwd","rsaStr": "8983124","ltyp": "id"}session.post(login_url, cookies=cookie, json=login_data)# 可使用下面代码查看登录状态# response = requests.post(login_url, headers=headers, json=login_data)# print(response.text)def get_floors():url = 'https://cwcfw.zua.edu.cn/xysf/api/user/ElecRoomIs/GetOption'data = {"key": "build","option": {"areaid": "1","buildid": "-1","roomid": "-1","IsLxr": False,"IsDefault": False,"IsFirst": False,"Cxid": ""}}response = session.post(url, headers=headers, json=data)# print(response.text)floors = {}for floor in response.json().get('Content')[1:]:if not floor.get('selected'):continuename = floor.get('label').strip()[:-2]num = floor.get('value').strip()floors[name] = num# pprint(floors)return floorsdef get_rooms(floor):url = 'https://cwcfw.zua.edu.cn/xysf/api/user/ElecRoomIs/GetOption'data = {"key": "room","option": {"areaid": "1","buildid": floor,"roomid": "-1","IsLxr": False,"IsDefault": False,"IsFirst": False,"Cxid": ""}}response = session.post(url, headers=headers, json=data)# print(response.json())rooms = {}for room in response.json().get('Content')[1:]:if not room.get('selected'):continuename = room.get('label').strip()[:-2]num = room.get('value').strip()rooms[name] = num# pprint(rooms)return roomsdef get_balance(floor, room_id):url = "http://cwcfw.zua.edu.cn/xysf/aAppPage/index.aspx/GetRechargeInfo"data = {"rybh": json.dumps({"areaid": "1","buildid": floor,"roomid": room_id,"IsLxr": False,"IsDefault": False,"IsFirst": False,"Cxid": ""}),"category": "ElecRoomIs"}response = session.post(url, headers=headers, json=data)# print(response.json())Content = response.json().get('d').get('Content')address = Content.get('CzThirdInfo').get('Czxm').split('/')[-1].split('空调')[0]balance = Content.get('CzThirdInfo').get('Balance')return f'{room_id}\t{address}: {balance} kWh'cookie = {"ASP.NET_SessionId": "",# 这里面填入登录时抓取到的cookie
}
session = requests.session()
login()while True:room_name = input('enter room name(0 to exit): ').strip()if room_name == '0':breakfloor = room_name.split('-')[0]floors = get_floors()floor_id = floors.get(floor)rooms = get_rooms(floor_id)rooms_id = rooms.get(room_name)balance = get_balance(floor_id, rooms_id)print(balance)

如需对抓取登录信息方法有疑问,可通过评论区或阅读原文交流

免责声明

本文内容仅为技术研究与经验分享,旨在提供信息参考。所有方法、代码或操作步骤仅供学习交流,不构成任何形式的技术建议或法律依据。

使用者需自行承担因实践本文内容而产生的全部风险。作者及发布平台对任何直接、间接、因使用或无法使用本文内容造成的损失或损害概不负责。

技术应用应遵守所在国家/地区法律法规,任何违反法律的行为均与本文无关。建议实施前做好数据备份及环境隔离,确保操作安全可控。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.tpcf.cn/news/914476.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vue中计算属性的介绍

Vue.js 中的计算属性是基于它的响应式系统来实现的,它可以根据 Vue 实例的数据状态来动态计算出新的属性值。在 Vue 组件中,计算属性常用于对数据进行处理和转换,以及动态生成一些需要的数据。一、使用方式1.定义计算属性: 在Vue组…

MFC UI控件CheckBox从专家到小白

文章目录CheckBox勾选框控件控件与变量绑定控件点击消息映射互斥CheckBox勾选框控件 控件与变量绑定 方案一: BOOL m_bEnable1; BOOL m_bEnable2; void A::DoDataExchange(CDataExchange* pDX) {DDX_Check(pDX, IDC_CK_1, m_bEnable1);DDX_Check(pDX, IDC_CK_2, …

阿尔卡特ACT 250 ATP 150 AND ATP 400 分子泵控制器TURBOMOLECULAR PUMP CONTROLLER ALCATEL

阿尔卡特ACT 250 ATP 150 AND ATP 400 分子泵控制器TURBOMOLECULAR PUMP CONTROLLER ALCATEL

python的小学课外综合管理系统

前端开发框架:vue.js 数据库 mysql 版本不限 后端语言框架支持: 1 java(SSM/springboot)-idea/eclipse 2.NodejsVue.js -vscode 3.python(flask/django)–pycharm/vscode 4.php(thinkphp/laravel)-hbuilderx 数据库工具:Navicat/SQLyog等都可以 摘要 随着…

实用技巧 Excel 与 XML互转

一 概述 在android多语言适配中,可能提供的是excel格式的多语言翻译,而且翻译数量非常庞大。那手动一个一个往xml里面添加效率非常低,这时候就需要把excel快速转为android可以直接用的资源文件string.xml二 转换流程2.1 第一步任意文件夹或者…

云原生技术与应用-Containerd容器技术详解

目录 一.Containerd概述 1.什么是containerd 2.Containerd的起源与背景 二.Containerd架构 1.Containerd架构概述 2.核心组件解析 三.安装配置Containerd 1.安装Containerd 2.配置Containerd 四.Containerd基本操作 1.镜像类操作 2.容器类操作 3.任务类操作 4.其他操作 一.…

LINUX714 自动挂载/nfs;物理卷

开机自动挂载 /etc/fstab vim /etc/fstab /dev/sdb2 /u2 ext4 defaults 0 0 mount -a [rootweb ~]# vim /etc/fstab [rootweb ~]# cat /etc/fstab# # /etc/fstab # Created by anaconda on Sat Apr 19 17:11:28 2025 # # Accessible filesystems, by reference, are maintai…

系统性学习C语言-第十六讲-深入理解指针(6)

系统性学习C语言-第十六讲-深入理解指针(6)1. sizeof 和 strlen 的对比1.1 sizeof 1.2 strlen 1.3 sizeof 和 strlen 的对比2. 数组和指针笔试题解析2.1 一维数组2.2 字符数组2.3 二维数组3. 指针运算笔试题解析3.1 题目1:3.2 题目…

8:从USB摄像头把声音拿出来--ALSA大佬登场!

前言前面的章节我们从认识摄像头开始,逐渐认识的YCbCr,并对其进行了H264的编码以及MP4封装。整个过程中,我们大致使用了V4L2和FFmpeg这两个重量级工具,就像我们前面章节所讲,V4L2只是给图像做服务的,并不参…

Linux 命令:useradd

Linux useradd 命令详细教程 useradd 是 Linux 系统中用于创建新用户账户的基础命令,它通过配置文件(如 /etc/passwd、/etc/shadow)和默认设置自动完成用户创建流程。本文将详细介绍其用法、参数及相关配置。资料已经分类整理好:h…

Pytest之收集用例规则与运行指定用例

🍅 点击文末小卡片,免费获取软件测试全套资料,资料在手,涨薪更快 小伙伴们大家好呀,今天笔者会给大家讲解一下pytest是如何收集我们写好的用例?我们又有哪些方式来运行单个用例或者批量运行用例呢&#xff…

qt 使用memcpy进行内存拷贝时注意的问题

int offset sizeof(st_target_data);// 预先分配足够空间this->featureData.resize(offsetsize);// 再执行拷贝memcpy(this->featureData.data()offset, dataa, size);注意 一定要在mencpy之前 使用resize分配足够的空间,否则在方法退出时候会闪退&#xff…

微调性能赶不上提示工程怎么办?Can Gradient Descent Simulate Prompting?——论文阅读笔记

今天速读一篇文章 Can Gradient Descent Simulate Prompting? 一句话总结 针对【新知识应用的场景里,FT效果往往追不上ICL】这个情况,作者引入MAML的思想↓ 内圈让模型学习新知识形成知识FT模型; 外圈通过最小化ICL和知识FT模型的KL散度&…

从“直觉抢答”到“深度思考”:大模型的“慢思考”革命,思维链、树、图如何让AI越来越像人?

注:此文章内容均节选自充电了么创始人,CEO兼CTO陈敬雷老师的新书《GPT多模态大模型与AI Agent智能体》(跟我一起学人工智能)【陈敬雷编著】【清华大学出版社】 GPT多模态大模型与AI Agent智能体书籍本章配套视频课程【陈敬雷】 文…

Android系统的问题分析笔记 - Android上的调试方式 debuggerd

debuggerd 是 Android 系统中的一个重要调试工具,主要用于生成进程崩溃时的核心转储(core dump)和调试信息(如堆栈跟踪)。以下是关于 debuggerd 的详细说明: 1. 基本功能 崩溃分析:当 Native 进…

python 双下划线开头函数

在 Python 里,双下划线开头的函数(准确地说是方法)有着特殊的用途和意义。下面为你详细介绍相关内容: 1. 类的特殊方法(魔术方法) 以双下划线开头和结尾的方法,被称为特殊方法或者魔术方法&…

VyOS起步指南:用Docker快速搭建网络实验环境

文章目录1. VyOS是什么?为什么选择它?2. 五分钟快速部署:Docker方案3. 进入容器:初探VyOS世界4. 核心操作:像开发者一样思考5. 踩坑提醒:新手常见问题6. 结语:网络即代码的未来1. VyOS是什么&am…

动态规划理论基础,LeetCode 509. 斐波那契数 LeetCode 70. 爬楼梯 LeetCode 746. 使用最小花费爬楼梯

动态规划理论基础动态规划,英文:Dynamic Programming,简称DP,如果某一问题有很多重叠子问题,使用动态规划是最有效的。所以动态规划中每一个状态一定是由上一个状态推导出来的,这一点就区分于贪心&#xff…

暑期自学嵌入式——Day02(C语言阶段)

点关注不迷路哟。你的点赞、收藏,一键三连,是我持续更新的动力哟!!! 主页: 一位搞嵌入式的 genius-CSDN博客https://blog.csdn.net/m0_73589512?spm1000.2115.3001.5343 目录 Day02→数据类型&#xf…

如何单独安装设置包域名

前言 在 npm 中,直接通过 package-lock.json 无法单独设置包的安装地址,因为该文件是自动生成的依赖关系锁定文件。但你可以通过以下方法间接实现: 一、在 package.json 中指定包来源(推荐) 在 package.json 的 depend…