【python爬虫】每日获取强智教务系统课表,并发送短信到学生手机

自从学校换了强智的教务系统后,学校的app的查课表功能基本就报废了,记不住课表的我无奈自己动手。

功能实现:如果当天有课,在当天早上6点30以短信的形式自动发送课表至手机

首先我想的是利用模拟登陆然后直接获取课表

输入一些错误信息,点击登陆,得到一个请求

其中的flag参数是重要线索,顺着这个参数找到对应的js

此时可以发现整个加密的流程

通过向/Logon.do?method=logon&flag=sess发送请求获得一个dataStr

再将dataStr切片,分成scode与sxh

code = 用户名 + ‘%%%’ +密码

再通过for循环加密,得到encoded (登录的请求参数之一)

同时对验证码进行识别(我用的是pytesseract + PIL)

最后将userAccount(用户名)、userPassword(密码)、RANDOMCODE(验证码)、encoded作为参数向http://logon.do/?method=logon发起请求,即可完成模拟登录。

但由于pytesseract的处理能力实在有限,识图率太低了(灰度处理、二值化、降噪后处理成功率还不到一半)

然后我选择了另一种方法

强智有一个小程序叫智校园助手,利用HttpCanary可以获取强智的接口,然后又在git上找到了教务系统api的python封装

嘻嘻嘻,于是事情变得简单了起来

import time
import requests
import re
import os
import json
import datetime

#调用腾讯云api(pip install -i https://mirrors.tencent.com/pypi/simple/ --upgrade tencentcloud-sdk-python。)

from tencentcloud.common import credential
from tencentcloud.common.exception.tencent_cloud_sdk_exception import TencentCloudSDKException
from tencentcloud.sms.v20190711 import sms_client, models
from tencentcloud.common.profile.client_profile import ClientProfile
from tencentcloud.common.profile.http_profile import HttpProfile



account = ""                                 #此处为你的学号
password = ""                                #此处为密码
url = "http://218.75.197.123:83/"+"app/"   #此处你自己学校教务系统ip地址,这里以湖南工大为例


class SW(object):                            

    def __init__(self, account, password, url):
        super(SW, self).__init__()
        self.url = url
        self.account = account
        self.password = password
        self.session = self.login()               #保持会话

    HEADERS = {
        "User-Agent": "Mozilla/5.0 (Linux; U; Mobile; Android 6.0.1;C107-9 Build/FRF91 )",
        "Referer": "http://www.baidu.com",
        "accept-encoding": "gzip, deflate, br",
        "accept-language": "zh-CN,zh-TW;q=0.8,zh;q=0.6,en;q=0.4,ja;q=0.2",
        "cache-control": "max-age=0"
    }

    def login(self):
        params = {
            "method": "authUser",
            "xh": self.account,
            "pwd": self.password
        }
        session = requests.Session()
        req = session.get(self.url, params=params, timeout=5, headers=self.HEADERS)
        s = json.loads(req.text)
        # if s['flag'] != "1": exit(0)
        self.HEADERS['token'] = s['token']          #请求头中添加token
        return session
    
    def get_current_time(self):                     #获取当前时间信息
        params = {
            "method": "getCurrentTime",
            "currDate": datetime.datetime.now().strftime('%Y-%m-%d')
        }
        req = self.session.get(self.url, params=params, timeout=5, headers=self.HEADERS)
        return req.text

    def get_class_info(self, zc=-1):                #获取课表
        s = json.loads(self.get_current_time())
        params = {
            "method": "getKbcxAzc",
            "xnxqid": s['xnxqh'],
            "zc": s['zc'] if zc == -1 else zc,
            "xh": self.account
        }
        req = self.session.get(self.url, params=params, timeout=5, headers=self.HEADERS)
        return json.loads(req.text)

if __name__ == '__main__':
    Q = SW(account, password, url)
    information = Q.get_class_info()                     #当前周次课表
    s_time = json.loads(Q.get_current_time())
    year, month, day = s_time['s_time'].split("-",2)     #将课表时间拆分成年月日
    start = datetime.date(int(year), int(month), int(day))
    now = datetime.date.today()
    year, month, day = str(now).split("-", 2)            #将当前时间拆分成年月日

    kechen, shi_jian, di_dian ='', '',''
    iswork =False                                        #今天是否有课

#由于本人现在每天只有一节课,且由于我腾讯云验证为个人开发者,短信模版只允许12字变量,故以仅字符串保存变量。
如课程较多且为企业开发者,可以考虑直接将某节课的所有信息合成一个变量并存入列表中

    for i in range(len(information)):                    #遍历课表
        change_time = int(information[i]['kcsj'][0]) - 1 
        if now == start+datetime.timedelta(days=change_time):   #判断今天是否有课
            kechen = information[i]['kcmc']                     #课程名
            shi_jian = information[i]['kssj'] +"-"+ information[i]['jssj']  #课程时间
            di_dian = information[i]['jsmc']                    #上课地点
            iswork = True
    
    if iswork:
        rb = requests.get('http://wthrcdn.etouch.cn/weather_mini?city=株洲')  #天气查询
        data = json.loads(rb.text)

    
        number1 = year + "年" + month + "月" + day + "日"
        number2 = s_time['zc']
        number3 = data['data']['forecast'][0]['date'][2:]
        number4 = data['data']['forecast'][0]['type']
        number5 = data['data']['forecast'][0]['low'][2:] + "-" + data['data']['forecast'][0]['high'][2:]
        number6 = kechen
        number7 = shi_jian
        number8 = di_dian
    
        #此处8个参数用于传递给短信模版

        try:
            cred = credential.Credential("secretId", "secretKey") 
            # 实例化一个认证对象,入参需要传入腾讯云账户密钥对secretId,secretKey
            httpProfile = HttpProfile()
            clientProfile = ClientProfile()
            clientProfile.language = "en-US"
            clientProfile.httpProfile = httpProfile
            client = sms_client.SmsClient(cred, "ap-guangzhou", clientProfile)
            req = models.SendSmsRequest()
            req.SmsSdkAppid = ""    #此处填写短信应用ID
            req.Sign = ""           #此处填写短信签名
            req.SenderId = ""

            req.PhoneNumberSet = ["+86",]  #填入需要收到短信的号码
            req.TemplateID = ""    #此处填写短讯模版id
            req.TemplateParamSet =["{}".format(number1) ,
                                    "{}".format(number2),
                                    "{}".format(number3),
                                    "{}".format(number4),
                                    "{}".format(number5),
                                    "{}".format(number6),
                                    "{}".format(number7),
                                    "{}".format(number8)]   
            resp = client.SendSms(req)   #发送短信

最后只需要在利用crontab在服务器上设置一个定时任务每天6点30执行一次就可以啦

30 6 * * * python /home/kechenbiao/kechenbiao.py

最终效果;

腾讯短信可以参考 https://github.com/TencentCloud/tencentcloud-sdk-python/blob/master/examples/sms/v20190711/SendSms.py

(由于本人只需要课表,所以只做了课表查询,实际功能还有很多,包括成绩查询、空教室查询等)

  • 4
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
Python爬虫教务系统的方法有多种。根据引用,你可以通过模拟登录来实现。首先,你需要分析登录过程,了解登录请求的参数和地址。然后,你可以使用Python的requests库发送POST请求,将你的账号和密码作为参数发送给服务器。此外,如果登录时需要验证码,你可以使用百度的OCR技术来进行验证码的识别。最后,你可以使用execjs库来执行JavaScript代码,以查询成绩。 另一种简单的方法是使用Cookie来绕过登录验证。根据引用,教务系统通常通过用户Request请求中的Cookie进行身份识别。因此,你可以在爬虫访问时自建表头Header,并在表头中添加已登录的Cookie。这样,你就可以成功登录教务系统。 综上所述,Python爬虫教务系统的方法可以通过模拟登录或使用Cookie来实现。具体的实现细节取决于你所访问的教务系统的具体要求和限制。 - 本文介绍用python模拟登录中国海洋大学教务系统的方法,此系统为湖南青果软件公司开发,因此如果你学校的教务系统也是青果开发的,那么此文对你的模拟登录也会有一定的借鉴意义。 - 使用爬虫脚本成功登录教务系统,由于网站前后端分离各自负责不同工作,网站通常通过用户Request请求中的Cookie进行身份识别,因此实现登录的最简单方法就是在爬虫访问时自建表头Header,在表头中添加已登录的Cookie即可绕过登录验证。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值