目录

  • 一、内容介绍
  • 二、工具介绍
  • 三、JSoup处理细节
    • 1.需求分析
    • 2.模拟登录内网
    • 3.模拟登录教务系统
  • 四、界面
    • 1.登录界面
    • 2.查询主界面
      • 2.1 成绩查询
      • 2.2 考试安排
      • 2.3 GPA查询
      • 2.4 成绩总表
    • 3.个人中心界面
      • 3.1 个性签名
      • 3.2 作者博客
      • 3.3 退出登录
  • 五、附录
    • 1.登录界面处理逻辑
    • 2.JSoup模拟登录

一、内容介绍

本次大作业主要使用JSoup和鸿蒙开发来实现一个教务查询软件。软件分为两个部分:教务查询和个人中心。用户只需要知道自己的学号、教务系统密码以及内网VPN密码,无论是否使用校园网,都能登录该应用。教务查询部分全部用JSoup实现并展示在鸿蒙手机应用中,该部分包括成绩查询、考试查询、GPA查询以及成绩总表查询四个功能。个人中心部分包含用户的个人信息以及退出登录等操作。

二、工具介绍

JSoup是一款Java的HTML解析器,可直接解析某个URL地址、HTML文本内容。它提供了一套非常省力的API,可通过DOM,CSS以及类似于jQuery的操作方法来取出和操作数据。本次大作业利用JSoup来模拟登录进而爬取教务系统内的各种信息,获取到的成绩等信息将在鸿蒙手机应用上进行展示。

三、JSoup处理细节

1.需求分析

场景:需要访问教务系统,爬取出各种个人教务信息,并在自己所写的手机应用上进行展示。由于访问教务系统需要连接校园网,为了方便用户在校外也能使用本应用,所以本次爬取采用了“内网-教务系统”的两级爬取策略,即先模拟登录校园内网,然后携带内网cookies登录教务系统,最终爬取出相关信息。

2.模拟登录内网

内网登录界面如图1所示:

主要登录步骤如下:

  1. 在登录界面输入用户名以及登录密码,按下F12,并在Elements中搜索action,查找表单数据最终被提交到哪里,如图2所示:

    可以看到,输入的表单数据最终被提交到了"/users/sign_in"里。
  2. 点击登录,在Network里面找到sign_in,可以看到模拟登录需要的各种信息,如图3所示:
  3. 写代码模拟登录。

3.模拟登录教务系统

模拟登录进入到了内网界面后,点击教务系统,进入到教务系统的登录界面,利用同样的方式获取模拟登录所需的信息,登录到教务系统中。

四、界面

1.登录界面

登录界面如图4所示:

用户输入自己的学号、教务系统密码以及内网VPN密码后,点击Login按钮,即可成功登录。登录后,鸿蒙开发提供的工具包Preferences将自动保存用户的所有登录信息,信息存储在用户的SD卡中。当再次打开APP时,系统将自动登录。

2.查询主界面

查询主界面如图5所示:

在查询主界面,利用JSoup爬取到的网页信息设计了多个查询功能,下面将依次介绍。

2.1 成绩查询

点击查询主界面的“成绩查询”按钮,进入到成绩查询界面,点击学年、学期以及查询性质三个按钮,会弹出相应选项,如图6所示:

学年、学期以及课程性质都选择完毕后,点击查询按钮,结果如图7所示:

成绩信息中只包含课程名和成绩分数两项信息。点击其中任意一条成绩信息,随后会弹出该门课程更加详细的信息,如图8所示:

详细信息中包括课程性质、考试性质以及开课学院等信息。

2.2 考试安排

点击查询主界面的“考试安排”按钮,进入到考试安排查询界面,选择学年、学期选项,然后点击查询,结果如图9所示:

考试信息中只包括考试科目以及考试地点两项信息。任意点击其中一条信息,会弹出更加详细的考试信息,如图10所示:

详细信息中包括考试时间、教学班组成以及考试校区等信息。

2.3 GPA查询

点击查询主界面的“GPA”按钮,进入到GPA查询界面。选择学年、学期以及课程性质三个选项,然后点击查询,结果如图11所示:

可以看出该名学生2019-2020学年第2学期的GPA是4.37。

2.4 成绩总表

点击查询主界面的“成绩总表”按钮,进入到成绩总表查询界面,结果如图12所示:

成绩总表中包含该用户截止目前的所有学分以及课程的详细情况。

3.个人中心界面

个人中心界面显示了用户的个人信息,所有信息均通过JSoup爬取教务系统网页获得。当用户在登录界面点击登录后,获取到的用户个人信息将用于个人中心界面的初始化操作。用户登录成功后,个人中心界面如图13所示:

用户在个人中心界面可以完成查看个人信息、修改个性签名、查看作者博客、退出登录等操作。

3.1 个性签名

点击个人中心界面的“个性签名”按钮,进入到个性签名修改界面,如图14所示:

重新输入个性签名后,点击确定,即可成功修改。如果用户并未改变原有的内容,点击返回键可正常返回,否则系统会提示用户点击“确认”键来进行修改操作。修改后的个性签名如图15所示:

3.2 作者博客

点击个人中心界面的“作者博客”按钮,即可进入到开发者的CSDN博客主页,如图16所示:

3.3 退出登录

点击个人中心界面的“退出登录”按钮,会弹出一个提示窗口,如图17所示:

点击确认后,系统将清除掉用户的所有数据并跳转到登录界面(图4),重新进行登录。

五、附录

完整代码地址:代码,原创不易,请随手给个follow和star,感谢!!!

1.登录界面处理逻辑

package com.example.ncepu;import com.example.ncepu.JWUtils.ConnectJWGL;
import com.example.ncepu.Utils.PreferenceUtils;
import com.example.ncepu.Utils.TimeUtils;
import com.example.ncepu.slice.MainAbilitySlice;
import ohos.aafwk.ability.Ability;
import ohos.aafwk.content.Intent;
import ohos.aafwk.content.Operation;
import ohos.agp.colors.RgbColor;
import ohos.agp.components.Button;
import ohos.agp.components.TextField;
import ohos.agp.utils.Color;
import ohos.agp.window.dialog.ToastDialog;
import ohos.app.Context;
import ohos.data.DatabaseHelper;
import ohos.data.preferences.Preferences;import java.util.Map;public class MainAbility extends Ability {public static ConnectJWGL connectJWGL;private Button login;private TextField textId, textPwd1, textPwd2;private Preferences preferences;private DatabaseHelper databaseHelper;public static Context mcontext;@Overridepublic void onStart(Intent intent) {super.onStart(intent);super.setMainRoute(MainAbilitySlice.class.getName());super.setUIContent(ResourceTable.Layout_ability_main);mcontext = getContext();initViews();}public void initViews() {login = (Button) findComponentById(ResourceTable.Id_main_btn_login);textId = (TextField) findComponentById(ResourceTable.Id_usersid);textPwd1 = (TextField) findComponentById(ResourceTable.Id_password);textPwd2 = (TextField) findComponentById(ResourceTable.Id_password1);login.setClickedListener(component -> {if(!TimeUtils.isFastClick()) {new ToastDialog(getContext()).setText("正在处理,请不要频繁点击!").show();return;}//设置颜色login.setTextColor(new Color(Color.getIntColor("#7adfb8")));String _id= textId.getText();String password=textPwd1.getText().toString();String password1 = textPwd2.getText().toString();if(_id.equals("")) {new ToastDialog(getContext()).setText("学号不能为空").show();}else if(password.equals("")) {new ToastDialog(getContext()).setText("教务系统密码不能为空!").show();}else if(password1.equals("")) {new ToastDialog(getContext()).setText("内网密码不能为空!").show();}else {new Thread(() -> {try{login(_id, password1, password);}catch(Exception e){e.printStackTrace();}}).start();//线程启动}});}private void login(String _id, String password1, String password) {try {connectJWGL = new ConnectJWGL(_id, password1, password, MainAbility.this);//内网登录密码错误,登录失败if(connectJWGL.init() == 0) {new ToastDialog(getContext()).setText("内网密码错误!").show();
//                runOnUiThread(() -> ToastUtil.showMessage(MainActivity.this, "内网密码错误!"));}else {if(MainAbility.connectJWGL.beginLogin()) {Map<String, String> info_map = connectJWGL.getStudentInformation();PreferenceUtils.getInstance().putString("id", _id);PreferenceUtils.getInstance().putString("in_net", password1);PreferenceUtils.getInstance().putString("sign", "Hungry And Humble");PreferenceUtils.getInstance().putString("jw_password", password);PreferenceUtils.getInstance().putString("name", info_map.get("name"));PreferenceUtils.getInstance().putString("stu_id", info_map.get("id"));PreferenceUtils.getInstance().putString("class", info_map.get("class"));PreferenceUtils.getInstance().putString("major", info_map.get("major"));PreferenceUtils.getInstance().putString("sex", info_map.get("sex"));PreferenceUtils.getInstance().putString("dept", info_map.get("dept"));PreferenceUtils.getInstance().putString("year", info_map.get("year"));String cookies = connectJWGL.cookies.toString();String cookies_in = connectJWGL.cookies_innet.toString();PreferenceUtils.getInstance().putString("cookies", cookies);PreferenceUtils.getInstance().putString("cookies_in", cookies_in);
//                    preferences.flush();Intent intent = new Intent();Operation operation = new Intent.OperationBuilder().withDeviceId("").withBundleName("com.example.ncepu")//这个必须填包名.withAbilityName("com.example.ncepu.Student.StudentMainAbility")//这个必须填包名+类名.build();intent.setOperation(operation);// 通过AbilitySlice的startAbility接口实现启动另一个页面startAbility(intent);
//                    runOnUiThread(() -> ToastUtil.showMessage(MainActivity.this, "登录成功!"));}else {new ToastDialog(getContext()).setText("教务系统密码错误!").show();
//                    runOnUiThread(() -> ToastUtil.showMessage(MainActivity.this, "教务系统密码错误!"));}}} catch (Exception e) {//            runOnUiThread(() -> ToastUtil.showMessage(MainActivity.this, "内网连接超时,请检查网络是否正常连接或内网是否能正常访问!"));new ToastDialog(getContext()).setText("内网连接超时,请检查网络是否正常连接或内网是否能正常访问!").show();e.printStackTrace();}}
}

2.JSoup模拟登录

package com.example.ncepu.JWUtils;import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;import com.example.ncepu.Utils.Exam;
import ohos.app.Context;
import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import java.util.*;
import com.example.ncepu.Utils.Grade;public class ConnectJWGL {public Map<String,String> cookies_innet;Context mContext;private final String url = "***";public Map<String,String> cookies = new HashMap<>();private String modulus;private String exponent;private String csrftoken;private Connection connection;private Connection.Response response;private Document document;private String stuNum;private String jw_Password;private String in_Password;public ConnectJWGL(String stuNum, String in_Password, String jw_Password, Context mContext) throws Exception {this.stuNum = stuNum;this.in_Password = in_Password;this.jw_Password = jw_Password;this.mContext = mContext;Login_Innet login_innet = new Login_Innet(stuNum, in_Password);cookies_innet = login_innet.in_net();}//登录public boolean beginLogin() throws Exception{connection = Jsoup.connect(url+ "/jwglxt/xtgl/login_slogin.html").cookies(cookies_innet);//connection.header("Content-Type","application/x-www-form-urlencoded;charset=utf-8");connection.header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36");connection.header("Connection", "keep-alive");connection.data("csrftoken",csrftoken);
//        connection.data("language", "zh_CN");connection.data("yhm",stuNum);connection.data("mm", jw_Password);connection.data("mm", jw_Password);response = connection.cookies(cookies).ignoreContentType(true).followRedirects(true).method(Connection.Method.POST).timeout(60000).execute();
//        response = connection.execute();System.out.println("登录后的cookies为:" + response.cookies().get("JSESSIONID"));Map<String, String> subCookies = new HashMap<>();subCookies.put("JSESSIONID", response.cookies().get("JSESSIONID"));System.out.println("subCookies为:" + subCookies);cookies = subCookies;document = Jsoup.parse(response.body());
//        System.out.println("登录后的界面为:" + document);if(document.getElementById("tips") == null){System.out.println("教务系统密码正确");return true;}else{System.out.println(document.getElementById("tips").text());return false;}}
}

嵌入式系统课程设计:基于JSoup的鸿蒙教务查询软件相关推荐

  1. 嵌入式课程设计linux,嵌入式系统课程设计--基于U盘的linux操作系统的构建

    嵌入式系统课程设计--基于U盘的linux操作系统的构建 1 课程设计报告课程设计报告 课程名称课程名称 嵌入式系统课程设计嵌入式系统课程设计 设计题目设计题目基于基于 U盘的盘的 linux 操作系 ...

  2. 嵌入式系统课程设计题目

    简介:一些嵌入式系统课程设计题目,可以当做对你学习ARM的一个检测. 嵌入式系统课程设计-选题要求及课题 1.嵌入式系统课程设计时长两星期,要求学生分组进行课程设计,每组学生人数为2-3人(可在不超过 ...

  3. 【嵌入式系统课程设计——纸张计数显示装置设计】

    一.简介 本项目分享的是一个嵌入式系统的课程设计,老师给了多个题目供我们选择.我们组选择的题目是纸张计数显示装置设计,也是2019年全国大学生电子设计竞赛的F题. 有关这个题目的经验分享,网上已经出现 ...

  4. 嵌入式系统课程设计报告

    嵌入式系统课程设计报告 题目7(序号) 学生成绩查询系统(题目)              专    业:软件工程 班    级:   软件二班    姓    名:xx    学    号:     ...

  5. python设计教务管理系统_python课程设计——基于wx的GUI教务系统——2020.12.25

    一丶python-GUI教务系统 1.实践具体内容及基本要求 1.实验内容 选题1:创建一个单机版有GUI界面的(或Web版)的学生成绩系统,能从文件(或数据库)中读写数据,并具备如下功能. (1) ...

  6. 音乐播放器设置滑动杆JAVA_嵌入式系统课程设计---音乐播放器

    下一首按纽播放列表中当前MP3文件的下一首MP3文件 打开按钮选择一首MP3文件 列表按钮显示隐藏播放列表窗口 歌词按钮显示隐藏歌词显示窗口 静音按钮打开/关闭播放器的输出声音 音量控制条对播放器的音 ...

  7. 基于STM32的光敏传感器数据采集系统-嵌入式系统与设计课程设计

    目录 1 项目概述 1.1 项目介绍 1.2 项目开发环境 1.3 小组人员及分工 2 需求分析 2.1 系统需求分析 2.2 可行性分析 2.3 项目实施安排 3 系统硬件设计 3.1 系统整体硬件 ...

  8. 在linux下进行嵌入式系统设计,一种应用于测控系统的基于Linux的嵌入式系统的设计...

    描述 1.前言 随着网络控制技术的快速发展,工业以太网得到逐步完善,在工业控制领域获得越来越广泛的应用.工业以太网使用了TCP/IP协议,便于联网,并具有高速控制网络的优点.随着32位嵌入式CPU价格 ...

  9. 大学生课程设计-基于SSM的物业管理系统-智能小区物业系统代码java-社区物业水电缴费系统代码jsp

    大学生课程设计-基于SSM的物业管理系统-智能小区物业系统代码java-社区物业水电缴费系统代码jsp 注意:该项目只展示部分功能,如需了解,评论区咨询即可. 1.开发环境 开发语言:Java 后台: ...

最新文章

  1. 地理信息技术加持 用数字孪生让城市更“聪明”
  2. html 文件上传_某平台存在多处任意文件上传
  3. 函数式编程语言python-用Python进行基础的函数式编程的教程
  4. 简单java题_java
  5. python可以在excel中应用吗,python怎样在excel中应用?-Python教程
  6. Java类类getGenericSuperclass()方法及示例
  7. 从软件质量看如何写代码(1)
  8. Java 堆内存是线程共享的!面试官:你确定吗?
  9. 一个人学的软件测试,到底有多难?
  10. 数据中台对企业意义和作用有哪些
  11. js通过FormData对象 异步提交文件 实现文件上传(附带参数)
  12. 工厂选择设备问题matlab,dsp实验一 常见问题教程
  13. oracle类型number,Oracle NUMBER 类型细讲
  14. SAP 常用的库存表
  15. VMware不支持虚拟化的Intel VT-X/EPT
  16. 【案例分享】某银行用这20件事,实现数字化转型
  17. 阿里巴巴java开发规范手册
  18. 空间分析工具:GIS
  19. (一)ArcMap基础——ArcMap的窗口组成
  20. 围棋算法实现 java

热门文章

  1. [MODIS数据处理#2]常用的Arcmap内置工具(一)
  2. python求素数(质数)及其优化
  3. 老板彻底晕菜!美女是这样要求加工资
  4. 用UltraIso便捷版制作万能隐藏启动U盘
  5. FPGA图像处理HLS实现sobel边沿检测,提供HLS工程和vivado工程源码
  6. 2021中国数字经济发展白皮书 附下载
  7. [笔记分享] [Hardware] MSM8x60 User Guide study report
  8. 创建自己的盒子box_创建自己的
  9. 数学笔记23——部分分式
  10. 计算机病毒 两大传播途径,计算机病毒的传播途径