chapter12-实战成绩通知短信系统(下)

2024-01-22 09:52

本文主要是介绍chapter12-实战成绩通知短信系统(下),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

注意!成绩短息通知服务的源码共分为两种:第一种为线性的程序,逻辑简单,但是格式杂乱;第二种为以类作为基础,封装了各种函数,逻辑较为复杂,但是格式清晰。建议新手先学习第一种代码风格,了解代码逻辑后,尝试自己完成第二种开发
上节课,我们成功的登录了某方的教务系统,同时已经得到了我们想要获取的成绩页面。这节课,我们将首先提取成绩页面中的有效信息,然后将相关信息保存至数据库中,最后,使用短信接口发送成绩通知。相关的代码,你仍然可以在本课程对应的Github页面获取,欢迎各位同学在讨论区进行讨论!

提取信息

首先让我们分析一下成绩页面的HTML格式:

<table class="datelist" cellspacing="0" cellpadding="3" border="0" id="Datagrid1" width="100%"><tr class="datelisthead"><td>学年</td><td>学期</td><td>课程代码</td><td>课程名称</td><td>课程性质</td><td>课程归属</td><td>学分</td><td>绩点</td><td>成绩</td><td>辅修标记</td><td>补考成绩</td><td>重修成绩</td><td>学院名称</td><td>备注</td><td>重修标记</td></tr><tr><td>2016-2017</td><td>2</td><td>1310040</td><td>ASP.NET应用开发1</td><td>专业选修课</td><td> </td><td>3.5</td><td>1.9</td><td>69</td><td>0</td><td> </td><td> </td><td>计算机与软件工程学院</td><td> </td><td>0</td></tr><tr><td>2016-2017</td><td>2</td><td>2011536</td><td>形势与政策Ⅵ</td><td>通识必修课</td><td> </td><td>0.0</td><td>3.5</td><td>良好</td><td>0</td><td> </td><td> </td><td>马克思主义学院</td><td> </td><td>0</td></tr>
</table>

从上面的HTML源码中,我们可以清晰的看到,所有的信息都存在于id为Datagrid1的表格中。因此,我们首先要提取Datagrid1表格中的所有tr

soup = BeautifulSoup(score_text.content, "lxml",from_encoding="gb18030")
trs = soup.find(id="Datagrid1").findAll("tr")

上述代码和我们之前遇到的用法不太一样,因此我们要详细说明一下上述代码中的相应参数:

soup = BeautifulSoup(score_text.content, "lxml",from_encoding="gb18030")

首先是score_text.content,在以前的开发中,我们使用的是text方式获取网页信息,这里我们使用了’content’方式的原因是,某方返回的数据是gb2312格式的内容,因此我们需要直接用二进制的方式来传递内容,同时,我们也通过from_encoding来进一步的向BeautifulSoup说明我们的原始参数。
接下来我们要解析tr中的所有数据:

Grades = []
for tr in trs:tds = tr.findAll("td")tds = tds[:2] + tds[3:5] + tds[6:9]oneGradeKeys = ["year", "term", "name", "type", "credit","gradePonit","grade"]oneGradeValues = []for td in tds:oneGradeValues.append(td.string)oneGrade = dict((key, value) for key, value in zip(oneGradeKeys, oneGradeValues))Grades.append(oneGrade)

上述代码中,我们遍历了所有tr中的td内容。需要指出的是,我们获取成绩,仅仅需要成绩所对应的年份学期,课程名,课程性质,学分,绩点,成绩。因此在获取到td中的数据库后,我们需要剔除一些无用的数据。具体的,原始数据为:

[<td>2016-2017</td>, <td>2</td>, <td>1310040</td>, <td>ASP.NET应用开发1</td>, <td>专业选修课</td>, <td> </td>, <td>3.5</td>, <td>3.7</td>, <td>87</td>, <td>0</td>, <td> </td>, <td> </td>, <td>计算机与软件工程学院</td>, <td> </td>, <td>0</td>]

整理后的数据为:

[<td>2016-2017</td>, <td>2</td>, <td>ASP.NET应用开发1</td>, <td>专业选修课</td>, <td>3.5</td>, <td>3.7</td>, <td>87</td>]

接下来,让我们打印一下我们的成果

注意:因为传递的内容编码为gb2312格式,因此我们需要定义python程序的默认格式

# coding=gbk
for score in Grades:year = score["year"]term = score["term"]gradepoint = score["gradePonit"]grade = score['grade']print(gradepoint,end='\t')print(grade,end='\t')name = score["name"]print(name)

在这里插入图片描述

Bingo!我们已经获取到了相关的成绩信息!接下来让我们将数据存入数据库中

保存数据到数据库

因为数据库的操作,我们在之前的章节中就已经学习过,因此本文直接给出对应的代码。

  1. 创建数据表
CREATE TABLE SCORE(
id INT AUTO_INCREMENT PRIMARY KEY,
year_ varchar(12),
term_ VARCHAR(12),
name_ VARCHAR(12),
type_ VARCHAR(10),
credit_ VARCHAR(10),
gradePoint_ VARCHAR(10),
grade_ VARCHAR(10)
)ENGINE=INNODB;
  1. 在Python操作数据库
import pymysql
db = pymysql.connect("localhost","root","654321","mysql" )
cursor = db.cursor()
def insert_info(year, term, name, type, credit,gradePonit,grade):sql = "INSERT INTO score(year_, term_, name_, type_, credit_,gradePoint_,grade_) VALUES('"+str(year)+"','"+str(term)+"','"+str(name)+"','"+str(type)+"','"+str(credit)+"','"+str(gradePonit)+"','"+str(grade)+"')"print(sql)cursor.execute(sql)db.commit()

####判别是否发送短信
3. 从数据库中判断
为了精确的发送短信,我们在获取到信息之后,从数据库中查询是否存在对应的课程名称,如果存在,则不发送;如果数据库中不存在该门课程的信息,则发送短息:

 int result = select_info(name)if result!=0:time.sleep(60*60)else:send_mail(year,term,name,type,credit,gradePoint,grade)
  1. 从数组中判断
    从数据库中获取信息,经过数据库连接、数据库关闭等操作,不仅浪费了时间,而且还消耗了大量的系统资源。因此,我们可以定义一个全局变量,将相关信息保存在变量中。判断新的课程是否存在变量中:
juage=[]
if name not in juage:send_mail(year, term, name, type, credit, gradePoint, grade)juage.append(name)
else:print("已经存在,不发送短信")

####发送短信
发送短息我们已经学习了很多的方法。因此本文并不指定大家选择哪个方法。课题提供的代码中,使用的是通过139信箱发送短信,大家可以使用其他的方法进行操作。
####系统说明
5. 为了保证该系统全天为我们服务,我们可以将主函数一直运行,每次运行后使用time.sleep()函数,使服务休眠1小时或者你指定的时间;
6. 因为验证码目前需要手动输入,因此建议使用Windows服务器配置环境。(后续将会提供自动识别验证码服务,大家以后可以迁移至Linux服务中)

系统测试

在运行之前,请确你已经配置好下面的参数:

  • 用户名

  • 用户密码

  • 教务网地址

  • 教务网验证码地址

  • 查询成绩地址

  • 数据库连接相关信息

  • 邮件发送的相关信息
    配置好上述参数的信息后,你的手机肯定会收到这样一条短信:
    在这里插入图片描述

    没错!你已经完成了成绩通短信通知服务!那么,为什么不参考之前文章中的知识,让它在云服务器中为你服务呢?

    总结
  1. 本文存在着大量的编码转化、数据存储操作。希望大家有问题一定要去讨论区进行讨论,我会第一时间为大家解答;
  2. 还是要提醒大家:项目需要配置的信息很多,希望同学们能够静下心来,耐心的跟着文章学习;
  3. 自动识别验证码目前的准确率已经达到了90%,我将会尽快更新相关代码。可能你看到这篇文章的时候,就不需要人工识别验证码了。

这篇关于chapter12-实战成绩通知短信系统(下)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/632627

相关文章

MySQL 多列 IN 查询之语法、性能与实战技巧(最新整理)

《MySQL多列IN查询之语法、性能与实战技巧(最新整理)》本文详解MySQL多列IN查询,对比传统OR写法,强调其简洁高效,适合批量匹配复合键,通过联合索引、分批次优化提升性能,兼容多种数据库... 目录一、基础语法:多列 IN 的两种写法1. 直接值列表2. 子查询二、对比传统 OR 的写法三、性能分析

golang程序打包成脚本部署到Linux系统方式

《golang程序打包成脚本部署到Linux系统方式》Golang程序通过本地编译(设置GOOS为linux生成无后缀二进制文件),上传至Linux服务器后赋权执行,使用nohup命令实现后台运行,完... 目录本地编译golang程序上传Golang二进制文件到linux服务器总结本地编译Golang程序

Linux系统性能检测命令详解

《Linux系统性能检测命令详解》本文介绍了Linux系统常用的监控命令(如top、vmstat、iostat、htop等)及其参数功能,涵盖进程状态、内存使用、磁盘I/O、系统负载等多维度资源监控,... 目录toppsuptimevmstatIOStatiotopslabtophtopdstatnmon

Python办公自动化实战之打造智能邮件发送工具

《Python办公自动化实战之打造智能邮件发送工具》在数字化办公场景中,邮件自动化是提升工作效率的关键技能,本文将演示如何使用Python的smtplib和email库构建一个支持图文混排,多附件,多... 目录前言一、基础配置:搭建邮件发送框架1.1 邮箱服务准备1.2 核心库导入1.3 基础发送函数二、

PowerShell中15个提升运维效率关键命令实战指南

《PowerShell中15个提升运维效率关键命令实战指南》作为网络安全专业人员的必备技能,PowerShell在系统管理、日志分析、威胁检测和自动化响应方面展现出强大能力,下面我们就来看看15个提升... 目录一、PowerShell在网络安全中的战略价值二、网络安全关键场景命令实战1. 系统安全基线核查

从原理到实战深入理解Java 断言assert

《从原理到实战深入理解Java断言assert》本文深入解析Java断言机制,涵盖语法、工作原理、启用方式及与异常的区别,推荐用于开发阶段的条件检查与状态验证,并强调生产环境应使用参数验证工具类替代... 目录深入理解 Java 断言(assert):从原理到实战引言:为什么需要断言?一、断言基础1.1 语

Java MQTT实战应用

《JavaMQTT实战应用》本文详解MQTT协议,涵盖其发布/订阅机制、低功耗高效特性、三种服务质量等级(QoS0/1/2),以及客户端、代理、主题的核心概念,最后提供Linux部署教程、Sprin... 目录一、MQTT协议二、MQTT优点三、三种服务质量等级四、客户端、代理、主题1. 客户端(Clien

在Spring Boot中集成RabbitMQ的实战记录

《在SpringBoot中集成RabbitMQ的实战记录》本文介绍SpringBoot集成RabbitMQ的步骤,涵盖配置连接、消息发送与接收,并对比两种定义Exchange与队列的方式:手动声明(... 目录前言准备工作1. 安装 RabbitMQ2. 消息发送者(Producer)配置1. 创建 Spr

深度解析Spring Boot拦截器Interceptor与过滤器Filter的区别与实战指南

《深度解析SpringBoot拦截器Interceptor与过滤器Filter的区别与实战指南》本文深度解析SpringBoot中拦截器与过滤器的区别,涵盖执行顺序、依赖关系、异常处理等核心差异,并... 目录Spring Boot拦截器(Interceptor)与过滤器(Filter)深度解析:区别、实现

深度解析Spring AOP @Aspect 原理、实战与最佳实践教程

《深度解析SpringAOP@Aspect原理、实战与最佳实践教程》文章系统讲解了SpringAOP核心概念、实现方式及原理,涵盖横切关注点分离、代理机制(JDK/CGLIB)、切入点类型、性能... 目录1. @ASPect 核心概念1.1 AOP 编程范式1.2 @Aspect 关键特性2. 完整代码实