前言

众所周知,我是一名苦逼的大学生,甚至在每周一、三、五的早上还要进行虎哥晨读打卡。

众所周知,大学生在学习方面的记性约等于鱼的记忆,导致我经常忘记早晨打卡。

但是,nt友好的虎哥打卡还进行了小程序提醒,不过却总是上课时提醒,待中午到寝室就又忘得一干二净。

于是,卑微的学生就写了这样一个python程序,检测是否虎哥打卡,并基于QMSG进行QQ推送催促。

这还是我的第一个真正的python爬虫!

准备工作

由于这个打卡程序是基于微信的,想要获取请求头就必须进行抓包处理,在这里,我使用的是酷友制作的软件HttpCanary小黄鸟。

Andriod 11由于文件权限问题,还需进行自行移动证书等操作,亦或者刷入酷友制作的magisk模块。

进行HttpCanary的准备工作后,我们就可以进行抓包操作,并成功抓到以下请求和响应。
请求
响应
很明显,这个请求便是我们需要的,接着,可以得知响应json中打卡的值为is_submited

写代码之前,需先观察我们抓到的请求,找出其中必要的参数。观察一下,很明显,appidapsid是我们必需的。

再加上必要的User-Agent,我们可以写出request请求的代码。

接着观察请求的网址https://apiopen.jingdaka.com/user/get_theme?calendar_id=45866274,很明显,id是我们切入的重点。在HttpCanary进行重写操作,并将id改为45866273,可以发现得到的响应是星期三的打卡。

所以所,我们可以将url写成base_url = 'https://apiopen.jingdaka.com/user/get_theme?calendar_id=%s'%(id)

python代码

对得到的请求进行分析并处理,我们就可以得到json中的is_submited

1
2
3
request = requests.get(base_url, headers=headers)
d = json.loads(request.content.decode('utf8'))
sub = d['data']['is_submited']

接着,对is_submited的值进行判断,若为0则进行QQ推送。

写好代码后,马上运行,成功返回了今天打卡的结果——is_submited的值为1

但是,我们不能仅仅局限于一天的打卡呀,应该在运行一次后更改id的值,以进行下一次的检测。

起初,我的想法是仅仅在运行时加一,但由于代码运行时,其值均为临时的值,总不能一直运行吧?

那么,我们为什么不改变文本文件中的值呢?在读取文本文件中id的值,进行检测并递增后,在将递增后的值写入文本文件,恰好解决了这个问题。

于是,新建一个id.csv存储id的值,并进行读取

1
2
3
4
5
# 读取csv中id的值
f = open('id.csv')
data = f.readline()
# 我们仅仅需要数字,用正则取出数字id
id = re.sub("\D", "", data)

在检测并判断之后,我们进行递增操作,并写入文本文件

1
2
3
4
5
6
# 必须将id强制转换成整数类型,才能进行递增操作
id = int(id)
id = id + 1
# 最后,将递增后的id写入csv文件,供下次使用
with open('id.csv', 'w') as idFile:
idFile.write('%d' % id)

就这样,python代码便大功告成,亦可进行递增操作
我这样地无比期待星期一

部署

由于打卡的特殊性,进在周一三五进行,那么触发代码的时间便与众不同。

通过阅读腾讯云函数的文档,腾讯云的Cron 表达式可以实现这种方式。代码如下

0 0 12 * * WED * 表示在每个星期三中午12点触发

但是,由于腾讯云函数并不提供文件写入权限,或者是我未发现?

如果您需要对执行过程中产生的数据进行持久化存储,请使用 COS 或 Redis/Memcached 等外部持久化存储。

我只能将其部署在自己的服务器上,期待可以找到方法解决这个问题。

当然,在github上我也遇到同样的问题,暂待解决

完整代码

由于只是个python新手,代码可读性并不高,甚至好多都是c++写法 😃

该代码仅成功运行于服务器

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
import requests
import json
import re

# 读取csv中id的值
f = open('id.csv')
data = f.readline()
# print(data)
# 我们仅仅需要数字,用正则取出数字id
id = re.sub("\D", "", data)
print(id)
base_url = 'https://apiopen.jingdaka.com/user/get_theme?calendar_id=%s'%(id)
headers = {
"User-Agent":
"Mozilla/5.0 (Linux; Android 11; Mi 10 Pro Build/RKQ1.200826.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.62 XWEB/2767 MMWEBSDK/201201 Mobile Safari/537.36 MMWEBID/4024 MicroMessenger/8.0.1.1841(0x28000151) Process/appbrand0 WeChat/arm64 Weixin NetType/4G Language/zh_CN ABI/arm64 MiniProgramEnv/android",
"content-type": "application/json",
"Accept-Encoding": "gzip,compress,br,deflate",
"version": "7.3.16",
"appid": " ",
"apsid": " ",
"charset": "utf-8",
"filter": "test1",
"Connection": "keep-alive",
"Host": "apiopen.jingdaka.com",
"Referer": "https://servicewechat.com/wx5a6e75651505714e/29/page-frame.html"
}
# 仅appid、apsid与User-Agent必需

if __name__ == '__main__':
request = requests.get(base_url, headers=headers)
d = json.loads(request.content.decode('utf8'))
# print(d)
# print(d['data']['is_submited'])
sub = d['data']['is_submited']
# print(sub)
if sub == 1:
test = 'yes'
print(test)
# 必须将id强制转换成整数类型,才能进行递增操作
id = int(id)
id += 1
# 最后,将递增后的id写入csv文件,供下次使用
with open('id.csv', 'w') as idFile:
idFile.write('%d' % id)
print(id)
else:
test = '今日英语虎哥未打卡,尽快打卡'
print(test)
id = int(id)
id += 1
with open('id.csv', 'w') as idFile:
idFile.write('%d' % id)
QmsgKey = " "
content = f"""{test}"""
data = {
"msg": content
}
url_send = "https://qmsg.zendee.cn/send/%s" % (QmsgKey)
try:
res = requests.post(url_send, data=data)
sucmsg = res.json()['success']
if sucmsg == True:
print("qq推送服务成功")
else:
print("qq推送服务失败")
except:
print("qq推送参数错误")

后记

咕咕咕咕咕咕
去tmd计算机二级C,全都是些可读性为0的代码,我为什么要报二级呀!
当初想着学习C语言知识呢,结果是个这,我还不如报个三级网络技术或数据库管理呢。
直接裸考C,考不过去球吧。