1、puppeteer 是什么?

puppeteer: Google 官方出品的 headless Chrome node
puppeteer github仓库
puppeteer API

官方介绍:

您可以在浏览器中手动执行的大多数操作都可以使用Puppeteer完成!

生成页面的屏幕截图和PDF
抓取SPA并生成预渲染内容(即“SSR”)。
自动化表单提交,UI测试,键盘输入等。
创建最新的自动化测试环境。使用最新的JavaScript和浏览器功能直接在最新版本的Chrome中运行测试。
捕获时间线跟踪 您的网站,以帮助诊断性能问题。
测试Chrome扩展程序。

2、爬取网站生成PDF

2.1 安装 puppeteer

// 安装 puppeteer
// 可能会因为网络原因安装失败,可使用淘宝镜像
// npm install -g cnpm --registry=https://registry.npm.taobao.org
npm i puppeteer
# or "yarn add puppeteer"

2.2 《React.js小书》简介

React.js小书》简介 关于作者@胡子大哈
这是⼀本关于 React.js 的⼩书。
因为⼯作中⼀直在使⽤ React.js,也⼀直以来想总结⼀下⾃⼰关于 React.js 的⼀些
知识、经验。于是把⼀些想法慢慢整理书写下来,做成⼀本开源、免费、专业、简单
的⼊⻔级别的⼩书,提供给社区。希望能够帮助到更多 React.js 刚⼊⻔朋友。
下图是《React.js 小书》部分截图:

2.3 一些可能会用到的 puppeteer API

// 新建 reactMiniBook.js, 运行 node reactMiniBook.js 生成pdf
const puppeteer = require('puppeteer');(async () => {// 启动浏览器const browser = await puppeteer.launch({// 无界面 默认为true,改成false,则可以看到浏览器操作,目前生成pdf只支持无界面的操作。// headless: false,// 开启开发者调试模式,默认false, 也就是平时F12打开的面版// devtools: true,});// 打开一个标签页const page = await browser.newPage();// 跳转到页面 http://huziketang.mangojuice.top/books/react/await page.goto('http://huziketang.com/books/react/', {waitUntil: 'networkidle2'});// path 路径, format 生成pdf页面格式await page.pdf({path: 'react.pdf', format: 'A4'});// 关闭浏览器await browser.close();
})();

知道这启动浏览器打开页面关闭浏览器主流程后,再来看几个API

const args = 1;
let wh = await page.evaluate((args) => {// args 可以这样传递给这个函数。// 类似于 setTimeout(() => {console.log(args);}, 3000, args);console.log('args', args); // 1// 这里可以运行 dom操作等js// 返回通过dom操作等获取到的数据return {width: 1920,height: document.body.clientHeight,};
}, args);
// 设置视图大小
await page.setViewport(wh);
// 等待2s
await page.waitFor(2000);
// 以iPhone X执行。
const devices = require('puppeteer/DeviceDescriptors');
const iPhone = devices['iPhone X'];
await page.emulate(iPhone);

2.4 知道了以上这些API后,就可以开始写主程序了。

简单说下:实现功能和主流程。从上面React.js小书截图来看。
1、打开浏览器,进入目录页,生成0. React 小书 目录.pdf
2、跳转到1. React.js 简介页面,获取左侧所有的导航a链接的href,标题。
3、用获取到的a链接数组进行for循环,这个循环里主要做了如下几件事:

3.1 隐藏左侧导航,便于生成pdf
3.2 给React.js简介等标题 加上序号,便于查看
3.3 设置docment.title 加上序号, 便于在页眉中使用。
3.4 隐藏 传播一下知识也是一个很好的选择 这一个模块(因为页眉页脚中设置了书的链接等信息,就隐藏这个了)
3.5 给 分页 上一节,下一节加上序号,便于查看。
3.6 最末尾声明下该pdf的说明,仅供学习交流,严禁用于商业用途。
3.7 返回宽高,用于设置视图大小
3.8 设置视图大小,创建生成pdf

4、关闭浏览器

具体代码:可以查看这里爬虫生成《React.js小书》的pdf每一小节的代码

// node 执行这个文件
// 笔者这里是:
node src/puppeteer/reactMiniBook.js

即可生成如下图:每一小节(0-46小节)的pdf

生成这些后,那么问题来了,就是查看时总不能看一小节,打开一小节来看,这样很不方便。
于是接下来就是合并这些pdf成为一个pdf文件。

3、合并成一个PDF文件 pdf-merge

起初,我是使用在线网站Smallpdf,合并PDF。合并的效果还是很不错的。这网站还是其他功能。比如wordpdf等。
后来找到社区提供的一个npm packagepdf merge 。(毕竟笔者是写程序的,所以就用代码来实现合并了)

这个pdf-merge依赖 pdftk

安装 PDFtk
Windows
下载并安装
笔者安装后,重启电脑才能使用。

Debian, Ubuntu 安装
笔者在Ubuntu系统安装后,即可使用。
apt-get install pdftk

使用例子

const PDFMerge = require('pdf-merge');const files = [`${__dirname}/1.pdf`,`${__dirname}/2.pdf`,
];// Buffer (Default)
PDFMerge(files)
.then((buffer) => {...});// Stream
PDFMerge(files, {output: 'Stream'})
.then((stream) => {...});// 笔者这里使用的是这个
// Save as new file
PDFMerge(files, {output: `${__dirname}/3.pdf`})
.then((buffer) => {...});

知道这些后,可以开始写主程序了。
简单说下主流程
1、读取到生成的所有pdf文件路径,并排序(0-46)
2、判断下输出文件夹是否存在,不存在则创建
3、合并这些小节的pdf保存到新文件 React小书(完整版)-作者:胡子大哈-时间戳.pdf

具体代码:可以查看这里爬虫生成《React.js小书》的pdf合并pdf的代码

最终合并的pdf文件在这里React小书(完整版)-作者:胡子大哈,可供下载。

本想着还可以加下书签和页码,没找到合适的生成方案,那暂时先不加了。如果读者有好的方案,欢迎与笔者交流。

小结

1、puppeteerGoogle 官方出品的 headless Chrome node 库,可以在浏览器中手动执行的大多数操作都可以使用Puppeteer完成。总之可以用来做很多有趣的事情。
2、用 puppeteer 生成每一小节的pdf,用依赖pdftkpdf-merge npm包, 合并成一个新的pdf文件。或者使用Smallpdf等网站合并。
3、《React.js小书》,推荐给大家。爬虫生成pdf,应该不会对作者@胡子大哈有什么影响。作者写书服务社区不易,尽可能多支持作者。

最后推荐几个链接,方便大家学习 puppeteer
puppeteer入门教程
Puppeteer 初探之前端自动化测试
爬虫生成ES6标准入门 pdf
大前端神器安利之 Puppeteer
puppeteer API中文文档

关于

作者:常以轩辕Rowboat若川为名混迹于江湖。前端路上 | PPT爱好者 | 所知甚少,唯善学。
个人博客
segmentfault前端视野专栏,开通了前端视野专栏,欢迎关注
掘金专栏,欢迎关注
知乎前端视野专栏,开通了前端视野专栏,欢迎关注
github,欢迎follow~

前端使用puppeteer 爬虫生成《React.js 小书》PDF并合并相关推荐

  1. React.js 小书 Lesson1-2 - 前端组件化(一):从一个简单的例子讲起

    React.js 小书 Lesson1-2 - 前端组件化(一):从一个简单的例子讲起 本文作者:胡子大哈 本文原文:http://huziketang.com/books/react/lesson2 ...

  2. React.js 小书 Lesson5 - React.js 基本环境安装

    React.js 小书 Lesson5 - React.js 基本环境安装 本文作者:胡子大哈 本文原文:http://huziketang.com/books/react/lesson5 转载请注明 ...

  3. React.js 小书 Lesson12 - state vs props

    React.js 小书 Lesson12 - state vs props 本文作者:胡子大哈 本文原文:http://huziketang.com/books/react/lesson12 转载请注 ...

  4. React.js 小书 Lesson27 - 实战分析:评论功能(六)

    React.js 小书 Lesson27 - 实战分析:评论功能(六) 本文作者:胡子大哈 本文原文:http://huziketang.com/books/react/lesson27 转载请注明出 ...

  5. React.js小书总结

    (迁移自旧博客2017 08 27) 第一阶段 react的组件相当于MVC里面的View. react.js 将帮助我们将界面分成了各个独立的小块,每一个块就是组件,这些组件之间可以组合.嵌套,就成 ...

  6. React.js 小书 Lesson14 - 实战分析:评论功能(一)

    React.js 小书 Lesson14 - 实战分析:评论功能(一) 本文作者:胡子大哈 本文原文:http://react.huziketang.com/blog/lesson14 转载请注明出处 ...

  7. React.js 小书 Lesson15 - 实战分析:评论功能(二)

    作者:胡子大哈 原文链接: http://huziketang.com/books/react/lesson15 转载请注明出处,保留原文链接和作者信息. 上一节我们构建了基本的代码框架,现在开始完善 ...

  8. React.js 小书 Lesson24 - PropTypes 和组件参数验证

    作者:胡子大哈 原文链接: http://huziketang.com/books/react/lesson24 转载请注明出处,保留原文链接和作者信息. 我们来了到了一个非常尴尬的章节,很多初学的朋 ...

  9. React.js 小书 Lesson18 - 挂载阶段的组件生命周期(一)

    React.js 小书 Lesson18 - 挂载阶段的组件生命周期(一) 本文作者:胡子大哈 本文原文:http://huziketang.com/books/react/lesson18 转载请注 ...

  10. 2022前端应该掌握的10个 JS 小技巧

    你知道 0 ?? 1等于多少吗? 大家好,我是 LBJ,今天我们聊聊2022一些值得掌握的新特性! 现在前端发展很快,各种技术和框架层出不穷.百花齐放,很多人都喊学不动啦!事实上JavaScript ...

最新文章

  1. 三星笔记本又发新品,这一次仍然惊艳
  2. hssfcolor 不建议使用_POI导出Excel经典实现
  3. 关于通过反汇编查看dll的方法【转】(
  4. MCSE2003学习之一
  5. ListView(3)
  6. 结合内存分析java归并排序_排序算法之归并排序(Mergesort)解析
  7. [SDOI2011]计算器
  8. BLS数字签名算法介绍及拓展
  9. javawebday30(验证码在客户端 用当前时间来请求下一张图片 VerifyCode代码)
  10. 数学建模MATLAB之分析法(一)
  11. 显示万年历的程序(汇编语言实现,附源代码)
  12. Python-GeoPandas地图、专题地图绘制
  13. JAVA大型OA协同办公系统源码【源码免费分享】
  14. Leetcode每日一题 面试题56 - I.数组中数字出现的次数
  15. ubuntu10.10下安装五笔86输入法
  16. gmx_MMPBSA--计算蛋白-配体自由能及能量分解
  17. 彩虹屁夸人语录 夸人好看的彩虹屁合集
  18. mysql实现两列数据或者两行数据相减
  19. 山东大学移动信息门户03
  20. 手写字体的fisher算法识别

热门文章

  1. 博达路由器常见功能教学0
  2. 微信小程序电商实战-首页(下)
  3. php怎么异步执行,php怎么实现异步
  4. C# 查询集合中某个元素里的值
  5. Go 关键字 Select
  6. thinkphp生成的验证码不显示问题解决
  7. Tp nginx.conf 配置(Linux)
  8. oracle11gr2克隆安装,克隆安装Oracle 11G HOME
  9. 练字第一方案失败,转向第二方案
  10. 解决办法:error: unknown type name ‘__int64‘