puppeteer需要 Node V6.4.0及以上版本,生成网站截图

作者:新美高梅

使用标准DOM API访问网页并提取信息

上面的 CSS 隐藏了打印按钮,并在每个div之后插入一个分页符,其中包含content类。有一篇很棒的文章总结了你可以用打印规则做什么,以及它们有什么问题,包括浏览器兼容性。

puppeteer

puppeteer 是一个通过DevTools 协议提供高级API 来控制 chrome,chromium 的 NODE库; puppeteer默认运行在 headless 模式, 也可配置后运行在全模式(non-headless).

让我们将视口更改为1920px x 1080px。在goto方法之前插入以下代码:

乍一看,这个解决方案似乎是最简单的,事实证明的确是这样,但它有其自身的局限性。如果你没有特殊需求,例如在 PDF 中选择文本或对文本进行搜索,那么这就是一种简单易用的方法。

puppeteer使用哪个版本的 chromium?

在puppeteer相关版本的package.json文件里查看.

像Cypress一样自动化UI测试

function getPDF() { return axios.get(`${API_URL}/your-pdf-endpoint`, { responseType: 'arraybuffer', headers: { 'Accept': 'application/pdf' } })

为puppeteer贡献

查看贡献指南 以了解puppeteer开发概述

您还必须已经安装了最新版本的Node.js的。

在客户端和服务器端都可以生成PDF文件。但是让后端处理它可能更有意义,因为你并不想耗尽用户浏览器可以提供的所有资源。

FAQ(常见问题)

在终端中键入以下内容,继续运行代码:

方案2:只使用 PDF 库

Example - 导航到 截图后保存为example.png.

保存如下文件为 example.js

const puppeteer = require('puppeteer');
(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto('https://example.com');
  await page.screenshot({path: 'example.png'});

  await browser.close();
})();

执行下面命令 node example.js

puppeteer 设置出时页面尺寸为 800 x 600px ,截图尺寸也是这个. 通过Page.setViewport() 设置个性化页面尺寸.

对于本教程,您需要JavaScript,ES6 +和Node.js的基础知识。

什么是Puppeteer?其文档中写道:

例子

提示: puppeteer需要 Node V6.4.0及以上版本, 但以下例子中使用了在Node V7.60及以上版本中的 async/await .

使用过其它浏览器测试框架的人对puppeteer也会熟悉. 创建Browser实列, 打开页面,然后使用puppeteer API操作页面.

在Facebook上,#login_form可以通过DevTools访问选择器。该选择器包含登录表单,因此我们使用waitForSelector方法来等待它。

让我们来看一个例子吧。

在测试环境中安装运行puppeteer时存在问题?

我们有一份针对不同操作系统的排错指南需求列表.

生成预渲染的内容-即服务器端渲染

之后,我们将 PDF 保存为变量,关闭浏览器并返回 PDF。

为什么puppeteer V.xxx 不能和Chromium V.yyy一同工作?

puppeteer作为 chromium 不可分割的一部分. 每个版本的puppeteer绑定于一个特定版本的 chromium以保证 puppeteer工作.

着并不是通过人工来约束,许多puppeteer工作确实在 chromium 仓库里.下面时典型故事:

  • puppeteer bug报告
  • 这原本是DevTools protocol的 issue, 然后在chromium里修复
  • 当bug修复后,滚动更新chromium到 puppeteer

然而,通常人们更愿意将puppeteer 和官方的Google Chrome一同使用.这种情况下需要选择特定版本的puppeteer以使chromium版本接近chrome.

使用Puppeteer创建黑客新闻PDF

要始终将登录凭据保存在环境变量中,不要硬编码!

puppeteer可以做什么

大部分在浏览器里手动执行的动作都可以通过puppeteer实现! 这里有几个列子来让你开始.

  • 生成页面截图和PDF.
  • 爬取单页面应用生成提前渲染的内容(例如 SSR).
  • 自动提交表单, UI测试, 键盘输入等.
  • 创建最新的自动化的测试环境,在最新的 chrome 里使用 js 和浏览器的最新特性来运行你的测试.
  • 捕获网站的跟踪时间线以帮助诊断性能问题.

现在,继续前进,也可以更改文件名以在像这样的方法:unsplash.png``unsplash2.png``screenshot

在选择 CSS 打印规则时,你必须在每个浏览器中测试结果,以确保它提供的布局是相同的,并且它不是100%能做到这一点。

API文档

探索API 文档和例子来学习更多.

awaitpage.pdf({path:'hn.pdf',format:'A4'})

即便如此,我仍然会展示这两种方法的解决方案。

如何使用puppeteer的提前版本?

npm i --save puppeteer@next

提示: 提前版本可能不稳定和包含bugs.

使用以下代码创建一个名为的新文件:signin.js

就这样!

Example - 在页面上下文中执行js

保存为 get-dimensions.js

const puppeteer = require('puppeteer');
(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto('https://example.com');

  const dimensions = await page.evaluate(() => {
    return {
      width: document.documentElement.clientWidth,
      height: document.documentElement.clientHeight,
      deviceScaleFactor: window.devicePixelRatio
    }
  })
})()

执行如下命令 node get-dimensions.js, 查看Page.evaluate() API 获取关于evaluate和相关方法 (如:evaluateOnNewDocument, exposeFunction)的详细信息.

注意:仅从1.7.0版发布。puppeteer-core

await page.type('#email', process.env.PDF_USER)await page.type('#password', process.env.PDF_PASSWORD)await page.click('#submit')

puppeteer的目标和职责是什么?

这个项目的目标是:

  • 提供一个精简和权威的库以突出 DevTools Protocol 的能力
  • 为类似的测试库提供实现参考. 最终其它框架可以采用puppeteer作为基础层.
  • 发展采用 无头,自动化 浏览器测试.
  • 帮助DevTools Protocol 新特性做 dogfood 测试, 捕获bug
  • 寻找浏览器自动化测试的痛点, 然后帮助解决这些差别.

我们采用chromium职责来帮助我们驱动产品做决定:

  • 快速: puppeteer在一个自动化测试页面的性能开销几乎为0.
  • 安全: puppeteer在 Chromium 操作过程中,自动使潜在的恶意页面安全.
  • 稳定: puppeteer不是脆弱的,也不会有内存泄漏
  • 简易: puppeteer 提供易用易理解和调试的高级API.

puppeteer-core旨在成为Puppeteer的轻量级版本,用于启动现有的浏览器安装或连接到远程浏览器。确保您安装的puppeteer-core版本与您打算连接的浏览器兼容。

如果你在 Alpine 镜像上安装 Puppeteer,请确保在看到页面的这一部分时再向下滚动一点。否则你可能会忽略一个事实:你无法运行最新的 Puppeteer 版本,并且你还需要用一个标记禁用 shm :

什么是导航(navigation)?

在puppeteer观点中, '导航(navigation)' 是所有改变页面URL的事物. 除了常规的导航外,在浏览器中点击网络从web服务器中获取新文档, 包含a标签导航和history API

在这个navigation定义中, puppeteer和单页面应用无缝衔接.

您可以在其官方网站上了解有关Puppeteer的更多信息。这些文档非常好,有大量的示例,并且所有文档都有据可查。

如上所述,如果你不把文件保存到磁盘,将会得到一个缓冲区。你只需要把含有适当内容类型的缓冲区发送到前端即可。

Puppeteer是用来取代Selenium/webDriver的吗?

不是, 这两个项目因为一些不同的原因都是有价值的.

  • Selenium/WebDriver 集中于自动跨浏览器; 它的价值在于提供一个在所有主要浏览器里工作的单一标准API.
  • Puppeteer 专注于Chromium;它的价值在于丰富的功能和高可靠性.
    也就是说,你可以使用puppeteer在非Chromium浏览器里运行测试. 例如使用community-driver jest-puppeteer. 虽然puppeteer不是你唯一可用的解决方案,但确实有几分比web Driver好的特点:
  • puppeteer 可以零设置,附带特定版本的chromium是其更好的工作,puppeteer开始使用非常容易,在一天结束时只在chromium上运行几个测试比不测试好.
  • puppeteer 是事件驱动架构, 移除大量潜在脆弱环节. 不需要在puppeteer脚本调用邪恶的"sleep(1000)"
  • puppeteer 默认运行在headless模式下,使得启动非常快. puppeteer V1.5.0 也暴露出浏览器上下文, 使高效的并行执行测试成为可能.
  • puppeteer 在调试时高亮: 翻转headless位 false ,设置slowMo选项, 将会看到浏览器的行为. 甚至可以打开Chrome DevTools来检查测试环境.

它也得到了积极的维护,因此Chromium支持ECMAScript的所有新功能。

除非你是一位经验丰富的 CSS 大师,在创建可打印页面方面有很多的经验,否则这可能会非常耗时。

Example - 创建PDF

文件保存为hn.js

const puppeteer = require('puppeteer');
(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto('https://news.ycombinator.com', {waitUntil: 'networkidle2'});
  await page.pdf({path: 'hn.pdf', format: 'A4}');

  await browser.close();
})();

执行如下命令 node hn.js, 查看 Page.pdf() API 寻找更多关于创建PDF的信息.

然后我们调用newPage它并转到Unsplash并对其进行截图,并将截图另存为。unsplash.png

时间: 2019-03-31阅读: 421标签: pdf

谁维护puppeteer?

Chrome DevTools团队维护这个库, 同时欢迎大家的参与!

使用Puppeteer,您可以:

它本质上是一个可以从 Node.js 运行的浏览器。如果你读过它的文档,其中首先提到的就是你可以用 Puppeteer 来生成页面的截图和PDF。优秀!这正是我们想要的。

调试技巧

  1. 关闭无头模式 - 有时观看浏览器的显示是有用的. 使浏览器运行在全模式而不是无头模式下, 使用headless: false:
const browser = await puppeteer.launch({headless: false,})
  1. 慢下来 - slowMo 选项减慢puppeteer 执行速度, 减慢指定的总毫秒数. 这是帮助观察发生什么的另一个途径.
const browser = await puppeteer.launch({
  headless: false,
  slowMo: 250 //减慢puppeteer 250ms
});
  1. 捕获控制台输出 - 监听console事件. 当调试page.evaluate() 内部代码时比较便利.
page.on('console', msg => console.log('页面log', msg.text()));
await page.evaluate(() => console.log(`url is ${location.href}`))
  1. 停止执行测试,在浏览器内使用debugger
  • 运行puppeteer时使用 {devtools: true}:
const browser = await puppeteer.launch({devtools: true});
  • 改变测试超时时间:
    • jest: jest.setTimeout(100000);
    • jasmine: jasmine.DEFAULT_TIME_INTERVAL = 100000;
    • mocha: this.timeout(100000); (改变测试时使用 function 不能使用箭头函数)
  • 在evaluate内部使用 debugger 语句, 在已存在的evaluate环境中添加 debugger
await page.evaluate(() => {
  debugger;
});

puppeteer测试将会停止在上面这条语句, chromium也将停留在 debugger 模式.

  1. 打开详细记录 - 调用所有公共API 和内部传输协议将会被puppeteer命名空间下的 debug模块记录
# 基本的详细记录
 env DEBUG="puppeteer:*" node script.js

 # 调试输出可通过命名空间来开关
 env DEBUG="puppeteer:*,-puppeteer:protocol" node script.js # 记录除了协议信息的所有信息
 env DEBUG="puppeteer:session" node script.js # 记录会话协议(protocol messages)
 env DEBUG="puppeteer:mouse,puppeteer:keyboard" node script.js # 只记录鼠标和键盘API调用

 # 传输协议记录的比较繁杂. 下面例子过滤所有网络信息.
 env DEBUG="puppeteer:*" env DEBUG_COLORS=true node script.js 2>&1 | grep -v '"Network'

结论

背景:几个月前,一个客户要求我们开发一个功能,用户可以得到 PDF 格式的 React 页面内容。该页面基本上是患者病例的报告和数据可视化结果,其中包含许多 SVG。另外还有一些特殊的请求来操纵布局,并对 HTML 元素进行一些重新排列。因此与原始的 React 页面相比,PDF 中应该有不同的样式和额外的内容。

还有更多问题,到哪里寻求帮助?

这里有许多关于puppeteer帮助的路径:

  • bugtracker
  • stackoverflowh
  • slack channel

确保在提交你的问题之前在这些频道里搜索问题.

$nodesignin

方案1:从 DOM 制作屏幕截图

开始

使用Puppeteer生成Unsplash的屏幕截图

这段代码段来自 PDFKit 文档。但是如果你的目标是直接生成一个 PDF 文件,而不是对一个已经存在的(并且不断变化的)HTML 页面进行转换,它还是很有用的。

puppeteer不支持什么特性?

你也许会发现当puppeteer控制包含audio和video的页面时一些行为不是预期的.(例如, 视频播放时截图会失败), 这有以下两个原因:

  • Puppeteer 是和chromium绑定的,并不是chrome, 所以puppeteer继承了 chromium所有限制. 这意味着puppeteer 不支持一些许可格式例如: AAC和 H.264(然而也可能强制puppeteer使用, 当 通过executablePath选项使用chrome替代chromium时. 只有在官方发布的chrome支持这些媒体格式时才能使用这些配置)
  • 自从puppeteer控制chromium/chrome的桌面版后,只在手机版本里的chrome特性不被支持. 这意味着puppeteer不支持 http Live Streaming(HLS).

首先,我们需要puppeteer包装。然后,我们launch在其上调用初始化实例的方法。此方法是异步的,因为它返回一个Promise。因此,我们await为其获取browser实例。

一旦发送了请求,缓冲区的内容就应该开始下载了。最后一步是将缓冲区数据转换为 PDF 文件。

安装

为了在你的项目里使用puppeteer, 执行:

npm i puppeteer
# 或者 yarn add puppeteer

提示: 安装puppeteer是,会下载最新版本的chromium(Mac下170 M, Windows下282M))以保证API正常工作. 要跳过这一步,请参阅环境变量().

使用Puppeteer做到这一点真的很容易。继续,在项目的根目录中创建一个文件。然后粘贴以下代码:screenshot.js

打印快乐!

运行时的默认设置

  1. 使用无头浏览器模式(headless)

puppeteer 运行chromium 在headless模式下. 当运行浏览器时设置'headless' 选项使chromium运行在全模式下.

const browser = await puppeteer.launch({headless: false});
  1. 绑定特定版本的chromium

默认情况下,puppeteer下载使用指定版本的 chromium 以保证所有的API正常工作. 创建Browser实例时指定 executablePath值来以使用不同浏览器.

const browser = await puppeteer.launch({executablePath: '/path/to/Chrome'})

查看puppeteer.launch() API了解更多信息.

阅读这篇文章了解chromium和 Chrome 的不同, 描述了Chrome和 chromium 在Linux下的不同.

  1. 创建一个新用户

puppeteer每次运行时先创建一个 chromium 用户, 运行结束后就清除用户信息.

puppeteer 2.0.0

注意:page.pdf方法接收options对象,你可以使用 'path' 选项将文件保存到磁盘。如果未提供路径,则 PDF 将不会被保存到磁盘,而是会得到缓冲区。(稍后我将讨论如何处理它。)

信任的和不信任的输入事件有什么不同?

在浏览器中输入事件被分为两大类: 信任的和不被信任的.

  • 信任事件: 通过页面的用户接口产生. 例如使用鼠标和键盘.
  • 非信任事件: 通过web API产生. 例如document.createEvent 或者 element.click() 方法.

网站能够区分这两类事件:

  • 使用 Event.isTrusted事件标志.
  • 嗅探伴随事件. 例如每一个可信任的点击事件之前都是'moussedown' 和'mouseup'事件.

为了自动化的目的, 生成可信任事件是比较重要的. 通过puppeteer生成的输入事件都是可信任事件和触发适当的伴随事件.如果需要非信任事件,需要通过page.evaluate 在页面上下文中生成模拟事件:

await page.evaluate(() => {
  document.querySelector('button[type=submit]').click();
})

networkidle2对于进行长时间轮询或任何其他附带活动的页面非常有用,并且当至少两个网络连接持续至少500毫秒时,认为导航已完成。

由于这个任务比用简单的 CSS 规则解决要复杂得多,所以我们先探讨了可能的实现方法。我们找到了 3 个主要解决方案。这篇博文将指导你了解它们的可能性并最终实施。

现在,整个文件应如下所示:screenshot.js

const puppeteer = require('puppeteer') async function printPDF() { const browser = await puppeteer.launch({ headless: true }); const page = await browser.newPage(); await page.goto('', {waitUntil: 'networkidle0'}); const pdf = await page.pdf({ format: 'A4' }); await browser.close(); return pdf})

本文由美狮美高梅官方网站发布,转载请注明来源

关键词: