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

本文涉及的产品
云服务器 ECS,每月免费额度200元 3个月
云服务器ECS,u1 2核4GB 1个月
简介: 期末考试刚结束,查成绩需要登录到教务系统,比较繁琐。而成绩只有老师在系统中录入之后才能查到,我们也不知道老师什么时候录成绩,又很急着想知道每一门课的成绩。想到的解决办法就是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远程连接

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

相关实践学习
一小时快速掌握 SQL 语法
本实验带您学习SQL的基础语法,快速入门SQL。
7天玩转云服务器
云服务器ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,可降低 IT 成本,提升运维效率。本课程手把手带你了解ECS、掌握基本操作、动手实操快照管理、镜像管理等。了解产品详情: https://www.aliyun.com/product/ecs
相关文章
|
13天前
|
数据采集 存储 API
网络爬虫与数据采集:使用Python自动化获取网页数据
【4月更文挑战第12天】本文介绍了Python网络爬虫的基础知识,包括网络爬虫概念(请求网页、解析、存储数据和处理异常)和Python常用的爬虫库requests(发送HTTP请求)与BeautifulSoup(解析HTML)。通过基本流程示例展示了如何导入库、发送请求、解析网页、提取数据、存储数据及处理异常。还提到了Python爬虫的实际应用,如获取新闻数据和商品信息。
|
17天前
|
数据采集 Python
【python】爬虫-西安医学院-校长信箱
本文以西安医学院-校长信箱为基础来展示爬虫案例。来介绍python爬虫。
【python】爬虫-西安医学院-校长信箱
|
1天前
|
存储 索引 Python
Python从入门到精通——1.3.1练习编写简单程序
Python从入门到精通——1.3.1练习编写简单程序
|
1天前
|
开发框架 前端开发 数据库
Python从入门到精通:3.3.2 深入学习Python库和框架:Web开发框架的探索与实践
Python从入门到精通:3.3.2 深入学习Python库和框架:Web开发框架的探索与实践
|
3天前
|
数据采集 存储 JSON
Python爬虫面试:requests、BeautifulSoup与Scrapy详解
【4月更文挑战第19天】本文聚焦于Python爬虫面试中的核心库——requests、BeautifulSoup和Scrapy。讲解了它们的常见问题、易错点及应对策略。对于requests,强调了异常处理、代理设置和请求重试;BeautifulSoup部分提到选择器使用、动态内容处理和解析效率优化;而Scrapy则关注项目架构、数据存储和分布式爬虫。通过实例代码,帮助读者深化理解并提升面试表现。
13 0
|
5天前
|
机器学习/深度学习 搜索推荐 Python
Python特征工程面试:从理论到实践
【4月更文挑战第17天】本文探讨了Python在数据科学面试中的特征工程,涵盖基础概念如特征选择和提取,实战技能如缺失值和异常值处理,以及特定场景应用。强调避免过度依赖单一方法,忽视数据分布和相关性,以及保持特征工程的可解释性。提供代码示例展示了处理缺失值、标准化、特征选择和异常值检测的基本操作。建议结合业务理解,灵活运用多种方法并注重模型解释性。
20 9
|
6天前
|
数据采集 JavaScript 前端开发
使用Python打造爬虫程序之破茧而出:Python爬虫遭遇反爬虫机制及应对策略
【4月更文挑战第19天】本文探讨了Python爬虫应对反爬虫机制的策略。常见的反爬虫机制包括User-Agent检测、IP限制、动态加载内容、验证码验证和Cookie跟踪。应对策略包括设置合理User-Agent、使用代理IP、处理动态加载内容、验证码识别及维护Cookie。此外,还提到高级策略如降低请求频率、模拟人类行为、分布式爬虫和学习网站规则。开发者需不断学习新策略,同时遵守规则和法律法规,确保爬虫的稳定性和合法性。
|
7天前
|
SQL 安全 Go
如何在 Python 中进行 Web 应用程序的安全性管理,例如防止 SQL 注入?
在Python Web开发中,确保应用安全至关重要,主要防范SQL注入、XSS和CSRF攻击。措施包括:使用参数化查询或ORM防止SQL注入;过滤与转义用户输入抵御XSS;添加CSRF令牌抵挡CSRF;启用HTTPS保障数据传输安全;实现强身份验证和授权系统;智能处理错误信息;定期更新及审计以修复漏洞;严格输入验证;并培训开发者提升安全意识。持续关注和改进是保证安全的关键。
16 0
|
8天前
|
机器学习/深度学习 数据采集 算法
scikit-learn入门指南:从基础到实践
【4月更文挑战第17天】这篇指南介绍了scikit-learn,一个Python数据分析和机器学习的重要库。内容涵盖安装、数据加载与预处理、模型训练(如KNN分类器)、评估、调参优化及高级应用,如降维和聚类。通过实例展示了scikit-learn在分类任务中的使用,强调其在数据科学中的重要性。要深入了解,可参考官方文档和实践案例。
|
9天前
|
数据采集 NoSQL 搜索推荐
五一假期畅游指南:Python技术构建的热门景点分析系统解读
五一假期畅游指南:Python技术构建的热门景点分析系统解读