飞天加速计划·高校学生在家实践——教务系统查成绩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远程连接

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

相关实践学习
2分钟自动化部署人生模拟器
本场景将带你借助云效流水线Flow实现人生模拟器小游戏的自动化部署
7天玩转云服务器
云服务器ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,可降低 IT 成本,提升运维效率。本课程手把手带你了解ECS、掌握基本操作、动手实操快照管理、镜像管理等。了解产品详情: https://www.aliyun.com/product/ecs
相关文章
|
26天前
|
机器学习/深度学习 人工智能 算法
基于Python深度学习的眼疾识别系统实现~人工智能+卷积网络算法
眼疾识别系统,本系统使用Python作为主要开发语言,基于TensorFlow搭建卷积神经网络算法,并收集了4种常见的眼疾图像数据集(白内障、糖尿病性视网膜病变、青光眼和正常眼睛) 再使用通过搭建的算法模型对数据集进行训练得到一个识别精度较高的模型,然后保存为为本地h5格式文件。最后使用Django框架搭建了一个Web网页平台可视化操作界面,实现用户上传一张眼疾图片识别其名称。
89 4
基于Python深度学习的眼疾识别系统实现~人工智能+卷积网络算法
|
2月前
|
机器学习/深度学习 人工智能 算法
猫狗宠物识别系统Python+TensorFlow+人工智能+深度学习+卷积网络算法
宠物识别系统使用Python和TensorFlow搭建卷积神经网络,基于37种常见猫狗数据集训练高精度模型,并保存为h5格式。通过Django框架搭建Web平台,用户上传宠物图片即可识别其名称,提供便捷的宠物识别服务。
311 55
|
29天前
|
安全 前端开发 数据库
Python 语言结合 Flask 框架来实现一个基础的代购商品管理、用户下单等功能的简易系统
这是一个使用 Python 和 Flask 框架实现的简易代购系统示例,涵盖商品管理、用户注册登录、订单创建及查看等功能。通过 SQLAlchemy 进行数据库操作,支持添加商品、展示详情、库存管理等。用户可注册登录并下单,系统会检查库存并记录订单。此代码仅为参考,实际应用需进一步完善,如增强安全性、集成支付接口、优化界面等。
|
2月前
|
存储 缓存 监控
局域网屏幕监控系统中的Python数据结构与算法实现
局域网屏幕监控系统用于实时捕获和监控局域网内多台设备的屏幕内容。本文介绍了一种基于Python双端队列(Deque)实现的滑动窗口数据缓存机制,以处理连续的屏幕帧数据流。通过固定长度的窗口,高效增删数据,确保低延迟显示和存储。该算法适用于数据压缩、异常检测等场景,保证系统在高负载下稳定运行。 本文转载自:https://www.vipshare.com
127 66
|
27天前
|
存储 NoSQL 数据库连接
在Python程序中实现LevelDB的海量key的分批次扫描
通过本文的步骤,您可以在Python程序中实现对LevelDB海量key的分批次扫描。这样不仅能够有效地管理大规模数据,还可以避免一次性加载过多数据到内存中,提高程序的性能和稳定性。希望这篇指南能为您的开发工作提供实用的帮助。
63 28
|
13天前
|
数据采集 JSON 数据格式
Python爬虫:京东商品评论内容
京东商品评论接口为商家和消费者提供了重要工具。商家可分析评论优化产品,消费者则依赖评论做出购买决策。该接口通过HTTP请求获取评论内容、时间、点赞数等数据,支持分页和筛选好评、中评、差评。Python示例代码展示了如何调用接口并处理返回的JSON数据。应用场景包括产品优化、消费者决策辅助、市场竞争分析及舆情监测。
|
25天前
|
数据采集 供应链 API
Python爬虫与1688图片搜索API接口:深度解析与显著收益
在电子商务领域,数据是驱动业务决策的核心。阿里巴巴旗下的1688平台作为全球领先的B2B市场,提供了丰富的API接口,特别是图片搜索API(`item_search_img`),允许开发者通过上传图片搜索相似商品。本文介绍如何结合Python爬虫技术高效利用该接口,提升搜索效率和用户体验,助力企业实现自动化商品搜索、库存管理优化、竞品监控与定价策略调整等,显著提高运营效率和市场竞争力。
63 3
|
23天前
|
机器学习/深度学习 算法 前端开发
基于Python深度学习果蔬识别系统实现
本项目基于Python和TensorFlow,使用ResNet卷积神经网络模型,对12种常见果蔬(如土豆、苹果等)的图像数据集进行训练,构建了一个高精度的果蔬识别系统。系统通过Django框架搭建Web端可视化界面,用户可上传图片并自动识别果蔬种类。该项目旨在提高农业生产效率,广泛应用于食品安全、智能农业等领域。CNN凭借其强大的特征提取能力,在图像分类任务中表现出色,为实现高效的自动化果蔬识别提供了技术支持。
基于Python深度学习果蔬识别系统实现
|
26天前
|
Python
[oeasy]python057_如何删除print函数_dunder_builtins_系统内建模块
本文介绍了如何删除Python中的`print`函数,并探讨了系统内建模块`__builtins__`的作用。主要内容包括: 1. **回忆上次内容**:上次提到使用下划线避免命名冲突。 2. **双下划线变量**:解释了双下划线(如`__name__`、`__doc__`、`__builtins__`)是系统定义的标识符,具有特殊含义。
29 3
|
2月前
|
存储 算法 Python
文件管理系统中基于 Python 语言的二叉树查找算法探秘
在数字化时代,文件管理系统至关重要。本文探讨了二叉树查找算法在文件管理中的应用,并通过Python代码展示了其实现过程。二叉树是一种非线性数据结构,每个节点最多有两个子节点。通过文件名的字典序构建和查找二叉树,能高效地管理和检索文件。相较于顺序查找,二叉树查找每次比较可排除一半子树,极大提升了查找效率,尤其适用于海量文件管理。Python代码示例包括定义节点类、插入和查找函数,展示了如何快速定位目标文件。二叉树查找算法为文件管理系统的优化提供了有效途径。
58 5

热门文章

最新文章