在后面的 5 篇文章打底下,咱们应该接入点接地气的业务了。

本篇开始将接触前端多语言性能。

不晓得小伙伴们有没有接触过,这一次 jsliang 将把实在的我的项目中对于多语言的解决(对,仅是解决而不是解说多语言怎么配置)脱敏后拿进去分享下。

该分享所用的数据仅为参考实在我的项目而虚构,毕竟这只是【工具库】而不是要打造反对多语言的我的项目,然而这套工具批改下还是能用到其余中央的,具备参考价值

本篇文章咱们将解说如何应用 Puppeteer 管制 Chrome/Chromium,从而达到下载文件的目标。

一 前言

Puppeteer 是一个 Node 库,它提供了一个高级 API 来通过 DevTools 协定管制 Chromium 或 Chrome。

就跟它在 GitHub 简介中介绍的一样:你在浏览器中手动执行的绝大多数操作都能够应用 Puppeteer 来实现!

  • 抓取页面快照
  • 生成页面 PDF
  • 主动操作页面 DOM
  • ……

具体例子小伙伴能够翻看本文下方参考文献的 GitHub 或者中文文档,这里不一一举例(省得被吐槽复制 README.md)

二 Puppeteer

  • 装置:npm i puppeteer

jsliang 装置的时候报错:

  • (node:7584) ExperimentalWarning: The fs.promises API is experimental

我的 Node.js 版本是 node@10.16.0,所以须要降级 Node.js。

查了下材料有 2 种办法降级,一种是下载最新版笼罩装置,另一种是通过 nvm/nvmw 形式去治理。

jsliang 网络还不错,间接下载个最新文档版吧:Node 官网

装置结束后查看下最新版本:

  • node -vv14.17.1

这时候再装置 Puppeteer,显示装置胜利,package.json 显示:"puppeteer": "^10.0.0"

装置 Puppeteer 过程中可能会有各式各样的报错,考验小伙伴们网速的时候到了

装置结束,开始搞事~

2.1 抓取快照

咱们拿抓取页面快照做个简略举例:

src/index.ts
import program from 'commander';import common from './common';import './base/console';import puppeteer from 'puppeteer';program  .version('0.0.1')  .description('工具库')program  .command('jsliang')  .description('jsliang 帮忙指令')  .action(() => {    common();  });program  .command('test')  .description('测试频道')  .action(async () => {    // 启动浏览器    const browser = await puppeteer.launch({      headless: false, // 关上实体浏览器    });    // 创立新标签页并关上    const page = await browser.newPage();    await page.goto('https://www.baidu.com/s?wd=jsliang');    // 获取快照并存储到本地    await page.screenshot({      path: './src/baidu.png',    });    // 敞开窗口    await browser.close();  });program.parse(process.argv);

执行完 npm run test 之后,src 文件夹外面会呈现图片文件 baidu.png,关上展现如下:

实测 迷信上网工具 或者 360 安全卫士会对这操作造成影响,为了避免你血压飙升,请确保这些软件的敞开

这样咱们就初步理解 Puppeteer 啦,当然它还能够导出 PDF 等,自行翻下文【参考文献】中的内容对 Puppeteer 进一步理解吧。

2.2 下载文件

既然咱们能够获取到截图,那么咱们能操作 DOM 也就难能可贵,咱们获取下线上的文件吧!

拿金山文档举例,咱们先创立一个 Excel 文件:

创立形式能够本人去玩玩,就不做解说了,金山文档地址:https://www.kdocs.cn/

而后,咱们下个环节就是须要将这个 Excel 下载下来(假如曾经请人做好翻译工作了),就是这样的 Excel:

该图片来源于网络,本次常识分享用以参考,侵权必删

而后咱们搞个简略的吧:

多语言咋样不重要,咱们目标是须要操作 Puppeteer 获取到这个 Excel 文件

OK,文件有了,咱们怎样才能下载下来呢?当初状况是:

  • 试想一下如果咱们通过 Puppeteer 关上,那是无头浏览器啊,跟无痕差不多了,如果失常登录的话,须要从新登录、进入链接,而后才是点击按钮,进行下载。

所以,这里用到金山文档的免登录链接:

众所众知免登录就是不必登陆,尽管这个解释很弱智,然而我感觉很有必要……

这里提供下面的 Demo 地址,小伙伴们能够拿来练习,然而不确保这个链接会不会哪天就被我删了,所以依照下面步骤自行设置一个吧!

  • 【金山文档 Excel 试用文件.xlsx】:https://www.kdocs.cn/l/sdwvJUKBzkK2

OK,罗里吧嗦讲了那么多前置条件,上面咱们进入正题 —— 如何获取到线下文件:

  1. 操作浏览器关上 https://www.kdocs.cn/l/sdwvJUKBzkK2
  2. 睡眠 6.66s(确保浏览器关上链接并加载页面)
  3. 而后触发【更多菜单】按钮的点击
  4. 睡眠 2s(确保更多菜单按钮点击到)
  5. 设置下载门路(确保下载地位,要不然弹窗就不好解决)
  6. 最初触发【下载】按钮的点击
  7. 睡眠 10s(确保资源下载到)
  8. 敞开窗口

下面惟一要关注的点是第 5 点,因为咱们 Windows 点击下载是会有弹窗的(并不是默认下载),所以须要提前设置好下载门路(代码中会体现)。

那么,上代码!

src/common/index.ts
import { inquirer } from '../base/inquirer';import { Result } from '../base/interface';import { sortCatalog } from './sortCatalog';import { downLoadExcel } from './downLoadExcel';const common = (): void => {  // 问题路线:看 questionList.ts  const questionList = [    // q0    {      type: 'list',      message: '请问须要什么服务?',      choices: ['公共服务', '文件治理']    },    // q1    {      type: 'list',      message: '以后公共服务有:',      choices: ['文件排序']    },    // q2    {      type: 'input',      message: '须要排序的文件夹为?(绝对路径)',    },    // q3    {      type: 'list',      message: '请问须要什么反对?',      choices: ['多语言', 'Markdown 转 Word'],    },    // q4    {      type: 'list',      message: '请问须要什么反对?',      choices: [        '下载多语言资源',        '导入多语言资源',        '导出多语言资源',      ],    },    // q5    {      type: 'input',      message: '资源下载地址(HTTP)?',      default: 'https://www.kdocs.cn/l/sdwvJUKBzkK2',    }  ];  const answerList = [    // q0    async (result: Result, questions: any) => {      if (result.answer === '公共服务') {        questions[1]();      } else if (result.answer === '文件治理') {        questions[3]();      }    },    // q1    async (result: Result, questions: any) => {      if (result.answer === '文件排序') {        questions[2]();      }    },    // q2    async (result: Result, _questions: any, prompts: any) => {      const sortResult = await sortCatalog(result.answer);      if (sortResult) {        console.log('排序胜利!');        prompts.complete();      }    },    // q3    async (result: Result, questions: any) => {      if (result.answer === '多语言') {        questions[4]();      }    },    // q4    async (result: Result, questions: any) => {      if (result.answer === '下载多语言资源') {        questions[5]();      }    },    // q5    async (result: Result, _questions: any, prompts: any) => {      if (result.answer) {        const downloadResult = await downLoadExcel(result.answer);        if (downloadResult) {          console.log('下载胜利!');          prompts.complete();        }      }    },  ];  inquirer(questionList, answerList);};export default common;

看到下面的代码我悔恨了,为啥 Inquirer.ts 被我革新的那么恶心,弄得 jsliang 还须要顺便写个文件来表明问题序列而后才捋顺问题程序:

src/common/questionList.ts
// common 板块的问题征询路线export const questionList = {  '公共服务': { // q0    '文件排序': { // q1      '须要排序的文件夹': 'Work 工作', // q2    },  },  '文件治理': { // q0    '多语言': { // q3      '下载多语言资源': { // q4        '下载地址': 'Work 工作', // q5      },      '导入多语言资源': { // q4        '导入地址': 'Work 工作',      },      '导出多语言资源': { // q4        '导出全量资源': 'Work 工作',        '导出单门资源': 'Work 工作',      }    },    'Markdown 转 Word': '暂未反对', // q3  },};

写完后转入写性能上:

src/common/downLoadExcel.ts
import puppeteer from 'puppeteer';import path from 'path';import fs from 'fs';export const downLoadExcel = async (link: string): Promise<boolean> => {  // 启动浏览器  const browser = await puppeteer.launch({    headless: false, // 关上实体浏览器    devtools: true, // 关上开发模式  });  // 1. 创立新标签页并关上  const page = await browser.newPage();  await page.goto(link);  // 2. 睡眠 6.66s - 确保页面失常关上  await page.waitForTimeout(6666);  // 3. 触发【更多菜单】按钮的点击  const moreBtn = await page.$('.header-more-btn');  moreBtn?.click();  // 4. 睡眠 1s - 确保按钮点击到  await page.waitForTimeout(2000);  // 5. 设置下载门路  const dist = path.join(__dirname, './dist');  if (!fs.existsSync(dist)) {    fs.mkdirSync(dist);  }  await (page as any)._client?.send('Page.setDownloadBehavior', {    behavior: 'allow',    downloadPath: dist,  });  // 6. 触发【下载】按钮的点击  const elements = await page.$$('.header-menu-item');  let downloadBtn;  if (elements.length) {    downloadBtn = elements[8];  }  if (!downloadBtn) {    console.error('没找到下载按钮');    await browser.close();  }  await downloadBtn?.click();  // 7. 睡眠 10s - 确保资源下载到  await page.waitForTimeout(10000);  // 8. 敞开窗口  await browser.close();  return await true;};

这样子运行之后,如果控制台不报错,那么 VS Code 展现为:

能够看到 common 目录下确实有 dist/Excel 试用文件.xlsx 了,咱们就能够接入 node-xlsx 这个库来操作 Excel 啦~

下期见!

三 参考文献

  • Github: Puppeteer
  • Puppeteer
  • puppeteer 前端利器
  • Puppeteer 之爬虫入门

jsliang 的文档库由 梁峻荣 采纳 常识共享 署名-非商业性应用-雷同形式共享 4.0 国内 许可协定 进行许可。<br/>基于 https://github.com/LiangJunrong/document-library 上的作品创作。<br/>本许可协定受权之外的应用权限能够从 https://creativecommons.org/licenses/by-nc-sa/2.5/cn/ 处取得。