由于上课需要,我每周都要从学院路坐校车到沙河,但是智慧北航的放票向来都是到点就空.哪怕卡点抢票也不一定抢得到.因此,我制作了一份简陋的抢课脚本用来辅助我抢票,以下是对代码的原理介绍.

SBT_v0.9 代码解释

首先申明,本程序不会收集用户信息,请放心使用.

目前上传到 github 上的为 exe 文件,包含了 python 源代码所需的所有库,因此会比较大,共 100 多 M.

验证码图片识别

首先,观察抢票网页,我们发现有输入验证码环节,这一步是脚本需要攻克的最主要环节.于是我们使用了 ddddocr 这个开源库函数,非常好用!

代码如下:

1
2
3
4
5
6
7
8
9
# 识别验证码
headers = {
"User-Agent": user_agent,
}
response = requests.get(pathOfAuth, cookies=cookies, headers=headers) # type: ignore
img_bytes = io.BytesIO(response.content)
img = Image.open(img_bytes)
ocr = ddddocr.DdddOcr()
checkStr = ocr.classification(img)

这一步能够自动扫描验证码信息并存为checkStr变量,准确率很高.

跳转支付界面

在解决了最重要问题之后,我们需要模拟真实网页将”去支付”这一请求发送到验证网址,然后再获取验证网址反馈给我们的支付链接.到这一步,抢票就已经实现了,只需要点开链接缴费就行.

这里的代码直接参考了车票网站的源代码,可以说是直接”借鉴”了,读书人的事儿,能叫抄嘛~

代码如下:

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
response = requests.post(url, data=payload, cookies=cookies, headers=headers2)
print("Response Content:", response.content.decode("utf-8", "ignore"))

if response.status_code == 200:
try:
result = response.json()
if result["status"] == "1":
if result["price"] <= 0:
print(
"Payment Success: Redirecting to",
"/wechat/paySuccess?orderId="
+ result["orderId"]
+ "&code="
+ result["code"],
)

else:
print("Payment Redirect: Redirecting to", result["url"])
else:
print("Payment Failed:", result["message"])
except:
print("JSON Decode Error: The response content is not in JSON format.")
else:
print("Error:", response.status_code)



模拟网页点击,获取信息

解决了获取验证码之后的操作,我们需要回过头来解决登录认证问题.在这一步由于涉及 JavaScript 等命令,我们无法单纯使用 python 来模拟网页请求,结合 selenium 这个库,我们选择用edge 浏览器来充当获取认证信息的关键驱动.

获取验证码地址

获取个人信息的 cookies 之后,我们只需等待抢票网页更新,脚本打开获取验证码服务器的网址.之后调用 ddddocr 库来识别验证码.这一整套流程就完成了.

总结

在制作脚本时遇到了不少困难,甚至走了很长的一条弯路.起初我因为不会 selenium,甚至打算用 JavaScript 代码段强行调出验证码链接.感谢thomas舍友的大力支持!没有他,该脚本只能实现半自动,并且问题重重.

我们将持续更新,有空做出像样的 GUI 界面并且优化一下抢票速度.~

如果你想使用源代码,请点击以下链接:
此处下载源代码