写点什么

用 Puppeteer 优化项目本地开发流程:一键获取登录 Token

作者:陇锦
  • 2023-11-16
    北京
  • 本文字数:3011 字

    阅读完需:约 10 分钟

用Puppeteer优化项目本地开发流程:一键获取登录Token

最近公司有个项目是基于vue开发的,但部分老页面是前后端不分离的;比如登录页面。由于后端也没有相关登录接口,所以每次在本地启动服务后,需要到测试环境登陆;然后手动复制几个cookie粘贴到本地启动的页面中,整个过程比较繁;所以用node写个脚本去简化一下流程。

优化前的流程

  • 本地npm run serve启动服务

  • 登录测试环境https://test.xxxx.com/login

  • 打开调试,找到相关 cookie,复制

  • 打开本地启动的页面并打开调试;粘贴复制的 cookie,刷新页面

优化过程

安装 Puppeteer 和 readline

Puppeteer:


Puppeteer 是一个由 Google 开发的 Node.js 库,用于控制 headless 浏览器(无图形用户界面的浏览器)。它提供了一套高级的 API,允许开发者通过程序方式操控浏览器的行为,包括导航、表单提交、截图、生成 PDF 等功能。Puppeteer 通常用于执行自动化测试、屏幕截图、搜索引擎爬虫等任务。在本例中,我们使用 Puppeteer 模拟用户登录过程,获取登录后的 Cookies。


readline:


readline 是 Node.js 内置的模块之一,提供了一个接口来从可读流(如 process.stdin)读取数据。它通常用于从终端接收用户输入,使得我们可以以交互的方式与用户进行通信。在本例中,我们使用 readline 创建了一个接口,以便用户能够在终端中输入账号和密码。


这两个模块的结合使用使得我们可以通过 Puppeteer 控制浏览器完成登录,而 readline 则使得用户能够在终端中直接输入账号和密码。


安装并引入模块


npm i puppeteer@20.0.0npm i readline
复制代码


引入 puppeteerreadlinefs


const puppeteer = require('puppeteer')const readline = require('readline')const fs = require('fs')
复制代码

定义登录函数

我们定义一个名为 login 的异步函数,用于模拟用户登录和获取 cookies。


/*** 登录* @param {string} url 登录页面url* @param {string} usernameSelector 登录页面用户名输入框的ID* @param {string} passwordSelector 登录页面密码输入框的ID* @param {string} username 账号* @param {string} password 密码*/async function login(url, usernameSelector, passwordSelector, username, password) {// ...
}
复制代码

启动浏览器

login 函数中,使用 puppeteer.launch() 启动一个 headless 浏览器实例,然后通过page.goto打开我们传入的 url。


const browser = await puppeteer.launch({ headless: true })const page = await browser.newPage()await page.goto(url, { waitUntil: 'load' })
复制代码

输入用户名和密码

使用 page.type() 模拟输入用户名和密码,其中第一个参数为输入框的选择器。登录完成后,我们再通过page.click去点击登录按钮。


await page.type(usernameSelector, username)await page.type(passwordSelector, password)  await page.click('#_btnLogin')await page.waitForNavigation({ waitUntil: 'load' })
复制代码

获取 Cookies

使用 page.cookies() 获取页面的 cookies,并将我们需要的token提取出来。我们这里就随便以APITOKENbpmftoken 为例子;提取后我们就可以使用browser.close()关闭浏览器。


const cookies = await page.cookies()const tokens = {}for (const cookie of cookies) {    cookie.name === 'APITOKEN' && (tokens.APITOKEN = cookie.value)    cookie.name === 'bpmftoken' && (tokens.bpmftoken = cookie.value)}browser.close()
复制代码

写入 Tokens 到文件

将获取到的tokens写入JSON文件并关闭终端。


const tokenJSON = JSON.stringify(tokens, null, 2)const filePath = './src/config/tokens.json'fs.writeFile(filePath, tokenJSON, (err) => {    if (err) throw err    console.log('token已写入,请执行 npm run serve')    process.exit(1)});
复制代码

访问终端输入数据

使用 readline 模块创建一个接口,获取用户输入的账号和密码。


const rl = readline.createInterface({    input: process.stdin,    output: process.stdout})
let username = null;let password = null;const url = 'https://xxxx..com/login'; //登录页面const usernameSelector = '#_txtUid'; //用户名输入框IDconst passwordSelector = '#_txtPwd'; //密码输入框ID
rl.question('请输入账号:', (answer) => { username = answer rl.question('请输入密码:', (answer) => { password = answer rl.close() login(url, usernameSelector, passwordSelector, username, password) })});
复制代码


终端执行下面命令即可实现获取 token。


node login.js
复制代码


然后在项目中通过读取/src/config/tokens.json中的内容去手动写入token即可。


完整代码如下:


const puppeteer = require('puppeteer')const readline = require('readline')const fs = require('fs')
async function login(url, usernameSelector, passwordSelector, username, password) { const browser = await puppeteer.launch({ headless: true }) const page = await browser.newPage() try { await page.goto(url, { waitUntil: 'load' }) try { await page.type(usernameSelector, username) await page.type(passwordSelector, password)
} catch (error) { console.log(error) }
await page.click('#_btnLogin') await page.waitForNavigation({ waitUntil: 'load' }) console.log('登录成功') await page.waitForTimeout(500)
const cookies = await page.cookies() const tokens = {} for (const cookie of cookies) { cookie.name === 'APITOKEN' && (tokens.APITOKEN = cookie.value) cookie.name === 'bpmftoken' && (tokens.bpmftoken = cookie.value) }
await browser.close()

const tokenJSON = JSON.stringify(tokens, null, 2)
const filePath = './src/config/tokens.json'
fs.writeFile(filePath, tokenJSON, (err) => { if (err) throw err; console.log('token已写入, 请执行npm run serve') process.exit(1) }) } catch (error) { console.error('Error:', error) await browser.close() process.exit(1) }}

let username = null;let password = null;const url = 'https://xxxx..com/login'; //登录页面const usernameSelector = '#_txtUid'; //用户名输入框IDconst passwordSelector = '#_txtPwd'; //密码输入框ID
const rl = readline.createInterface({ input: process.stdin, output: process.stdout})
rl.question('请输入账号(默认GP00164,直接回车): ', (answer) => { username = answer || 'GP00164'; rl.question('请输入密码: (默认GP00164,直接回车)', (answer) => { password = answer || 'Xxzx2023@123' rl.close() login(url, usernameSelector, passwordSelector, username, password) })})
复制代码

总结

这样我们在本地开发过程中就不需要手动复制token,直接运行node login.js即可。


当然Puppeteer可以做很多事情,比如自动化测试、屏幕截图和生成 PDF、爬虫、性能测试、表单自动填写等等,更多 API 可以查看官网学习。


发布于: 刚刚阅读数: 3
用户头像

陇锦

关注

还未添加个人签名 2019-11-11 加入

还未添加个人简介

评论

发布
暂无评论
用Puppeteer优化项目本地开发流程:一键获取登录Token_Vue_陇锦_InfoQ写作社区