JavaScript实现模拟登录

来源网站:JavaScript实现模拟登录 – WhiteNight's Site

2023年6月1日

最近在搞爬取深圳技术大学的教务系统,搞定之后做个笔记。

实际上搞定模拟登录之后后面的就很简单了,只剩下爬课表和转json要处理。

前置准备与puppeteer

A high-level API to control headless Chrome over the DevTools Protocol

官方描述上面的英文就是,这里直接说该怎么用。

首先导入需要的npm包,然后准备好账号和密码,以及登录界面的Url。这里深圳技术大学教务系统的html为例。

const puppeteer = require('puppeteer');
const fs = require('fs');

const loginUrl = 'https://auth.sztu.edu.cn/idp/authcenter/ActionAuthChain?entityId=jiaowu';
const targetUrl = 'https://jwxt.sztu.edu.cn/jsxsd/framework/xsMain.htmlx';
const username = 'xxxxxxxxxxx'; 
const password = 'xxxxxxxxxxx'; 

准备好之后,通过puppeteer包中方法实现模拟浏览器和打开页面。由于像学校教务系统这些经常需要内网,挂着vpn或者外网环境时通常无法访问。所以建议用try-catch接收异常方便后面调试。同时记得自己先尝试访问教务系统的登录界面,看看能不能打开再进行后续测试。

const puppeteer = require('puppeteer');
const fs = require('fs');

const loginUrl = 'https://auth.sztu.edu.cn/idp/authcenter/ActionAuthChain?entityId=jiaowu';
const targetUrl = 'https://jwxt.sztu.edu.cn/jsxsd/framework/xsMain.htmlx';
const username = 'xxxxxxxxxxx'; 
const password = 'xxxxxxxxxxx'; 

async function simulateLogin() {
    try {
        const browser = await puppeteer.launch();
        const page = await browser.newPage();

        await page.goto(loginUrl);

    } catch (error) {
        console.error('登录失败:', error);
    }
}

simulateLogin();

然后想想还需要些啥?模拟登录,说白了还是“登录”。

一般的登录流程:

  • 打开登录界面
  • 在指定的文本框中输入账号和密码
  • 点击登录按钮

更详细的登录流程:

  • 访问登录界面,根据html初始化页面
  • 在指定的文本框中输入账号和密码,输入完成后对当前网页的account和password赋值。
  • 点击登录按钮,触发响应事件,将account和password(password大部分都会加密,具体是DES还是md5需要去网页源码下找相关函数)传到数据库进行校验。

我们现在完成了第一步。接下来就是为当前网页的account和password赋值。

直接右键“检查”输入账号和密码的文本框,以深圳技术大学的教务系统为例

<input type="text" class="inputLogin leoPwd" name="j_username" id="j_username" value="工号" title="202x0020xxxx" onmouseover="this.title=this.value" onblur="inputOnblur(this); verCodeDisplay('/idp', 'j_username', '1', 'yzm1Bar', true)" maxlength="64">

这里“检查”的是账号的输入框,可以发现它的nameh和id为”j_username”。有name或者id就好办了,直接检索当前页面各元素,然后给它赋值即可。密码同理,直接放上代码

const puppeteer = require('puppeteer');
const fs = require('fs');

const loginUrl = 'https://auth.sztu.edu.cn/idp/authcenter/ActionAuthChain?entityId=jiaowu';
const targetUrl = 'https://jwxt.sztu.edu.cn/jsxsd/framework/xsMain.htmlx';
const username = 'xxxxxxxxxxx'; 
const password = 'xxxxxxxxxxx'; 

async function simulateLogin() {
    try {
        const browser = await puppeteer.launch();
        const page = await browser.newPage();

        await page.goto(loginUrl);
 
        await page.type('input[name="j_username"]', username);
        await page.type('input[name="j_password"]', password);

    } catch (error) {
        console.error('登录失败:', error);
    }
}

simulateLogin();

模拟登录

探讨是否需要跳转网页

现在还差最后一步–模拟点击按钮。

但真的需要去“点击”按钮吗?很明显不需要。按钮只是为了触发响应事件做的,说明你并不需要去“点击”按钮,直接触发它的响应事件即可。

但是既然用了puppeteer包,那不如直接模拟点击按钮,明显省事的多。上面只是提供一种可行的思路,因为有些事件不是通过<button>响应的,这种情况的话就得考虑直接触发响应事件了。

当然,对于我学校的教务来说,点击按钮后直接就跳转到了教务界面。然后其他所有的操作都是动态加载的,即全部都在同一个url链接上完成加载。举个例子

  • 教务界面:https://white-night.club
  • 课表界面:https://white-night.club

但是,假设你和我一样在爬自己学校的课表。但是你的课表页面和登录后的界面是分开的。例子如下

  • 教务界面:https://white-night.club
  • 课表界面:https://white-night.club/courses

那么就可以分为两种情况。如果你的情况和我一样,可以写跳转,也可以不写。虽然我个人还是建议写个跳转以防万一。

如果是第二种情况,那我强烈建议写跳转。不然又要写一堆模拟点击按钮的操作。而且有些网页的响应事件不是通过button组件触发的,这种情况下你需要检索整个网页的html去“手动”触发响应事件。很明显超级麻烦。所以不如直接跳转到课表界面。

还是以深圳技术大学的教务为例,代码如下

const puppeteer = require('puppeteer');
const fs = require('fs');

const loginUrl = 'https://auth.sztu.edu.cn/idp/authcenter/ActionAuthChain?entityId=jiaowu';
const targetUrl = 'https://jwxt.sztu.edu.cn/jsxsd/framework/xsMain.htmlx';
const username = 'xxxxxxxxxxx'; 
const password = 'xxxxxxxxxxx'; 

async function simulateLogin() {
    try {
        const browser = await puppeteer.launch();
        const page = await browser.newPage();

        await page.goto(loginUrl);
 
        await page.type('input[name="j_username"]', username);
        await page.type('input[name="j_password"]', password);

        await page.waitForNavigation();

        // 如果想写跳转,保留这一行
        await page.goto(targetUrl);

        // 由于网速不同,建议自行设置等待时间以保证页面完全加载
        await page.waitForTimeout(2000);
    } catch (error) {
        console.error('登录失败:', error);
    }
}

simulateLogin();

接下来就是获取课表的html然后继续些什么字符串分割啊,正则表达式处理啊,划分后保存到json文件里啥的操作了。

写者注

和群友讨论的时候,讨论到我们学校的课表界面有个按钮,触发后就是直接把excel形式的课表保存到本地。用这种方式获取课表是最方便的。如果不需要后续数据处理的话可以试着直接保存为excel。
不过这种方法对于需要后续数据处理的有个问题。保存的路径是浏览器的下载路径,没法自定义。即使能自定义,这意味着我后续操作需要多一步获取文件路径的方法。而自动获取路径那是超级,超级麻烦的一件事。100个用户有99个的路径不一样,有英文有中文,有自定义有默认的。
当然,可以让用户通过filepicker去手动选择文件。但这种操作你仔细想一下就会发现,后续会出现很多修改或者实现起来超级麻烦的地方(比如学校给excel的命名规则改了;用户重复导入的话要保留这次导入的,然后把上一次导入的excel文件删了;如果上次导入的文件用户打开了在后台挂着,导致这个文件变为“只读”,你无法删除它;)。
当然并不是说无法实现,只是不建议这么做。如果我是用户我肯定希望我需要手动操作的地方越少越好。
所以最后还是选择了直接把课表网页的html保存下来,对html作操作的方法。这样保存的html直接在JavaScript程序的根目录下,操作起来还是很方便的。

标签:Javascript, 爬虫

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 使用JavaScript实现模拟数组数据最简单的方法就是使用Array对象,它允许你创建一个模拟数组,并使用一些方法来操作它。例如,可以使用Array.push()方法向模拟数组中添加新的数据项,也可以使用Array.pop()方法从模拟数组中删除数据项,以及Array.shift()方法从模拟数组中移除第一个元素。此外,也可以使用Array.forEach()方法对模拟数组中的每个元素执行指定的操作。 ### 回答2: 使用JavaScript可以很方便地实现模拟数组数据。我们可以使用数组相关的方法和属性,来操作和处理这些模拟的数据。 首先,我们可以创建一个空的数组,使用如下代码进行初始化: ```javascript let mockArray = []; ``` 然后,我们可以使用push方法向数组中添加元素: ```javascript mockArray.push(1); // 添加元素1 mockArray.push(2); // 添加元素2 ``` 我们也可以使用length属性获取数组的长度,通过访问数组下标来获取特定位置的元素: ```javascript console.log(mockArray.length); // 输出数组长度,结果为2 console.log(mockArray[0]); // 输出第一个元素,结果为1 ``` 此外,我们还可以使用pop方法删除数组中的最后一个元素: ```javascript mockArray.pop(); // 删除最后一个元素 console.log(mockArray.length); // 输出数组长度,结果为1 ``` 我们可以使用forEach方法遍历数组中的每一个元素: ```javascript mockArray.forEach(function(element) { console.log(element); // 输出每一个元素 }); ``` 我们还可以使用一些其他的方法和属性,如shift、unshift、slice、splice等,来操作和处理模拟的数组数据。 总之,通过使用JavaScript提供的数组相关的方法和属性,我们可以很方便地实现模拟数组数据,实现各种对数组的操作和处理。 ### 回答3: JavaScript中数组是一种用于储存多个值的数据结构。可以通过声明一个变量并使用方括号([])表示法来创建一个数组。下面是使用JavaScript实现模拟数组数据的一种方法。 首先,我们可以声明一个变量并将其赋值为空数组。例如: ``` let myArray = []; ``` 然后,我们可以使用JavaScript的`push()`方法向数组中添加元素。例如: ``` myArray.push(1); myArray.push(2); myArray.push(3); ``` 我们也可以使用`length`属性获取数组的长度。例如: ``` console.log(myArray.length); // 输出3 ``` 要访问数组中的元素,可以使用方括号([])表示法加上索引值来引用元素。索引值从0开始。例如: ``` console.log(myArray[0]); // 输出1 console.log(myArray[1]); // 输出2 console.log(myArray[2]); // 输出3 ``` 我们还可以使用`pop()`方法从数组中删除最后一个元素。例如: ``` myArray.pop(); console.log(myArray); // 输出[1, 2] console.log(myArray.length); // 输出2 ``` 此外,我们还可以使用循环来遍历数组中的元素。例如,使用`for`循环: ``` for (let i = 0; i < myArray.length; i++) { console.log(myArray[i]); } ``` 这些是使用JavaScript实现模拟数组数据的基本方法。当然,JavaScript提供了更多的数组操作方法,例如`splice()`、`slice()`等,可以根据需要进行学习和使用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值