CB791135F336AB4B3460F89584993C4A

感谢同学 Vampirehh 提供源代码 👏

我提供了 Github Actions 定时运行的思路 😉

鉴于原作者没有公开代码,我也就不公开 GitHub 仓库了。由于思路和整体流程还是很简单的,我这里重新整理一下。

前期准备

  1. PC端抓包工具:官网下载 Fiddler Classic 就可以。
  2. PC端登录微信。
  3. Python 以及 requests 模块。
  4. 想要每天自动执行的话还需要 GitHub 账号或者网络服务器一台,相比于后者注册个 GitHub 要简单的多。

打卡代码编写

大体思路还是很简单的,我们需要用抓包工具获取到打卡签到时发送的数据包,再使用 Python 的 requests 模块模拟这个请求。其实这个思路在我刚刚读研的时候就有,只是当时我卡在了下面的第一步。😅

Fiddler 抓取 Https

我本身代码能力一般,又不懂网络编程,不知道是不是所有微信小程序都需要使用 Https 协议。我们学院的信仰不息小程序使用的是 Https 协议,在我研一的时候我就尝试过使用 Fiddler 去抓包,可就是抓不到。直到后来看到了Vampirehh同学提供的代码,我问他我怎么抓不到,他告诉我需要设置一下。于是我打开了 Bing, 搜索之后发现 Fiddler 在默认情况下不会捕获 Https,需要自己手动设置一下。

打开 Fiddler,选择 Tools -> Options; 在 Options 选项卡中 选择 Https,勾选 Capture Https CONNECTs ,Decrypt HTTPS ttaffic 和 Ignore server certificate errors(unsafe)。最后点击 OK。

image-20211106175554372

image-20211106175702394

抓包开始

接下来,我们就可以打开信仰不息小程序,进行抓包工作了。

PC 端登录小程序。

image-20211106180333615

填写基本信息,点击提交按钮。

动画

接下来,在 Fiddler 界面中可以看到响应结果是 200 主机(Host) 是 www.dmuistac.com 的一个请求。我们点击这个请求,查看具体的信息。

image-20211106183311155

从具体的信息中,实际上我就就可以通过在浏览器中访问原始请求数据来进行签到了。

image-20211106184905008

比如,我可以通过访问如下地址来进行签到。(你点一下就帮我签到一次😁)

https://www.dmuisatc.com/DMU_WEB/student_5/info/?jsonnumber=1120200298&jsonname=汪广鑫&jsonclass=2020级硕士研究生中队&morning=36.4℃&afternoon=36.4℃&night=36.4℃&jsonbody=1&jsonbodychangeinfo=&textarea=在校&textprople=同学&jsontouch=1&jsontouchchangeinfo=0&jsonisolate=1&jsonisolatechangeinfo=0&latitude=38.91369&longitude=121.61476

这个链接是这样组成的。

image-20211106185715185

浏览器访问的结果就是下面这样。

image-20211106185351851

为了进一步证明我们的浏览器访问是可以签到的,我们可以点击微信小程序的我的填报按钮,来查看 FIddler 最新抓到的包,可以看到最近一次签到的时间。

image-20211106190025042

可以看到今天最后一次填报的时间就是我刚刚访问浏览器的时间。

image-20211106190220552

编写代码

接下来,我们就可以编写 python 代码,使用代码进行签到了。

Host 改变了

import requests

url = "https://www.dmuisatc.com/DMU_WEB/student_5/info/?jsonnumber=112020028&jsonname=%E6%B1%AA%E5%B9%BF%E9%91%AB&jsonclass=2020%E7%BA%A7%E7%A1%95%E5%A3%AB%E7%A0%94%E7%A9%B6%E7%94%9F%E4%B8%AD%E9%98%9F&morning=36.4%E2%84%83&afternoon=36.4%E2%84%83&night=36.4%E2%84%83&jsonbody=1&jsonbodychangeinfo=&textarea=%E5%9C%A8%E6%A0%A1&textprople=%E5%90%8C%E5%AD%A6&jsontouch=1&jsontouchchangeinfo=0&jsonisolate=1&jsonisolatechangeinfo=0&latitude=38.91369&longitude=121.61476"

headers = {
    'Host': 'www.dmuisatc.com', 
    'Connection': 'keep-alive',
    'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36 MicroMessenger/7.0.9.501 NetType/WIFI MiniProgramEnv/Windows WindowsWechat',
    'content-type': 'application/json',
    'Referer': 'https://servicewechat.com/wx8a86613d14cbe10c/12/page-frame.html',
    'Accept-Encoding': 'gzip, deflate, br'
}

res = requests.get(url,headers=headers)

print(res.text)
print(res)

执行上面的代码即可完成你的签到。

image-20211106191211855

再次点击小程序的 我的填报,可以看到 FIddler 的最新抓包结果显示代码也确实实现成功签到了。

image-20211106192738656

代码优化

上面的代码已经能够实现我们的基本需求,但是请求的链接是编码过的,看起来不是很友好。接下来我们写一个人看的版本。

首先我们依据 WebForms 编写字典,在利用 urlencode() 函数对字典进行 url 编码,最后请求编码后的 url 链接即可。

首先在 FIddler 中点击 WebForms,查看表单内容。

image-20211106194345600

将表单内容写成字典。

import requests
from urllib.parse import urlencode

url = "https://www.dmuisatc.com/DMU_WEB/student_5/info/?"

headers = {
    'Host': 'www.dmuisatc.com', ## 已经变了
    'Connection': 'keep-alive',
    'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36 MicroMessenger/7.0.9.501 NetType/WIFI MiniProgramEnv/Windows WindowsWechat',
    'content-type': 'application/json',
    'Referer': 'https://servicewechat.com/wx8a86613d14cbe10c/12/page-frame.html',
    'Accept-Encoding': 'gzip, deflate, br'
}

data = {
    "jsonnumber": "1120200298",
    "jsonname": "汪广鑫",
    "jsonclass": "2020级硕士研究生中队",
    "morning": "36.2℃",
    "afternoon": "36.2℃",
    "night": "36.2℃",
    "jsonbody": 1,
    "jsonbodychangeinfo": "",
    "textarea": "学校",
    "textprople": "同学",
    "jsontouch": 1,
    "jsontouchchangeinfo": 0,
    "jsonisolate": 1,
    "jsonisolatechangeinfo": 0,
    "latitude": 38.8699,    # 最后两个是经纬度
    "longitude": 121.5276,  # 可以通过谷歌地图获取想要定位位置的经纬度
}

res = requests.get(url+urlencode(data),headers=headers)

print(res.text)
print(res)

执行上面的代码,依然可以签到成功。

image-20211106195156659

最后,提供一个多人同时签到的版本,其实就是把 jsonnumber 和 jsonname 写成列表的形式。

import requests
from urllib.parse import urlencode
import json
import time

headers = {
    'Host': 'www.dmuisatc.com',  ## 已经变了 
    'Connection': 'keep-alive',
    'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36 MicroMessenger/7.0.9.501 NetType/WIFI MiniProgramEnv/Windows WindowsWechat',
    'content-type': 'application/json',
    'Referer': 'https://servicewechat.com/wx8a86613d14cbe10c/10/page-frame.html',
    'Accept-Encoding': 'gzip, deflate, br'
}

datas = []

id = ["学号1","学号2","学号3"]
name = ["姓名1","姓名2","姓名3"]

for i in range(len(id)):
    datas.append({
    "jsonnumber": id[i],
    "jsonname": name[i],
    "jsonclass": "2020级硕士研究生中队",
    "morning": "36.2℃",
    "afternoon": "36.2℃",
    "night": "36.2℃",
    "jsonbody": 1,
    "jsonbodychangeinfo": "",
    "textarea": "学校",
    "textprople": "同学",
    "jsontouch": 1,
    "jsontouchchangeinfo": 0,
    "jsonisolate": 1,
    "jsonisolatechangeinfo": 0,
    "latitude": 38.8699,
    "longitude": 121.5276,
})

for j in range(len(id)):
    url = 'https://www.dmuisatc.com/DMU_WEB/student_5/info/?'
    url = url + urlencode(datas[j])
    print(url)
    daka = requests.get(url, headers=headers)
    print(daka.text)
    print(daka)
    time.sleep(10)

基于 GitHub Actions 实现自动签到

如果你有网络服务器,可以把这个脚本放在服务器上执行定时任务,考虑到大多数人是没有服务器的,所以我们这里介绍如何利用GitHub Actions 实现自动签到。

我不会做科普工作,如果你不知道什么是 GitHub Actions 建议自行百度。这里只教你怎么做,一步一步跟着做就好了。

首先,登录 GitHub,创建一个新的仓库。

image-20211107021356227

填写基本信息点击创建仓库。

image-20211107021517003

创建 python 文件并粘贴已经写好的代码。

动画

同样的步骤再创建一个执行代码所需要的环境文件,requirements.txt

image-20211107022251748

接下来创建 GitHub Actions 的配置文件。

image-20211107022814602

文件的内容如下:


name: XinYangBuXi

on:
  push:
    branches: [ master ]
  pull_request:
    branches: [ master ]
  watch:
    types: started
  schedule:
    - cron: "0 */8 * * *"

jobs:
  XinYangBuXi:
    runs-on: ubuntu-latest

    steps:
    - name: 'Checkout codes'
      uses: actions/checkout@v2

    - name: 'setup python'
      uses: actions/setup-python@master
      with: 
        python-version: 3.7
      
    - name: 'requirements'
      run: |
        pip3 install -r requirements.txt
        
    - name: '打卡'
      run: |
        python daka.py
        echo `date +"%Y-%m-%d %H+8:%M:%S"` begin > time.log
        
    - name: 'Commit Files'
      id: commit
      run: |
        git config --local user.email "action@github.com"
        git config --local user.name "GitHub Action"
        git add .
        git diff --quiet && git diff --staged --quiet || git commit -am 'avoid being suspended'
        echo ::set-output name=status::success
           
    - name: 'GitHub Push'
      if: steps.commit.output.status != 'success'
      uses: ad-m/github-push-action@v0.6.0
      with:
        github_token: ${{ secrets.GITHUB_TOKEN }}
        branch: ${{ github.ref }}

接下来点击 Actions 可以看到一个已经运行的工作流。如果你是第一次使用 GitHub Actions 可能还需要点几个 Enable ,自己看情况操作就行了。如果你看到了下图画面,就表示代码已经成功运行了。

image-20211107023438506

我们点击查看具体运行情况。

image-20211107023533276

可以看到确实打卡成功了✨

image-20211107023633178

我们的仓库里会多一个 time.log 文件,里面记录着上一次执行代码的时间。

image-20211107023737836

至此,Fuck 信仰不息的工作就已经完成了。我们以后再也不需要抱歉了。

打卡提醒

使用 SMTP 服务可以收到邮件提醒,SMTP 服务我觉得国内的 QQ 邮箱和 163 邮箱都挺好用的,由于我不想每天都收到邮件提醒,就不写相关代码了。有兴趣的自行百度吧,毕竟我也是面向百度程序设计的。

使用 Qmsg 的服务可以实现 QQ 提醒。

类似地,使用 Server酱 的服务可以实现微信提醒。

我嫌弃这些提醒太烦人了,我选择使用 Telegram Bot 进行提醒,其实不叫提醒,因为我手机的 Telegram 不会主动推送消息,可能是代理服务器不太好用的原因吧,我只是需要一个记录程序执行结果的地方,我想主动查看的时候不必去 GitHub,看一眼手机就可以了。

在你已经申请好 Telegram Bot 并且已知自己 chat ID 的情况下,只需加入以下几行代码就可以完成推送了。

import telebot # 你需要在你的 requirements.txt 文件中加入 pyTelegramBotAPI

chat_id = ""
token = ""
bot = telebot.TeleBot(token)

bot.send_message(chat_id=chat_id,text=str(daka)+'\n'+str(daka.text) + '\n\n')

推送结果:

F95366DDD073A928F4BA86C79ABE4E71

最后,请注意,如果你和我一样,只会面向百度程序设计,把所有变量都写死。换句话说,如果你的脚本里暴漏了你的 SMTP 密码或者 Qmsg Token 或者 Server酱 Token 或者 Telegram Bot 的 Token,那么你应该把你的仓库设置成私有的,以防止恶作剧者利用这些对你进行骚扰,甚至是进行违法行为!

必看的更新内容

2021 年 11 月 16 日

信仰不息的 Host 改变了

image-20211116180202087

所以现在应该 get 请求 www.informationofdum.com 这个地址了。

代码更新为:

import requests
from urllib.parse import urlencode
import json
import time

headers = {
    'Host': 'www.informationofdum.com',  
    'Connection': 'keep-alive',
    'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36 MicroMessenger/7.0.9.501 NetType/WIFI MiniProgramEnv/Windows WindowsWechat',
    'content-type': 'application/json',
    'Referer': 'https://servicewechat.com/wx8a86613d14cbe10c/13/page-frame.html',
    'Accept-Encoding': 'gzip, deflate, br'
}

datas = []

id = ["学号1","学号2","学号3"]
name = ["姓名1","姓名2","姓名3"]

for i in range(len(id)):
    datas.append({
    "jsonnumber": id[i],
    "jsonname": name[i],
    "jsonclass": "2020级硕士研究生中队",
    "morning": "36.2℃",
    "afternoon": "36.2℃",
    "night": "36.2℃",
    "jsonbody": 1,
    "jsonbodychangeinfo": "",
    "textarea": "学校",
    "textprople": "同学",
    "jsontouch": 1,
    "jsontouchchangeinfo": 0,
    "jsonisolate": 1,
    "jsonisolatechangeinfo": 0,
    "latitude": 38.8699,
    "longitude": 121.5276,
})

for j in range(len(id)):
    url = 'https://www.informationofdum.com/DMU_WEB/student_5/info/?'
    url = url + urlencode(datas[j])
    print(url)
    daka = requests.get(url, headers=headers)
    print(daka.text)
    print(daka)
    time.sleep(10)