是什么?
就是我们平时用的浏览器,完整的浏览器,只是不显示界面(如果你需要也可以设置显示),完整的渲染html,js,css.启动速度快,通常用于测试或者爬虫工具.
有哪些?
无头浏览器很多,包括但不限于:
- PhantomJS, 基于 Webkit
- SlimerJS, 基于 Gecko
- HtmlUnit, 基于 Rhnio
- TrifleJS, 基于 Trident
- Splash, 基于 Webkit
但是上边这些基本都不推荐使用,最新,最好用的应该是谷歌的无头浏览器(headless Chrome), 他基于 Chrome DevTools protocol 提供了不少高度封装的接口方便我们控制浏览器。
puppeteer
中文翻译:木偶,很形象的解释.
通过chrome的devTools 协议操作,调用谷歌浏览器,进行页面渲染或模拟人工操作.
使用nodejs语法做的api,方便快捷.因为nodejs本身就是js嘛,上手很容易.
快速上手
需要环境: nodejs v8版本以上
打开google.com,然后搜一个关键词
示例动图:
/*** 在无头浏览器自动填写表单并提交*/const puppeteer = require('puppeteer');const autoSubmitForm = async (url, path) => {// 启动浏览器const browser = await puppeteer.launch({// 关闭无头模式,方便我们看到这个无头浏览器执行的过程headless: false,});// 打开页面const page = await browser.newPage();// 设置浏览器视窗page.setViewport({width: 1376,height: 768,});// 地址栏输入网页地址await page.goto(url, {waitUntil: 'networkidle', // 等待网络状态为空闲的时候才继续执行});// await page.click('#lst-ib');await page.focus('#lst-ib');await page.type('辣子鸡', {delay: 1000, // 控制 keypress 也就是每个字母输入的间隔});await page.press('Enter');// 不关闭浏览器,看看效果// await browser.close();};module.exports = autoSubmitForm;if (require.main === module) {// for testautoSubmitForm('http://google.com');}
Puppeteer 官方文档
官方地址
- 官网 : https://pptr.dev/
- 源码:https://github.com/GoogleChrome/puppeteer
- 中文文档: https://zhaoqize.github.io/puppeteer-api-zh_CN/#?product=Puppeteer&version=v1.18.1&show=api-overview
概述
Puppeteer 是一个 Node 库,它提供了一个高级 API 来通过 DevTools 协议控制 Chromium 或 Chrome。
Puppeteer API 是分层次的,反映了浏览器结构。
注意:在下面的图表中,浅色框体内容目前不在 Puppeteer 中体现。

Puppeteer使用 DevTools 协议 与浏览器进行通信。Browser实例可以拥有浏览器上下文。BrowserContext实例定义了一个浏览会话并可拥有多个页面。Page至少有一个框架:主框架。 可能还有其他框架由 iframe 或 框架标签 创建。frame至少有一个执行上下文 - 默认的执行上下文 - 框架的 JavaScript 被执行。 一个框架可能有额外的与 扩展关联的执行上下文。Worker具有单一执行上下文,并且便于与 WebWorkers 进行交互。一些概念和名词
puppeteer vs puppeteer-core
自 v1.7.0 以来的每个版本我们都发布了两个包:
- puppeteer-core
puppeteer 是浏览器自动化的 产品。安装后,它会下载一个版本的 Chromium,然后使用puppeteer-core 驱动工作。作为最终用户产品,puppeteer 支持一堆方便的 PUPPETEER_* env 变量来调整行为。puppeteer-core 是一个 库 来帮助驱动任何支持 DevTools 协议的东西。puppeteer-core 在安装时不会下载 Chromium。作为一个库,puppeteer-core 是完全是通过其编程接口驱动的并忽略所有PUPPETEER_* env 变量。
总结一下,puppeteer-core 与 puppeteer 不同的地方:
puppeteer-core在安装时不会自动下载 Chromium。puppeteer-core忽略所有的PUPPETEER_*env 变量.
在大多数情况下,你可以使用 puppeteer 包。
然而, 如果是下面这些情况那你需要使用 puppeteer-core:
- 你正在构建 DevTools 协议顶部的另一个最终用户产品或库。例如,可以使用
puppeteer-core构建 PDF 生成器并编写下载headless_shell的自定义install.js脚本而不是 Chromium 来节省磁盘空间。 - 你正在打包 Puppeteer 用在 Chrome 扩展应用或浏览器中以使用 DevTools 协议,因为下载额外的 Chromium 二进制文件不是必须的。
当使用 puppeteer-core 时,使用下面这行代替原来的使用方式:
const puppeteer = require('puppeteer-core');
环境变量 Environment Variables
Puppeteer 寻找某些环境变量来帮助其操作。 如果 puppeteer 在环境中没有找到它们,这些变量的小写变体将从 npm 配置 中使用。
HTTP_PROXY,HTTPS_PROXY,NO_PROXY- 定义用于下载和运行 Chromium 的 HTTP 代理设置。PUPPETEER_SKIP_CHROMIUM_DOWNLOAD- 请勿在安装步骤中下载绑定的 Chromium。PUPPETEER_DOWNLOAD_HOST- 覆盖用于下载 Chromium 的 URL 的主机部分。PUPPETEER_CHROMIUM_REVISION- 在安装步骤中指定一个你喜欢 puppeteer 使用的特定版本的 Chromium。PUPPETEER_EXECUTABLE_PATH- 指定一个 Chrome 或者 Chromium 的可执行路径,会被用于puppeteer.launch。具体关于可执行路径参数的意义,可参考puppeteer.launch([options])。NOTE 在使用
puppeteer-core时,上述环境变量中以 PUPPETEER_* 开头的会被忽略.
错误处理 Error handling
如果 Puppeteer 方法无法执行一个请求,就会抛出一个错误。例如,page.waitForSelector(selector[, options]) 选择器如果在给定的时间范围内无法匹配节点,就会失败。
对于某些类型的错误,Puppeteer 使用特定的错误类处理。这些类可以通过 require('puppeteer/Errors') 获得。
支持的类列表:
一个处理超时错误的例子:
const {TimeoutError} = require('puppeteer/Errors');// ...try {await page.waitForSelector('.foo');} catch (e) {if (e instanceof TimeoutError) {// 如果超时,做一些处理。}}
测试浏览器的扩展 Working with Chrome Extensions
Puppeteer 可以用来测试 Chrome 扩展
注意 Chrome / Chromium 扩展当前只能在非无头模式下使用。
下面的代码用来处理扩展的 background page,该扩展的代码在 ./my-extension:
const puppeteer = require('puppeteer');(async () => {const pathToExtension = require('path').join(__dirname, 'my-extension');const browser = puppeteer.launch({headless: false,args: [`--disable-extensions-except=${pathToExtension}`,`--load-extension=${pathToExtension}`]});const targets = await browser.targets();const backgroundPageTarget = targets.find(target => target.type() === 'background_page');const backgroundPage = await backgroundPageTarget.page();// 像处理任何其他页面一样测试背景页面。await browser.close();})();
注意 目前还无法测试扩展弹出窗口或内容脚本。
