#16 Automation (4)

今天写第二步「进入选课页面」、第三步「至加选页面」及第四步「查询你想要的课程」。

enter

这个函式涵盖了第二步及第三步,因为不想分太多函式。

async function enter() {
    // 进入选课系统
    if (page.url().includes("IndexCtrl")) {
        await page.click("#button-1017");
        await page.waitForNavigation({ timeout: 10000 });
        if (!page.url().includes("EnrollCtrl")) throw new Error("Enter Failed");
    }

    // 等待选课子页面出现
    await page.waitForSelector("#stfseldListDo");

    // 设定自动登出时间为 6 小时
    await page.evaluate(() => {
        window.countSecond = 6 * 60 * 60;
    });

    // 取得选课子页面,点击加选按钮进入加选画面
    const child_page = await (await page.$("#stfseldListDo")).contentFrame();
    await child_page.waitForSelector("#add");
    await child_page.click("#add");
    await child_page.waitForTimeout(500);
    console.log("Entered System");
}

与登入时一样,我们用网址来判定状态并决定是否要执行。
在这里有个特别的地方:window.countSecond = 6 * 60 * 60
为什麽要这样?因为系统会自动登出,但因为太相信使用者,所以不知道为什麽这个机制做在前端而非後端用让 session 失效的方法。

接下来,因为网站是用 iframe 作系统分页的东西,所以必须用 .contentFrame() 取得 iframe 中的东西。

这也是为什麽不该用浏览器的重新整理的原因

那个 #add 就是进入加选页面最後一步的按钮啦!

query

query 会先用系统找到课程的资料,对於下一步的操作至关重要。

async function query() {
    // 取得子页面
    await page.waitForSelector("#stfseldListDo");
    const child_page = await (await page.$("#stfseldListDo")).contentFrame();
    
    const result = [];
    // 等待所有操作的元素都出现
    await Promise.all([child_page.waitForSelector("#serialNo-inputEl"), child_page.waitForSelector("#button-1059")]);
    // 遍历所有设定里写的课程代码
    for (const course of config.courses) {
        debug(`Searching ${course}`);
        // 输入代码,记得先清空,要不然第二个会叠上去
        await child_page.$eval("#serialNo-inputEl", (elm) => (elm.value = ""));
        await child_page.type("#serialNo-inputEl", course.toString().padStart(4, "0"));
        await child_page.waitForTimeout(300);
        
        // 案查询按钮
        await child_page.click("#button-1059");
        
        // 等待结果
        await child_page.waitForSelector("#gridview-1113-body > tr");
        await child_page.waitForTimeout(300);
        
        // 从列表中拿资料,因为 id 唯一,所以应该只会有一项资料
        const table = await child_page.$("#gridview-1113-body");
        const data = await table.evaluate((table) => {
            const data = [...table.children[0].children].map((elm) => elm.innerText);
            table.innerHTML = "";
            return data;
        });
        
        // 整理资料,毕竟拿到的会是一个阵列
        result.push({
            num: data[4].trim(),
            name: data[5].trim(),
            instructor: data[7].trim(),
            time: data[8].trim(),
            code: data[11].trim(),
            class: data[19].trim(),
        });
    }
    debug("Courses: ", result);
    return result;
}

其实就是完全拟人的步骤,毕竟是自动化嘛!

好混喔

明天应该会比较东西啦!
应该吧?


每日铁人赛热门 Top 10 (0929)

以 9/29 20:00 ~ 9/30 20:00 文章观看数增加值排名

  1. +284 让程序码化为 API Doc
    • 作者: Chris
    • 系列:Vue.js 进阶心法
  2. +273 终章 - 资安碎碎念与心得
    • 作者: John酱
    • 系列:网路奇妙物语 - IT&Security
  3. +224 [Day 28] 资料产品开发实务 - 非机器学习模型
    • 作者: bryanyang0528
    • 系列:资料产品开发与专案管理
  4. +205 Day 1 无限手套 AWS 版:掌控一切的 5 + 1 云端必学主题
    • 作者: 用图片高效学程序
    • 系列:无限手套 AWS 版:掌控一切的 5 + 1 云端必学主题
  5. +197 [Day30] 完结洒花❀ 看完赛心得顺便用Python画 3D 渐层花朵!
    • 作者: lulu_meat
    • 系列:奇怪的知识增加了!原来程序还可以这样用?!
  6. +179 [重构倒数第30天] - 使用 Vue3 Composition API 重构 JS 选单
    • 作者: MikeCheng
    • 系列:[ 重构倒数30天,你的网站不Vue白不Vue ]
  7. +178 [DAY-16] 找出你珍视的机会
    • 作者: flipsyde
    • 系列:带脑去上班 & No Rules Rules
  8. +151 EP 22
    • 作者: James Tsai
    • 系列:Re: 从零开始用 Xamarin 技术来复刻过去开发的一个 App : TopStore
  9. +147 Proxmox VE 安装容器:Ubuntu 20.04
    • 作者: Jason Cheng (节省哥)
    • 系列:突破困境:企业开源虚拟化管理平台
  10. +144 Day 3 云端四大平台比较:AWS . GCP . Azure . Alibaba
    • 作者: 用图片高效学程序
    • 系列:无限手套 AWS 版:掌控一切的 5 + 1 云端必学主题

有人完赛了!恭喜!!
现在也完成一半了,希望撑得下去。


<<:  Day15 对 VMA 上下其手

>>:  连续 30 天 玩玩看 ProtoPie - Day 15

[Java Day05] 1.3. 基本资料的转型

教材网址 https://coding104.blogspot.com/2021/06/java-t...

【後转前要多久】# Day01 前言 - 个人碎碎念

常听人说前端转後端, 鲜闻人讲後端转前端。 为什麽会想转前端? 好奇心使然、以及很少人做这件事情, ...

每日挑战,从Javascript面试题目了解一些你可能忽略的概念 - Day9

tags: ItIron2021 Javascript 前言 昨天我们简单讨论了恼人的强制转型问题,...

Day 8. Compare × G2 × Slate

这一篇是这一系列 Libraries 比较文实质性的最後一篇了,在下一篇稍做总结以後接着我们就要正...

同步与非同步

刚开始学习JavaScript的时候,很单纯的认为所有程序码是逐行执行的,就像看书不都是ㄧ行一行阅读...