#14 Automation (2)

在写爬虫程序的时候,我们需要先理解一下目标网站的结构。
做自动化时,我们也须了解手动执行时的步骤。

步骤

当我们想在选课网站上刷加选时,我们需要以下步骤:

  1. 登入选课系统
  2. 进入选课页面
  3. 至加选页面
  4. 查询你想要的课程
  5. 开始刷,希望有人退掉时你刚好看到

其中比较麻烦的是登入时有图形验证码。处理的方式之後会提到。

其实这看起来也不是什麽复杂的东西,所以很适合在这四五天内说完。

建立专案

与写爬虫一样,我们都必须先建立一个资料夹:

初始化它:

npm init -y

然後加上我们需要用到的 Packages:

npm i puppeteer

啥,我们只需要用到 puppeteer
嗯,目前是这样没错,当然之後还会需要其他东西,但现在就先这样。

你可能会发现 puppeteer 的大小有点大,这是因为它包含了一个 Chromium。

Chromium 就是这个忧郁版的 Chrome:

Chromium 是一个开源的浏览器,它长得跟 Chrome 很像,因为 Chrome 就是以 Chromium 为底再加上一些酷东西而成的。

说 Chromium 忧郁不是没有原因,因为 Chromium 相较於 Chrome 的确少掉了许多东西,如果你没搞清楚它少了什麽在用 puppeteer 时可能就会跟着它一起忧郁。其中一个差异是 Chromium 是不能播放 mp4 的,因为 mp4 的授权跟 Chromium 的开源授权不相容。

不过这次我们不会需要播放 mp4,所以可以用 Chromium,但如果你想要用 Chrome 的话也可以,用 puppeteer-core 取代 puppeteer 再上网查一下,在启动时会需要带上 Chrome 位置的参数。

好了,接下来新增 config.js 来储存一些设定:

module.exports = {
    username: "User Name",
    password: "Password",
    // 开课序号
    courses: [3056, 3057],
};

接着开始写 index.js,也就是主要的程序:

const puppeteer = require("puppeteer");

// 从 config.js 读取设定
const config = require("./config.js");

// 开发状态判断
const dev = true;

// 浏览器跟操作页面放到模组全域
let browser, page;

main();

async function main() {
    const START_T = Date.now();
    await init(); // 初始化,启动浏览器建立页面
    await login(); // 登入选课系统
    await enter(); // 进入选课页面、至加选页面
    const courses = await query(); // 查询你想要的课程的资讯
    await checker(courses); // 开始刷
    const END_T = Date.now();
    debug(`Execution Time: ${END_T - START_T}ms`);
}

function debug(...args) {
    if (dev) console.debug(...args);
}

我们的主要程序除了计算执行时间外,分别就我们在上面列出的步骤执行各项程序:

  1. 准备阶段 - init()
  2. 登入选课系统 - login()
  3. 进入选课页面 - enter()
  4. 至加选页面 - enter()
  5. 查询你想要的课程 - query()
  6. 开始刷,希望有人退掉时你刚好看到 - checker()

今天就以其中的 init() 函式作结吧:

async function init() {
    // 让 puppeteer 启动浏览器,并放置模组最上层之 browser 变数
    browser = await puppeteer.launch({
        headless: !dev,
        defaultViewport: null,
        args: ["--start-maximized", "--disable-web-security", "--disable-features=IsolateOrigins,site-per-process", "--no-sandbox"],
    });
    debug("Browser Lauched");
    
    // 新增一个分页,并放置模组最上层之 page 变数
    page = await browser.newPage();
    debug("Page Created");
}

我们用 puppeteer 提供的方法启动一个全萤幕的浏览器视窗,并带入一些给浏览器的参数。
然後再开启一个新分页。

後记

话说我现在发现好像不需要 puppeteer 就可以做出这个刷加选的东西了。
但为了让我有东西写到 30 天还是写一下 puppeteer 吧!
而且用 puppeteer 感觉比较不会被发现是程序刷的。


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

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

  1. +341 处理 API 层次感之地基篇
    • 作者: Chris
    • 系列:Vue.js 进阶心法
  2. +316 Day 1 无限手套 AWS 版:掌控一切的 5 + 1 云端必学主题
    • 作者: 用图片高效学程序
    • 系列:无限手套 AWS 版:掌控一切的 5 + 1 云端必学主题
  3. +277 Vuex 的使用偏好
    • 作者: Chris
    • 系列:Vue.js 进阶心法
  4. +260 Day 3 云端四大平台比较:AWS . GCP . Azure . Alibaba
    • 作者: 用图片高效学程序
    • 系列:无限手套 AWS 版:掌控一切的 5 + 1 云端必学主题
  5. +249 Day 2 AWS 是什麽?又为何企业这麽需要 AWS 人才?
    • 作者: 用图片高效学程序
    • 系列:无限手套 AWS 版:掌控一切的 5 + 1 云端必学主题
  6. +238 Day 4 网路宝石:AWS VPC Region/AZ vs VPC/Subnet 关系介绍
    • 作者: 用图片高效学程序
    • 系列:无限手套 AWS 版:掌控一切的 5 + 1 云端必学主题
  7. +228 Day 5 网路宝石:AWS VPC 架构 Routes & Security (上)
    • 作者: 用图片高效学程序
    • 系列:无限手套 AWS 版:掌控一切的 5 + 1 云端必学主题
  8. +215 [Day12] TS:什麽!型别还有递回(recursion)的概念?用组合技实作 SnakeToCamelCase
    • 作者: pjchender
    • 系列:React 前端工程师的两把刷子
  9. +210 Day 6 网路宝石:AWS VPC 架构 Routes & Security (下)
    • 作者: 用图片高效学程序
    • 系列:无限手套 AWS 版:掌控一切的 5 + 1 云端必学主题
  10. +202 Day 7 网路宝石:【Lab】VPC外网 Public Subnet to the Internet (IGW) (上)
    • 作者: 用图片高效学程序
    • 系列:无限手套 AWS 版:掌控一切的 5 + 1 云端必学主题

终於有些 Vue 和 React 的文章出现了
但我没用过 React 看不懂 QQ


<<:  【Day 15】反向传播(Backpropagation)

>>:  从 IT 技术面细说 Search Console 的 27 组数字 KPI (27) :SEO KPI 那个最有价值呢(上)?

TailwindCSS 从零开始 - Just In Time 模式的有趣功能

未来更新趋势 从官方文件可以看到在 JIT 模式中的 CSS 写法可以非常的多样且直觉,而未来 T...

Ruby on Rails Controller

第 1 步 - 新增 Route 别忘了,使⽤者想要看到你网站上的内容,第⼀步是要问过 Route,...

Batch Processing (4) - Materialization of Intermediate State

Beyond MapReduce 尽管 MapReduce 在 2000 年以後很夯,但它毕竟是分散...

自主学习Android_APP开发 #纪录1

纪录时间:2022/04/16 【前言】 在现在,每人基本都有属於自己的一只智慧型手机,各式各样的A...

IOT 组别

IOT https://wolkesau.medium.com/ddf91d896fd8 Maker...