-
Notifications
You must be signed in to change notification settings - Fork 0
/
electricity.py
90 lines (71 loc) · 2.92 KB
/
electricity.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
import asyncio
import aiohttp
from bs4 import BeautifulSoup
import xml.dom.minidom as dom
import re
from parse_room import InvalidRoomNameError, parse_room, normalize_name
def getForm(soup: BeautifulSoup, form_id):
form = {}
for i in soup.find(id=form_id).find_all('input'):
if 'value' in i.attrs:
form[i['name']] = i['value']
return form
url = 'http://202.120.163.129:88'
async def updateForm(session, form, soup: BeautifulSoup, key, value):
"该网页每次选择了选项后都会提交一次表单,此函数提交原来的并获得新的表。"
def normalized_equal(s):
return normalize_name(s) == normalize_name(value)
select = soup.find('select', id=key)
opt = select.find('option', string=normalized_equal)
if opt is None:
raise InvalidRoomNameError(value)
data = {key: opt['value']}
form.update(data)
async with session.post(url, data=form) as resp:
text = await resp.text()
soup = BeautifulSoup(text, 'lxml')
new_form = getForm(soup, 'form1')
form.update(new_form)
return soup
async def get_left_electricity(data):
"根据提供的房间数据访问能源管理中心以查询电费"
async with aiohttp.ClientSession(cookie_jar=aiohttp.CookieJar(unsafe=True)) as s:
#从ip接收cookies需要unsafe的cookie jar
async with s.get(url) as resp:
text = await resp.text()
soup = BeautifulSoup(text, 'lxml')
form = getForm(soup, 'form1')
keys = ['drlouming', 'drceng', 'dr_ceng', 'drfangjian']
for k, v in zip(keys, data):
soup = await updateForm(s, form, soup, k, v)
form.update({
'radio': 'usedR',
'ImageButton1.x': 51,
'ImageButton1.y': 37})
async with s.post(url, data=form, raise_for_status=True) as resp:
# 如果allow_redirects=False的话还得手动再转发一次
# async with s.get(url+'/usedRecord1.aspx') as resp:
text = await resp.text()
try:
pattern = r'(剩余电量|剩余金额).+?([+-]?\d+\.?\d*).*?([元度])'
return re.search(pattern, text).group(1, 2, 3)
except Exception as e:
raise ValueError(e)
async def query_electricity(room_name):
"解析房间名并在能源管理中心查询电费。"
try:
room, std_name = parse_room(room_name)
except Exception as e:
if isinstance(e, InvalidRoomNameError):
raise
else:
raise InvalidRoomNameError(e)
elec = await get_left_electricity(room)
return std_name, elec
async def main():
# 没有西南一
names = '西南一1022;8—404;20- 533;13-543;博士3号楼1303;西南11 216;西北三139;西南二539-1;彰武三1406;彰武8 1413;12-711'.split(';')
for r in await asyncio.gather(*map(query_electricity, names)):
print(r)
if __name__ == "__main__":
asyncio.run(main())