利用Python自动化完成每期的青年大学习,将python脚本托管到GitHub action并设置定时任务之后即可完全解放双手。

准备工作

要想自动化地完成这一操作,首先我们得分析当我们在微信上点开青年大学习的时候,后台到底干了什么,这样我们才能知道如何去自动化地完成这一系列动作。我们怎么才能知道呢,抓包看一下嘛,遇事不决,先抓包。

抓包软件,实际上就是接管你的系统代理,所有数据包都经过这个软件之后,再到原本要去的地方,大概就这个意思。

image-20211128150137836

所以我们先要准备抓包工具

安装抓包软件

我用的是Charles,挺好用的软件,官网下载就好,安装一路点过就好了。

安装证书

软件安装完成后还要安装CA证书,点install一路下一步安装就好

image-20211128150509163

安装手机证书

由于青年大学习必须得用微信完成,大学习的网址用电脑浏览器打开会提示必须用微信打开,单纯的改浏览器UA根本没用,因为青年大学习还要用微信登陆,所以我们抓包的时候用手机操作,然后用Charles查看发送的数据包即可。

但是现在Charles仅仅接管了电脑的系统代理,不拍,刚刚的选项还有一个,给手机安装证书,点击之后手机与电脑连接统一局域网,然后手机代理设置为手动,代理主机设置为电脑即可。

image-20211128151111456

按照要求进行操作,代理主机地址就是192.168.5.6,端口8888,每个人都不一样,地址其实就是电脑的内网ip。

image-20211128151154194

然后按照要求手机访问chls.pro/ssl去下载证书文件,这时候电脑上会有提示,是否允许连接,选择allow即可,下载好证书之后在手机设置,隐私安全之类的里面安装证书即可。

现在Charles就可以对手机进行抓包了。

开始抓包

电脑端保持监听,手机正常操作打开青年大学习,一系列操作之后可以在电脑上看到,手机访问了这个网址:

image-20211128151816859

点击开始学习后,在api下的student多了commit,这就是学习是向后台提交的数据。

image-20211128152015847

编写代码测试

直接POST

可以看到,访问类型是POST,直接用python进行测试。

image-20211128152140203

import requests
url = "http://dxx.scyol.com/api/student/commit"
r = requests.post(url)
r.encoding = 'utf-8'
print(r.text)

运行结果如下,说明还是需要设置UA、token之类的东西。

image-20211128152441287

观察之前正常操作时发送的commit:

image-20211128152740705

添加UA和token

就用这个UA和token,重新编写代码测试:

import requests
url = "http://dxx.scyol.com/api/student/commit"
agent = {
"User-Agent":
"Mozilla/5.0 (Linux; Android 10;)XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", #直接复制手机访问的UA
'Content-Type': 'application/json',
"token": "XXXXXXXXXXXXXXX", #直接复制抓包获取到的token
}
r = requests.post(url, headers=agent)
r.encoding = 'utf-8'
print(r.text)

再次运行,还是有问题,说明还是缺少东西。

image-20211128153533837

想到青年大学习开始前还要填写一些信息,但是这些操作并没有涉及到填写信息,再次分析抓包数据,在/api/stages/currentInfo中发现个人信息数据。

image-20211128153811708

添加json数据

直接构造data,按照格式填入自己的数据:

import requests
url = "http://dxx.scyol.com/api/student/commit"
agent = {
"User-Agent":
"Mozilla/5.0 (Linux; Android 10;)XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", #直接复制手机访问的UA
'Content-Type': 'application/json',
"token": "XXXXXXXXXXXXXXX", #直接复制抓包获取到的token
}
data = {
'name': 'xxx',
'tel': 'xxxxxxxxxxxxx',
'org': 'xxxxxxxxx',
'lastOrg': 'xxxxxxxxxx',
'orgName': 'xxxxxxxxxxxxx',
'allOrgName': 'xxxxxxxxxxxxxxxx'
}
r = requests.post(url, headers=agent, data=json.dumps(data))
r.encoding = 'utf-8'
print(r.text)

再次运行测试,发现返回结果正常,搞定!

image-20211128154441692

利用github action自动化运行

现在虽说可以直接运行完成学习,但是手动运行跟手机上直接操作好像没有什么区别,所以 再次用万能的action:

编写workflow:

将编写好的代码保存后上传到github仓库,由于代码中有许多隐私信息,所以创建私有仓库,也可以在公有仓库中用env,但是麻烦,不用!

在仓库根目录下创建.github文件夹,在里面创建workflow文件夹,再在里面放入.yml文件就可以啦

name: action

on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
schedule:
- cron: '00 05 * * *' # 每天早上五点自动运行,这里是标准UTC时间,换算之后是北京时间13点运行。
workflow_dispatch: # Allow manual triggering
Scheduled:
inputs:
description: 'Scheduled Time' # TO-DO
required: false

jobs:
qndxx:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2
- name: Set up Python 3.9
uses: actions/setup-python@v2
with:
python-version: 3.9
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install requests
- name: 'action'
run: |
python main.py

这个文件会在每天中午一点自动运行,定时设置可以自己修改,一般一周运行两次就好了。

添加邮件提醒

每次运行之后结果对不对呢,这点我们没法第一时间知道,我不允许这样的情况出现,所以再次修改Python代码,添加发送邮件功能:

一般来说自己给自己发,寄件邮箱和收件邮箱用同一个就好了。

def Send_Email(str):
msg = MIMEText(f'运行返回结果:{str}') # 构造邮件,内容为青年大学习
msg["Subject"] = "青年大学习自动化反馈" # 设置邮件主题
msg["From"] = 'action bot' # 寄件者
msg["To"] = 'xxx' # 收件者
from_addr = 'xxxxxxxxxx@qq.com'
password = 'xxxxxxxxxxxxxxxx' # 这里用申请的授权码,不是qq邮箱密码。
smtp_server = 'smtp.qq.com' # smtp服务器地址
to_addr = 'xxx@xxx.xxx' # 收件人地址
try:
server = smtplib.SMTP_SSL(smtp_server, 465, timeout=2)
server.login(from_addr, password) # 登录邮箱
server.sendmail(from_addr, to_addr, msg.as_string())
server.quit()
print('success')
except Exception as e:
if e == None:
print('Faild:%s' % e)
pass

完整代码

import requests
import json
import smtplib
from email.mime.text import MIMEText


def Send_Email(str):
msg = MIMEText(f'运行返回结果:{str}') # 构造邮件,内容为青年大学习
msg["Subject"] = "青年大学习自动化反馈" # 设置邮件主题
msg["From"] = 'action bot' # 寄件者
msg["To"] = 'xxx' # 收件者
from_addr = 'xxxxxxxxxx@qq.com'
password = 'xxxxxxxxxxxxxxxx' # 这里用申请的授权码,不是qq邮箱密码。
smtp_server = 'smtp.qq.com' # smtp服务器地址
to_addr = 'xxx@xxx.xxx' # 收件人地址
try:
server = smtplib.SMTP_SSL(smtp_server, 465, timeout=2)
server.login(from_addr, password) # 登录邮箱
server.sendmail(from_addr, to_addr, msg.as_string())
server.quit()
print('success')
except Exception as e:
if e == None:
print('Faild:%s' % e)
pass


def main():
url = "http://dxx.scyol.com/api/student/commit"
agent = {
"User-Agent":
"Mozilla/5.0 (Linux; Android 10;)XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", #直接复制手机访问的UA
'Content-Type': 'application/json',
"token": "XXXXXXXXXXXXXXX", #直接复制抓包获取到的token
}
data = {
'name': 'xxx',
'tel': 'xxxxxxxxxxxxx',
'org': 'xxxxxxxxx',
'lastOrg': 'xxxxxxxxxx',
'orgName': 'xxxxxxxxxxxxx',
'allOrgName': 'xxxxxxxxxxxxxxxx'
}
r = requests.post(url, headers=agent, data=json.dumps(data))
r.encoding = 'utf-8'
Send_Email(r.text)


if __name__=='__main__':
main()

运行效果

image-20211128160143876