【Pyhthon实战】Python对全校电费查询采集并可视化分析

news2024/11/25 0:30:59

前言

今天,我来说说怎么抓取宿舍电费的过程。我们学校是在完美校园交电费的,我们可以不用取抓包完美校园的数据接口,我们可以直接登录学校的一卡通网站,每个学校都有,大家可以自己找找,这里我为什么要抓包呢,因为学校提供的网站已经打不开了,这里就不介绍怎么抓包了。

以下是几个常用的抓包工具:

  1. Wireshark:这是一款开源的网络分析工具,支持多种操作系统。它可以捕获和分析网络数据包,并提供详细的统计和报告。

  2. Fiddler:这是一款基于 Windows 的 HTTP 调试代理工具,可以帮助你捕获和分析 HTTP 流量。它还提供了一些高级功能,例如自定义规则和脚本。

  3. Charles:这是一款跨平台的抓包代理工具,可以用于捕获 HTTP 和 HTTPS 流量。它也提供了一些高级功能,例如修改请求和响应,并支持网络模拟。

  4. Burp Suite:这是一款专业的 Web 应用程序安全测试工具,可以用于捕获和分析 HTTP 和 HTTPS 流量。它还提供了许多高级功能,例如漏洞扫描和自定义脚本。

接下来,我们开始登录,一般账号是自己的学号,密码是身份证后六位,我们登录之后,就可以看到电费充值的入口,我们点击之后,会看到这样的页面。

接下来,就是数据接口的分析了,我们多次调试,我们可以看到这样的结果,每个学校都是一样的,用几个参数来确定宿舍的电费查询接口。

获取楼号id

我们学校每个宿舍楼对应一个id,我们要是数据是怎么定义的,并不是一号楼对应的id就是1。这个接口需要我们传cookies,我这里就不放上面了,每个学校的情况可能不一样,大家可以自己调整代码,不过,我们学校的参数并没有加密,倒是简单了不少。

import requests


headers = {
    "X-CSRF-TOKEN": "6d51ac80-b777-4a26-99a1-06bfbf65360f",
}
cookies = {
    "JSESSIONID": "XXXX"
}
url = "http://218.22.140.88:8181/epay/electric/queryelectricarea"
data = {
    "sysid": "1"
}
response = requests.post(url, headers=headers, cookies=cookies, data=data, verify=False)


print(response)
buils = response.json()['buils']
for buil in buils:
    buiId = buil['buiId']
    buiName = buil['buiName']
    print(buiId,buiName)

我们这里定义了headers和cookies两个字典。headers字典包含了一个键为"X-CSRF-TOKEN"的项,对应的值是"6d51ac80-b777-4a26-99a1-06bfbf65360f"。这个值可能是与服务器进行身份验证或防止跨站请求伪造(CSRF)的令牌。cookies字典包含了一个键为"JSESSIONID"的项,对应的值是"XXXX"。这个值可能是用于保持用户会话状态的令牌。,也就是我们登录信息。

我们这里要注意,cookies有时效,还有那个X-CSRF-TOKEN也是有时效的,短期的使用是没有问题的。

我们使用response.json()方法将响应的内容转换为JSON格式,并将其存储在buils变量中。然后使用for循环遍历buils中的每个元素,并分别提取出每个元素的"buiId"和"buiName"的值,看看效果如何。

1 15号楼A
8 10号楼A
9 10号楼B
10 11号楼A
11 11号楼B
12 12号楼A
13 12号楼B
14 13号楼A
15 13号楼B
16 14号楼A
17 14号楼B
78 15号楼B
85 1号楼A
86 1号楼B
87 2号楼A
88 2号楼B
89 3号楼A
90 3号楼B
91 4号楼A
92 4号楼B
93 5号楼A
94 5号楼B
95 6号楼A
96 6号楼B
97 7号楼A
98 7号楼B
99 8号楼A
100 8号楼B
101 9号楼A
102 9号楼B
199 27号楼
200 29号楼
201 30号楼
202 31号楼
203 32号楼
233 16号楼A
234 16号楼B
247 33号楼

获取房间号

我们拿到了宿舍楼的id之后,我们接下来,就是拿到每个房间的id,只有通过这个,我们才能准确的查询到电费。

import requests

headers = {
    "X-CSRF-TOKEN": "bee9698b-79a1-4c38-b5e0-2b0937fc3a28",
}
cookies = {
    "JSESSIONID": "XXX"
}
url = "http://218.22.140.88:8181/epay/electric/queryelectricrooms"
data = {
    "sysid": "1",
    "area": "1",
    "district": "1",
    "build": "1",  # 楼号
    "floor": "1"
}
response = requests.post(url, headers=headers, cookies=cookies, data=data, verify=False)

print(response)

rooms = response.json()['rooms']

for room in rooms:
    roomId = room['roomId']
    roomName = room['roomName']
    print(roomId, roomName)

我们这里和上面代码差不多,只不过,请求的地址变了,还有额外加了几个参数。"http://218.22.140.88:8181/epay/electric/queryelectricrooms"这个URL是查询房间号的API接口,用于查询房间号的相关信息。我们发送的数据("sysid"、"area"、"district"、"build"、"floor")是用来过滤或查询这些信息的参数。

我们来执行这段程序,让其输出每个房间的房间ID和房间名字,这里就展示截图了:

获取单个房间的电费

我们到这里就可以实现我们需要查询电费的功能了,我们完全可以抓这个数据,为什么我前面还是说了那么多,我主要还是为后面的内容做铺垫。

import requests


headers = {
    "X-CSRF-TOKEN": "6d51ac80-b777-4a26-99a1-06bfbf65360f",
}
cookies = {
    "JSESSIONID": "XXX"
}
url = "http://218.22.140.88:8181/epay/electric/queryelectricbill"
data = {
    "sysid": "1",
    "roomNo": "1602",
    "elcarea": "1",
    "elcbuis": "9"
}
response = requests.post(url, headers=headers, cookies=cookies, data=data, verify=False)


# print(response)

restElecDegree = response.json()['restElecDegree']
print(restElecDegree)

("sysid"、"roomNo"、"elcarea"、"elcbuis")参数就可以查询每个房间的电费,执行的结果如下:

{'retcode': 0, 'retmsg': '成功', 'multiflag': False, 'restElecDegree': 13.0}

获取整个学校电费

我们发现查询电费的数据接口就是这个样子的:


url = "http://218.22.140.88:8181/epay/electric/queryelectricbill"
data = {
        "sysid": "1",
        "roomNo": roomId,
        "elcarea": "1",
        "elcbuis": buiId,
        }

我们只要获取到roomIdbuiId,就可以,也就是我们前面讲的获取楼号和房间号。拿到这些数据,我们就可以抓取整个学校的电费了,我们每隔一段时间采集一次,我们就可以分析学校用电情况。

import time

import requests
import csv

f = open('全校电费.csv', mode='w', encoding='utf-8_sig', newline='')
csv_writer = csv.DictWriter(f, fieldnames=['楼号', '楼号ID', '房间名称', '房间号', '电费'])
csv_writer.writeheader()
headers = {
    "X-CSRF-TOKEN": "bee9698b-79a1-4c38-b5e0-2b0937fc3a28",
}
cookies = {
    "JSESSIONID": "XXX"
}

def get_buiId():
    url = "http://218.22.140.88:8181/epay/electric/queryelectricarea"
    data = {
        "sysid": "1"
    }
    response = requests.post(url, headers=headers, cookies=cookies, data=data, verify=False)
    buils = response.json()['buils']
    for buil in buils:
        buiId = buil['buiId']  # 楼号ID
        buiName = buil['buiName']  # 楼号
        # print(buiId,buiName)
        get_roomId(buiId, buiName)


def get_roomId(buiId, buiName):
    print("正在查询",buiName,"编号为",buiId)
    url = "http://218.22.140.88:8181/epay/electric/queryelectricrooms"
    data = {
        "sysid": "1",
        "area": "1",
        "district": "1",
        "build": buiId,  # 楼号
        "floor": "1"
    }
    response = requests.post(url, headers=headers, cookies=cookies, data=data, verify=False)

    # print(response)

    rooms = response.json()['rooms']

    for room in rooms:
        roomId = room['roomId']
        roomName = room['roomName']
        # print(roomId, roomName)
        get_restElecDegree(buiId, buiName, roomId, roomName)
        # time.sleep(0.5)


def get_restElecDegree(buiId, buiName, roomId, roomName):
    print("正在查询", roomName, "编号为", roomId,"电费")
    url = "http://218.22.140.88:8181/epay/electric/queryelectricbill"
    data = {
        "sysid": "1",
        "roomNo": roomId,
        "elcarea": "1",
        "elcbuis": buiId,
    }
    response = requests.post(url, headers=headers, cookies=cookies, data=data, verify=False)


    restElecDegree = response.json()['restElecDegree']
    # print(buiId, buiName, roomId, roomName, restElecDegree)
    dit = {
        '楼号': buiName,
        '楼号ID': buiId,
        '房间名称': roomName,
        '房间号': roomId,
        '电费': restElecDegree,

    }
    csv_writer.writerow(dit)


get_buiId()

我们运行看下效果。

数据分析

我们这里就获取到了一次数据,就不做数据分析了,不过要使用Python进行电费数据分析,可以按照以下步骤:

  • 导入所需的库和数据

首先需要导入数据分析所需的Python库,如pandas、numpy和matplotlib等。然后将电费数据导入到一个pandas的数据框中(DataFrame)。

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

df = pd.read_csv('全校电费.csv')
  • 数据清洗

接下来需要对数据进行清洗,包括去除重复值、缺失值和异常值等。例如,可以使用pandas的drop_duplicates()方法去除重复值:

df.drop_duplicates(inplace=True)

可以使用pandas的isnull()方法查找缺失值,并使用dropna()方法删除包含缺失值的行:

df.isnull().sum()  # 查找缺失值
df.dropna(inplace=True)  # 删除包含缺失值的行

可以使用箱线图或者散点图等方法查找并删除异常值:

plt.boxplot(df['电费'])
df = df[df['电费'] < df['电费'].quantile(0.99)]
  • 数据分析

接下来可以对数据进行分析,并使用可视化方法展示分析结果。例如,可以计算月度电费的平均值、中位数和标准差:

df['日期'] = pd.to_datetime(df['日期'])
df.set_index('日期', inplace=True)
monthly_df = df.resample('M').mean()
monthly_df['电费'].describe()  # 计算统计量

然后可以使用matplotlib绘制折线图或柱状图展示,并加上适当的标签和标题等:

plt.plot(monthly_df.index, monthly_df['电费'])
plt.xlabel('时间')
plt.ylabel('月度平均电费')
plt.title('电费趋势图')
  • 数据可视化

数据可视化可以更好地展示数据分析结果,可以使用matplotlib、seaborn和plotly等库绘制各种图表,如折线图、柱状图、散点图、热力图等,以便更好地理解数据。

import seaborn as sns

sns.scatterplot(x='用电量', y='电费', data=df)

以上是使用Python对电费数据进行数据分析的基本步骤,具体分析方法可以根据数据特点和需要进行调整和改进。

总结

我们本文详细介绍了如何采集单个房间电费,并延展到获取全校电费并且做可视化分析。

 6adf31c8c5dd4e6a83314f4805b30bc1.jpg

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

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

相关文章

新华日报-北京晚报-天津日报-投稿要求

新华日报-北京晚报-天津日报-投稿要求 报纸出版快 稳妥 价优 《中国教育报》1800字符1-3个月见报 《中国教师报》1800字符1-3个月左右见报 《光明日报》普通版 1500字符左右 各科 2个月见报 《经济日报》普通版 1500字符 1-3个月见报 《法治日报》普通版 2000字符 3个月见报…

基于子口袋的分子生成

生成与靶蛋白具有高结合亲和力的分子&#xff08;也称为基于结构的药物设计&#xff0c;structure-based drug design&#xff09;是药物发现中的一项基本且具有挑战性的任务。最近&#xff0c;深度生成模型在生成以蛋白质口袋为条件的3D分子方面取得了显著成功。然而&#xff…

怎么绘制乡土中国思维导图?了解一下这个绘制步骤

怎么绘制乡土中国思维导图&#xff1f;乡土中国思维导图是一种将中国传统文化与现代思维方法相结合的思维导图。它是一种系统化的思考方法&#xff0c;可以帮助我们更好地理解乡土中国文化的内涵和特点&#xff0c;同时也能帮助我们更好地应对当下的社会和文化问题。那么今天就…

TZOJ 曹冲养猪 (扩展)中国剩余定理

求解&#xff1a; M a1 (b1) M a2 (b2) M a3 (b3) ........ 对于 上述式子我们可以拆成 &#xff1a; M b1 * p a1 b2 * q a2 左右移项得到&#xff1a; b1 * p - b2 * q a2 - a1 可以发现 这就是一个同余方程&#xff1a; a b1 , b b2 , x p , y q , c …

关于新手学习STM32开发应该如何入门?

对于新手来说&#xff0c;学习STM32开发可能会感到困惑&#xff0c;尤其是在拿到开发板后该如何入门。在这里有嵌入式学习路线&#xff0c;毕设&#xff0c;各种项目&#xff0c;需要留个6。以下是部分内容概述&#xff1a;硬件介绍&#xff1a;了解STM32开发板的基本硬件组成和…

Chatgpt API调用报错:openai.error.RateLimitError

Chatgpt API 调用报错&#xff1a; openai.error.RateLimitError: You exceeded your current quota, please check your plan and billing details. 调用OpenAI API接口 import openai import osopenai.api_key os.getenv("OPENAI_API_KEY")result openai.Chat…

欧科云链与华为云达成战略合作,开启Web3安全合规新时代

华为云——作为全球增速最快的主流云服务提供商&#xff1b; 欧科云链——作为全球领先的Web3链上数据及合规解决方案提供商&#xff1b; 今天&#xff0c;华为云 与 欧科云链 正式达成战略合作&#xff01; 两者相加在一起&#xff0c;未来又将会碰撞出怎样的火花&#xff1f;…

01-向量究竟是什么?

文章作者&#xff1a;里海 来源网站&#xff1a;https://blog.csdn.net/WangPaiFeiXingYuan 向量究竟是什么 引入一些数作为坐标是一种鲁莽的行为 ——赫尔曼外尔 The introduction of numbers as coordinates is an act of violence - Hermann Weyl 向量的定义 向量&#xff0…

代码随想录算法训练营第50天|动态规划part08|139.单词拆分、关于多重背包,你该了解这些!、背包问题总结篇!

代码随想录算法训练营第50天&#xff5c;动态规划part08&#xff5c;139.单词拆分、关于多重背包&#xff0c;你该了解这些&#xff01;、背包问题总结篇&#xff01; 139. 单词拆分 139. 单词拆分 思路&#xff1a; 单词就是物品&#xff0c;字符串s就是背包 拆分时可以重…

【EI复现】考虑区域多能源系统集群协同优化的联合需求侧响应模型(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

远程桌面配置指南:保留TCP地址、配置隧道和使用固定TCP地址

远程桌面配置指南&#xff1a;保留TCP地址、配置隧道和使用固定TCP地址 文章目录 远程桌面配置指南&#xff1a;保留TCP地址、配置隧道和使用固定TCP地址第一步&#xff1a;保留TCP地址第二步&#xff1a;为远程桌面隧道配置固定的TCP地址第三步&#xff1a;使用固定TCP地址远程…

10. Docker Swarm(一)

目录 1、前言 2、Docker Swarm体系架构 2.1、简单介绍 2.2、体系架构 3、简单使用 3.1、环境准备 3.2、初始化master节点 3.3、建立worker节点 3.4、查看集群的节点信息 3.5、部署应用 3.5.1、创建Dockerfile文件 3.5.2、构建镜像 3.5.3、将镜像上传到Docker仓库 …

crypto-js中AES的加解密封装

在项目中安装依赖&#xff1a; npm i crypto-js在使用的页面引入&#xff1a; import CryptoJS from crypto-jscrypto-js中AES的加解密简单的封装了一下&#xff1a; //加密const KEY 000102030405060708090a0b0c0d0e0f // 秘钥 这两个需要和后端统一const IV 8a8c8fd8fe3…

栈和队列OJ题讲解

&#x1f493;博主个人主页:不是笨小孩&#x1f440; ⏩专栏分类:数据结构与算法&#x1f440; 刷题专栏&#x1f440; C语言&#x1f440; &#x1f69a;代码仓库:笨小孩的代码库&#x1f440; ⏩社区&#xff1a;不是笨小孩&#x1f440; &#x1f339;欢迎大家三连关注&…

mysql事务隔离级别详细讲解

mysql事务讲解 MySQL事务处理&#xff08;TransAction&#xff09; 大家好&#xff0c;我是一名热爱研究技术并且喜欢自己亲手实践的博主。 工作这么多年&#xff0c;一直没有深入理解MySQL的事务&#xff0c;因为最近也在面试&#xff0c;准备复习mysql的相关知识&#xff0…

verilog 实现异步fifo

理论知识参考 异步FIFO_Verilog实现_verilog实现异步fifo_Crazzy_M的博客-CSDN博客 代码 /* 位宽8bit, 位深8 */ module async_fifo#(parameter FIFO_DEPTH 8,parameter FIFO_WIDTH 8 ) (input rst_n,input wr_clk,input wr_en,input [FIFO_WIDTH - 1:0…

数据结构之红黑树

二叉搜索树对于某个节点而言&#xff0c;其左子树的节点关键值都小于该节点关键值&#xff0c;右子树的所有节点关键值都大于该节点关键值。二叉搜索树作为一种数据结构&#xff0c;其查找、插入和删除操作的时间复杂度都为O(logn),底数为2。但是我们说这个时间复杂度是在平衡的…

C#小轮子 Debug,Release,发布模式如何运行不同的代码

文章目录 前言C#运行模式运行模式介绍三种模式区分代码 前言 编译模式和发布模式的代码不一样是非常正常的。比较常见的是数据库不一样。编译测试数据库和发布真实的数据库地址不一样。 C#运行模式 运行模式介绍 运行模式有三种&#xff1a; Debug 不进行优化&#xff0c;…

逆向破解学习-经典贪吃蛇大作战_1.00

试玩游戏 有支付取消关键字 找静态代码 找到关键字 ![在这里插入图片描述](https://img-blog.csdnimg.cn/5d9f3cc57d18477794197ea5fae8c5ba.png Hook代码 import de.robv.android.xposed.XC_MethodHook; import de.robv.android.xposed.XC_MethodReplacement; import de.r…

MyBatis操作数据库常用用法总结1

文章目录 1.单表查询1.1返回所有的表记录1.2根据id查找结果1.3根据名字查找结果 2.单表修改2.1修改密码 3.单表删除3.1根据id删除信息 4.单表增加&#xff08;根据业务情况返回&#xff09;4.1添加返回影响的行数4.2添加返回影响行数和id 5.多表查询&#xff08;多&#xff09;…