飞天加速计划·高校学生在家实践——教务系统查成绩Python爬虫程序

简介: 期末考试刚结束,查成绩需要登录到教务系统,比较繁琐。而成绩只有老师在系统中录入之后才能查到,我们也不知道老师什么时候录成绩,又很急着想知道每一门课的成绩。想到的解决办法就是24小时不停地访问教务系统,不停地查成绩。如果出了新的成绩,就给我发邮件。之前写过一个教务系统Python爬虫程序,这次通过学生活动免费领取了阿里云的服务器,把Python程序放在服务器上定时运行,这让我成为班里每一门课都是第一个知道成绩的人

我就读于自动化专业,现为一名大三学生。本学期学习了“智能控制终端技术”课程,教学内容包括网络与通信基础、基于C++的Qt界面开发、Linux入门等。

在上个学期末,也就是大三上考完试后,我觉得查考试成绩十分地繁琐,每天打开教务查成绩也很浪费时间、分散精力。于是编写了一个Python爬虫程序帮我去教务系统中爬取成绩,打印成绩单并计算GPA。在本学期的Linux入门课程学习中,了解到Linux系统除了在自己电脑上装虚拟机,或双系统,还可以通过购买租赁阿里云服务器的方式使用。

于是,我通过飞天加速计划·高校学生在家实践活动获得了两周的免费阿里云ECS(弹性计算服务)使用机会。我花了一个晚上的时间熟悉了云服务器的基本操作,并扩充了之前的教务系统查成绩爬虫代码,并将Python程序运行于阿里云ECS上。在官方教程指导下,从服务器租赁到程序部署,非常简单而迅速。

当出成绩之后,程序会给我发邮件,截图如下:
729CBE10-9572-4CEC-8AA4-3F7B6706E9BD.jpeg
DF967B56-D132-4ED6-ABAF-FE114C62E6BC.jpeg

下面来介绍一下我的教务系统查成绩Python程序

整个程序的实现步骤分为以下几部分:
1.教务系统爬虫
2.发邮件
3.整合1和2到一个py脚本中
4.部署到阿里云Linux服务器
除了py脚本,还需要在同一个路径下创建一个名为1.txt的文本文档,用于存放上一次查询时,出了几门课的成绩,比如:上一次查询出了3门课的成绩,那么1.txt文档的内容就是3

1.教务系统爬虫
我们学校的教务系统是正方软件股份有限公司开发的,实现的思路是:

  • 在Chrome浏览器里打开教务系统并登陆,找到查成绩的页面
  • 打开浏览器检查功能(F12),找到FXH文件,刷新网页,一般来说,成绩信息会存在一个json格式的文件中
  • 用python的requests库进行带参数的请求,带上headers、data,cookie会在请求头里
  • 从json文件中提取成绩相关的元素,存入变量
import requests
headers = {}          # 需要填充一下,是字典的形式,可以在浏览器中用检查找到请求头等信息
data =  {}            # 和headers一样要自己填充
url = 'https://jwxt.cjlu.edu.cn/cjcx/cjcx_cxXsgrcj.html?'
res = requests.post(url, headers = headers, data = data)
json = res.json()

text = text + "\r\n{} {} {} {}".format('课程名称'.center(10, chr(12288)), '学分'.center(4, chr(12288)), '成绩'.center(4, chr(12288)), '绩点'.center(4, chr(12288)))
sum_credit_gp = 0.0
sum_credit = 0.0
for each in json['items']:
    subject = each['kcmc']          # 课程名称
    credit = each['xf']             # 学分
    grade = each['bfzcj']           # 成绩
    gradepoint = each['jd']         # 绩点

    credit_gp = float(credit) * float(gradepoint)    # 学分绩点 = 学分*绩点
    sum_credit = sum_credit + float(credit)
    sum_credit_gp = sum_credit_gp + credit_gp        # 计算GPA

    text = text + "\r\n{}   {}   {}   {}".format(subject.center(10, chr(12288)), credit.center(4, chr(12288)), grade.center(4, chr(12288)), gradepoint.center(4, chr(12288)))

print(text)

#with open("/home/yrl/request_grade/1.txt", 'r') as f:                          # 部署到linux系统中,使用绝对路径
with open("1.txt", 'r') as f:               # 1.txt存储上一次num的数值
    num = f.read()                          # 出了几门课的成绩,num就是几
    if num == str(len(json['items'])):
        print("没有变化")
        # 不发送邮件

if num!=str(len(json['items'])):
    #with open("/home/yrl/request_grade/1.txt", 'w') as f:
    with open("1.txt", 'w') as f:
        print("发生变化,出了新的成绩")
        # 发送邮件
        self.send_mail()
        # 并修改txt文件
        f.write(str(len(json['items'])))

2.发邮件
发邮件程序中需注意

  • from_addr是发信人的邮箱
  • to_addr是收信人的邮箱,发信人和收信人邮箱可以是同一个
  • password是POP3授权码,我用的是qq邮箱,应该是一个16位的字符串
import smtplib                                                #调用smtplib模块 用于发信动作
from email.mime.text import MIMEText                          #调用MIMEText方法 构建邮件内容
from email.header import Header                               #从email包引入Header()方法 构建邮件头

from_addr = "xxxxx@qq.com"
password = "xxxxx"                                            #POP   授权码
to_addr = "xxxxx@qq.com"
smtp_server = 'smtp.qq.com'                                   #发信服务器
title = '请输入邮件标题'
text = '请输入正文内容'                                 

msg = MIMEText(text,'plain','utf-8')                          #正文内容 参1为正文内容 参2为格式(plain为纯文本) 参3为编码
msg['From'] = Header(from_addr)                               #构建邮件头
msg['To'] = Header(to_addr)                                   #构建邮件头
msg['Subject'] = Header(title)                                #构建邮件头

server = smtplib.SMTP_SSL(smtp_server)                        #开启发信服务,这里使用的是加密传输
server.connect(smtp_server,465)

server.login(from_addr, password)                             #登录
server.sendmail(from_addr, to_addr, msg.as_string())          #发送 参1发件人 参2收件人 参3"内容"
server.quit()                                                 #关闭服务器

print('邮件已发送')

3.整合1和2到一个py脚本中

import requests
import smtplib                                                #调用smtplib模块 用于发信动作
from email.mime.text import MIMEText                          #调用MIMEText方法 构建邮件内容
from email.header import Header                               #从email包引入Header()方法 构建邮件头

class RequestGrade:
    text = ""
    def send_mail(self):
        from_addr = "xxxxx@qq.com"
        password = "xxxxx"                                 #POP   授权码
        to_addr = "xxxxx@qq.com"
        smtp_server = 'smtp.qq.com'                                   #发信服务器
        title = '出了新的成绩'
        
        msg = MIMEText(self.text,'plain','utf-8')                     #正文内容 参1为正文内容 参2为格式(plain为纯文本) 参3为编码
        msg['From'] = Header(from_addr)                               #构建邮件头
        msg['To'] = Header(to_addr)                                   #构建邮件头
        msg['Subject'] = Header(title)                                #构建邮件头

        server = smtplib.SMTP_SSL(smtp_server)                        #开启发信服务,这里使用的是加密传输
        server.connect(smtp_server,465)

        server.login(from_addr, password)                             #登录
        server.sendmail(from_addr, to_addr, msg.as_string())          #发送 参1发件人 参2收件人 参3"内容"
        server.quit()                                                 #关闭服务器

        print('邮件已发送')

    def get_grade(self):
        headers = {}
        data =  {}

        url = 'https://jwxt.cjlu.edu.cn/cjcx/cjcx_cxXsgrcj.html?'
        res = requests.post(url, headers = headers, data = data)
        json = res.json()

        print("\n{} {} {} {}".format('课程名称'.center(10, chr(12288)), '学分'.center(4, chr(12288)), '成绩'.center(4, chr(12288)), '绩点'.center(4, chr(12288))))
        self.text = self.text + "\r\n{} {} {} {}".format('课程名称'.center(10, chr(12288)), '学分'.center(4, chr(12288)), '成绩'.center(4, chr(12288)), '绩点'.center(4, chr(12288)))
        sum_credit_gp = 0.0
        sum_credit = 0.0
        for each in json['items']:
            subject = each['kcmc']
            credit = each['xf']
            grade = each['bfzcj']
            gradepoint = each['jd']

            credit_gp = float(credit) * float(gradepoint)
            sum_credit = sum_credit + float(credit)
            sum_credit_gp = sum_credit_gp + credit_gp

            print("{}   {}   {}   {}".format(subject.center(10, chr(12288)), credit.center(4, chr(12288)), grade.center(4, chr(12288)), gradepoint.center(4, chr(12288))))
            self.text = self.text + "\r\n{}   {}   {}   {}".format(subject.center(10, chr(12288)), credit.center(4, chr(12288)), grade.center(4, chr(12288)), gradepoint.center(4, chr(12288)))

        print('\n\t\tGPA:{:.5f}'.format(sum_credit_gp / sum_credit))
        self.text = self.text + ('\r\n\t\tGPA:{:.5f}'.format(sum_credit_gp / sum_credit))

        with open("/home/yrl/request_grade/1.txt", 'r') as f:
        #with open("1.txt", 'r') as f:
            num = f.read()                          # 出了几门课的成绩
            if num == str(len(json['items'])):
                print("没有变化")
                # 不发送邮件
        
        if num!=str(len(json['items'])):
            with open("/home/yrl/request_grade/1.txt", 'w') as f:
            #with open("1.txt", 'w') as f:
                print("发生变化,出了新的成绩")
                # 发送邮件
                self.send_mail()
                # 并修改txt文件
                f.write(str(len(json['items'])))

if __name__ == "__main__":
    r = RequestGrade()
    r.get_grade()

4.部署到阿里云Linux服务器
我没有选Ubuntu或CentOS,因为他们自带的是Python版本是Python 2,而Alibaba Cloud Linux自带了Python 3。如果使用的是Python 2,可以下载安装Python 3,或重装系统,阿里云服务器重装系统很简便。
注意:需要提前装好pip包管理工具,并安装requests、smtplib等库

pip3 install requests

接下来就可以把我们的程序部署到服务器里啦
创建一个目录 名为request_grade

mkdir request_grade

在该路径下创建1.txt和main.py文件,使用vi编辑器填入数字和脚本

touch main.py
vi main.py

在终端定时运行这个程序
编辑定时任务

crontab -e

每分钟都运行一次

* * * * * python /home/yrl/request_grade/main.py

以上就是教务系统爬虫Python程序的源代码了。我的Python和Linux基础都较为一般,代码也有些许不足或让人不易理解,请多体谅。

感谢阿里云-高校学生在家实践活动给我提供了这个机会,给我实操使用Linux服务器的机会。

我在这个过程中也遇到了一些问题,可以给新手一些tips:
1.服务器的端口可以不要选择默认的22,不然睡一觉醒来,远程登录一下服务器就会发现有几百条甚至上千条访问失败的记录,这应该是其他人对服务器在进行扫描、攻击
2.续第一个问题,为提高安全性,建议把密码设置地更复杂一些
3.阿里云也提供了iPadOS和iOS的软件,可以直接使用SSH远程连接,非常方便;也可以使用其他SSH远程连接

希望未来能进一步深入学习,分享一些更优质的原创作品

相关实践学习
通义万相文本绘图与人像美化
本解决方案展示了如何利用自研的通义万相AIGC技术在Web服务中实现先进的图像生成。
7天玩转云服务器
云服务器ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,可降低 IT 成本,提升运维效率。本课程手把手带你了解ECS、掌握基本操作、动手实操快照管理、镜像管理等。了解产品详情: https://www.aliyun.com/product/ecs
相关文章
|
2月前
|
算法 搜索推荐 JavaScript
基于python智能推荐算法的全屋定制系统
本研究聚焦基于智能推荐算法的全屋定制平台网站设计,旨在解决消费者在个性化定制中面临的选择难题。通过整合Django、Vue、Python与MySQL等技术,构建集家装设计、材料推荐、家具搭配于一体的一站式智能服务平台,提升用户体验与行业数字化水平。
|
2月前
|
存储 分布式计算 大数据
基于Python大数据的的电商用户行为分析系统
本系统基于Django、Scrapy与Hadoop技术,构建电商用户行为分析平台。通过爬取与处理海量用户数据,实现行为追踪、偏好分析与个性化推荐,助力企业提升营销精准度与用户体验,推动电商智能化发展。
|
2月前
|
数据采集 Web App开发 数据安全/隐私保护
实战:Python爬虫如何模拟登录与维持会话状态
实战:Python爬虫如何模拟登录与维持会话状态
|
3月前
|
数据采集 Web App开发 自然语言处理
新闻热点一目了然:Python爬虫数据可视化
新闻热点一目了然:Python爬虫数据可视化
|
2月前
|
机器学习/深度学习 大数据 关系型数据库
基于python大数据的台风灾害分析及预测系统
针对台风灾害预警滞后、精度不足等问题,本研究基于Python与大数据技术,构建多源数据融合的台风预测系统。利用机器学习提升路径与强度预测准确率,结合Django框架实现动态可视化与实时预警,为防灾决策提供科学支持,显著提高应急响应效率,具有重要社会经济价值。
|
2月前
|
机器学习/深度学习 大数据 关系型数据库
基于python大数据的青少年网络使用情况分析及预测系统
本研究基于Python大数据技术,构建青少年网络行为分析系统,旨在破解现有防沉迷模式下用户画像模糊、预警滞后等难题。通过整合多平台亿级数据,运用机器学习实现精准行为预测与实时干预,推动数字治理向“数据驱动”转型,为家庭、学校及政府提供科学决策支持,助力青少年健康上网。

推荐镜像

更多