图书馆预约小工具
2022/3/15 · 2 min read
代码
#!/usr/bin/env python3
import json
import requests
import re
import datetime
from typing import TypedDict
MayaTime = TypedDict('MayaTime', {'st': str, 'et': str})
session = requests.session()
sid = 223 # 座位号
# 获取起止时间字典
def getTime(st: int, et: int) -> MayaTime:
st = '0' + str(st) if st < 10 else st
et = '0' + str(et) if et < 10 else et
return {
'st': f'{st}:00',
'et': f'{et}:00'
}
# 获取提交数据
def getDateTimeSection() -> any:
times = [getTime(9, 21), getTime(14, 21), getTime(14, 21), getTime(9, 21), getTime(17, 21),
getTime(9, 21), getTime(9, 21)]
tomorrow = (datetime.datetime.now() + datetime.timedelta(days=+1))
week = tomorrow.weekday()
at_date = tomorrow.strftime("%Y-%m-%d")
return {
'atDate': at_date,
'st': at_date + ' ' + times[week].get('st'),
'et': at_date + ' ' + times[week].get('et'),
'sid': sid,
}
# 获取登陆页面内容
def getLoginPageContent() -> str:
return session.get('https://libzwxt.ahnu.edu.cn/SeatWx/login.aspx').text
# 获取登陆所需字段
def getLoginPostData(login_page_content: str) -> dict:
login_post_data = {
'Button1': '登 录 ',
'hfurl': ''
}
params_name_list = ['__VIEWSTATE', '__VIEWSTATEGENERATOR', '__EVENTVALIDATION']
for param_name in params_name_list:
param_regex = re.compile(rf'id=\"{param_name}\" value=\".+\"')
ret = param_regex.search(login_page_content)
param_value = ret.group()
login_post_data[param_name] = param_value.split("\"")[3]
return login_post_data
# 登陆
def login(tb_user_name: str, tb_pass_word: str) -> None:
login_page_content = getLoginPageContent()
login_post_data = getLoginPostData(login_page_content)
login_post_data["tbUserName"] = tb_user_name
login_post_data["tbPassWord"] = tb_pass_word
ret = session.post('https://libzwxt.ahnu.edu.cn/SeatWx/login.aspx', login_post_data).text
# 预约
def reserve() -> None:
reserve_post_data = getDateTimeSection()
header = {
# 设定报文头
'Host': 'libzwxt.ahnu.edu.cn',
'Origin': 'http://libzwxt.ahnu.edu.cn',
'Referer': 'http://libzwxt.ahnu.edu.cn/SeatWx/Seat.aspx?fid=3&sid=1438',
'User-Agent': "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36",
'X-AjaxPro-Method': 'AddOrder',
}
ret = session.post('https://libzwxt.ahnu.edu.cn/SeatWx/ajaxpro/SeatManage.Seat,SeatManage.ashx',
data=json.dumps(reserve_post_data), headers=header).text
sendEmail(ret)
def sendEmail(message: str) -> str:
print(message)
data = {
'receiver': '1327909321@qq.com',
'title': '图书馆预约通知',
'content': message
}
print('发送邮件...')
ret = requests.post('http://api.mayapony.site/mailer', data=data).text
return ret
if __name__ == '__main__':
print('开始预约!')
# noinspection PyBroadException
try:
login('帐号', '密码')
print('登陆成功,正在预定...')
reserve()
except Exception as e:
sendEmail('出错!')
print('执行完毕!')
使用
-
把
python
代码文件放到服务器上,使用shell脚本执行(方便后期使用crontab
进行定时执行)python3 /path/to/index.py
使用
chmod +x /path/to/shellName.sh
使脚本可执行。 -
或者在
python
文件头部添加注释#!/usr/bin/env python3
,并使用chmod
使其可执行即可。
安装 Python3.8
在放到服务器上执行报错:
ImportError: cannot import name 'TypedDict'
这是因为 TypedDict
仅支持 python3.8
之后的版本,需要进行安装。
-
下载 python 包:
wget https://www.python.org/ftp/python/3.8.2/Python-3.8.2.tar.xz
-
解压
xz -d Python-3.8.2.tar.xz
xz
是一个压缩工具参数说明:
-z, --compress # 强制压缩 -d, --decompress, --uncompress # 强制解压 -t, --test # 测试压缩文件的完整性 -l, --list # 列出有关.xz文件的信息 -k, --keep # 保留(不要删除)输入文件 -f, --force # 强制覆盖输出文件和(解)压缩链接 -c, --stdout, --to-stdout # 写入标准输出,不要删除输入文件 -0 ... -9 # 压缩预设; 默认为6; 取压缩机*和* # 使用7-9之前解压缩内存使用量考虑在内! -e, --extreme # 尝试通过使用更多的CPU时间来提高压缩比; # 要求不影响解压缩存储器 -T, --threads=NUM # 最多使用NUM个线程; 默认值为1; set to 0 # 设置为0,使用与处理器内核一样多的线程 -q, --quiet # 抑制警告; 指定两次以抑制错误 -v, --verbose # 冗长; 指定两次更详细 -h, --help # 显示这个简洁的帮助并退出 -H, --long-help # 显示更多帮助(还列出了高级选项) -V, --version # 显示版本号并退出
-
安装:
cd Python-3.8.2 # 安装目录 ./configure --prefix=/usr/local/python3 # 编译 make # 编译安装 make install # 建立软链接 ln -s /usr/local/python3/bin/python3.8 /usr/bin/python ln -s /usr/local/python3/bin/pip3 /usr/bin/pip
OK!
装好了,迫不及待执行 python index.py
进行测试,结果发现无法请求图书馆接口!!,尝试 ping
图书馆域名也不通,果断放弃暂时先在自己电脑上跑着吧。
设置定时
crontab -e
在打开的buffer里添加:
10 6 * * * /path/to/index.py
意思是每天的六点十分执行。美滋滋