【无标题】

本文介绍了如何适配华电的教务系统以兼容小米小爱同学的课程表功能。通过使用AISchedule的旧版本插件,作者详细阐述了scheduleHtmlProvider和scheduleHtmlParser两个关键方法的实现过程,以及如何处理调试中遇到的问题,最终实现课程表数据的正确抓取和解析。
摘要由CSDN通过智能技术生成

华电课程系统适配小米小爱课程表记录

华电是真没多少名气, 本来想要用一下小爱同学的课程表教务系统导入功能, 结果只搜到俩项目, 一个是保定的一个还打不开( 估计是用的学校内网url ). 闲着也是闲着, 不如自己适配一下学校的教务系统.

本文纯属记录, 并非是为讲述代码原理( 咱也是现学现卖

整体思路

小爱同学课程表适配仅需要完善三个方法, 分别是网页抓取方法 scheduleHtmlProvider, 数据处理方法scheduleHtmlParser, 以及开课时间方法scheduleTimer, 第三个方法其实只需要按照注释填写好返回值即可.

使用工具

当前小爱课程表适配工具 AI ScheduleVer.3.2.0214 版本, 界面简洁舒适, 挺好看的就是非常难用, 所以咱是用的 0.1.4 版本编写好代码之后, 再直接扔到新版本上提交, 因此该文记录的是旧版本的代码编写过程

旧版本 AISchedule DevTools 0.1.4

新版本 AISchedule DevTools 0.3.3

两个都是浏览器插件, 下载解压后在Chrome中扩展程序中打开开发者模式, 加载已解压的扩展程序, 找到相应的解压后的文件夹导入扩展程序即可启用

插件使用过程

  1. 下载AISchdule DevTools压缩包, 解压到本地.
  2. 下载Chrome, 打开链接 chrome://extensions/ , 打开开发者模式, 导入AISchedule DevTools文件夹.

在这里插入图片描述

  1. 在Chrome打开一个新的Tab, 打开, 登陆自己的教务系统, 进入课程页面( 比如下图展示课程表) .

在这里插入图片描述

  1. 在网页内右键, 选 [检查] , 打开Chrome开发者工具, 会有新增的AISchedule标签, 进入后请跟随新手引导, 创建 [适配项目] . 注意: 学校url请填写官方url, 不要填写ip或者代理!

在这里插入图片描述

  1. 当点击provider/parser函数的代码区时, 会跳转到sources中, 在此你可以编辑scheduleHtmlProvider 方法, scheduleHtmlParser 方法, 并打断点debug.

在这里插入图片描述

  1. 可以参考注释与示例函数, 编写两个适配函数. 按ctrl+s/cmd+s保存, 然后在网页中右键, 选 [AISchedule DevTools 运行] , Console中会打印出运行结果, 两个函数的输出会分别在新窗口中显示, 以便边参考边修改函数.

在这里插入图片描述

  1. 经过调试, 如果在console中看到 [All run successfully] , 然后就可以复制到新版本插件, 创建项目, 右上角上传, 进行E2E自测 (端到端自测) .
  2. 在手机端打开课程表的教务导入功能, 搜索学校, 选择自己提交的适配, 即可亲自体验, 验证可用性. (此时版本为开发版)

    如果觉得没问题, 点击反馈按钮 [完美] (此时版本将自动变为预览版)

    然后在新版本插件中提交审核即可, 审核通过后项目将变为正式版

在这里插入图片描述

代码

scheduleHtmlProvider

此方法只要获取到课程表, 利用浏览器的元素检查可以很快定位到课程表 id

在这里插入图片描述

确定课程表 id 为 kbgrid_table_0 后在 scheduleHtmlProvider 返回即可, 代码如下

function scheduleHtmlProvider(iframeContent = "", frameContent = "", dom = document) {
    return dom.querySelector('#kbgrid_table_0').outerHTML                                
}

执行该方法后结果会弹出图中所示窗口

在这里插入图片描述

scheduleHtmlParser

该方法解析上一个方法返回的课程表获得相应的数据, 代码及注释如下

function scheduleHtmlParser(html) {
    let result = []

    let data = $("td")
    // 按照字符串 'td' 分离数据

    console.log(data)
    for(let i = 0 ; i < data.length ; i++){

        let id = data[i].attribs.id
        // 获取当前结点的 'id' 值, 在华电教务系统中, 只有课程数据才会提供 id 值, 该值为 dd-nn 格式, dd 为课程在星期几, nn 为课程在第几节
 
        if(id == undefined)
            continue
        if(data[i].children.length == 0)
            continue
        // 如果不是课程数据, 则略过; 如果没有课程数据, 则略过

        let dayData = id.split('-')[0]
        let sectionData = (Number(id.split('-')[1]) + 1 ) / 2
        // 此处解析 id 值为星期与节数

        for(let v = 0 ; v <data[i].children.length ; v++){

            let test = $(data[i].children[v]).find('span')
            // 这里是在课程数据中找到相应的数据结点, 因为 jQuery 中记录的数据较多, 观察网页源代码可以发现所有课程数据前都会有 span 属性的定义, 因此使用 'span' 去过滤数据

            let nameData = test[0].children[0].children[0].data
            let weekData
            let weeksData = []
            let positionData
            for(let u = 1 ; u < test.length ; u++){
                if(test[u].attribs.title == '节/周'){

                    weekData = test[u].next.children[0].data.replace(/\(.*?\)/g,'').replace('周','')
                    // 此处使用正则表达式去除数据中的垃圾部分, 此处是去除的括号及其内容和 '周' 这个汉字

                    let start = Number(weekData.split('-')[0])
                    let end = Number(weekData.split('-')[1])
                    for(;start <= end;start++){
                        weeksData.push(start)
                    }
                    // 此处放置上课的周数, 1-4 周就要写成整型数数组 [1, 2, 3, 4]
                }
                else if(test[u].attribs.title == '上课地点'){
                    positionData = test[u].next.children[0].data
                }
            }
            let re = {
                "name":nameData,
                "position":positionData,
                "teacher":'',
                "weeks":weeksData,
                "day":Number(dayData),
                "sections":[{"section":sectionData}]
                // 这里有个坑: 旧版 sections 是个 json 数组, 新版是个整形数数组

            }
            result.push(re)
        }
    }
    let finalResult = {"courseInfos" : result}
    console.log(finalResult)

    return finalResult
    // 此处返回 finalResult 是因为这是旧版本的规范, 新版本返回 result 即可
}

bug处理

  1. Unchecked runtime.lastError: The message port closed before a response was received.

    这个错误麻烦了我半天, 在网上查询结果都是在指责 Chrome 或者 Chrome插件, 最后发现原来是我数据返回的格式不对, 应该是数组的我用的 json , 应该是 json 的我用了数组

  2. console.log()

    这应该是我 debug 时最常用的代码, 遇到未知错误就打印一下, 不知道套几层 .children[0]. 就打印一下, 可谓是摸着打印结果写代码

参考教程链接

  1. 小爱课程表 开发者工具 使用文档-本校模式
  2. 小爱课程表开发者工具使用教程
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值