From:https://www.cnblogs.com/CyLee/p/9310839.html

puppeteer 官网:https://pptr.dev/
Puppeteer 中文文档 (与官方同步更新):https://segmentfault.com/a/1190000015913821

Puppeteer 中文文档 :https://learnku.com/docs/puppeteer/3.1.0

Puppeteer v1.5.0 中文翻译:https://blog.csdn.net/DeepLies/article/details/80861761
puppeteer api 与 教程:https://pptr.dev/#?product=Puppeteer&version=v1.6.0&show=api-class-puppeteer

github 地址 以及 doc :https://github.com/GoogleChrome/puppeteer

Puppeteer的入门教程和实践:https://juejin.im/post/59f1ef1a6fb9a045211df069
大前端神器安利之 Puppeteer:https://jeffjade.com/2017/12/17/134-kinds-of-toss-using-puppeteer/
Puppeteer初探--爬取并生成《ES6标准入门》PDF:https://segmentfault.com/a/1190000010736797

详解 Puppeteer 入门教程https://www.jb51.net/article/139808.htm

puppeteer初探:https://juejin.im/post/5b58a1a051882519790c9295

爬虫利器 Puppeteer 实战:https://www.jianshu.com/p/a9a55c03f768
puppeteer 爬虫入门教程:https://blog.csdn.net/u011350541/article/details/85469918
Puppeteer之爬虫入门:https://www.e-learn.cn/content/qita/845998
Puppeteer 实战-爬取动态生成的网页:https://blog.csdn.net/weixin_33724059/article/details/88031866
puppeteer实战之网页爬虫,模拟操作《二》:https://blog.csdn.net/mr_xiatian/article/details/79240978
puppeteer破解滑动验证码方法:http://www.php.cn/js-tutorial-387019.html
Node:使用Puppeteer完成一次复杂的爬虫:https://www.jianshu.com/p/97eeffa3bf3a

puppeteer的简单使用_爬取页面信息:https://segmentfault.com/a/1190000013037078
puppeteer进阶版_爬取小说站:https://segmentfault.com/a/1190000013055389

API 文档

完整 API 文档 和 例子.

Puppeteer 出现的背景

Chrome59 (linux、macos)、 Chrome60(windows)之后,Chrome自带headless(无界面)模式很方便做自动化测试或者爬虫。但是如何和 headless 模式的 Chrome 交互则是一个问题。通过启动 Chrome 时的命令行参数仅能实现简易的启动时初始化操作。Selenium、Webdriver 等是一种解决方案,但是往往依赖众多,不够扁平。

Puppeteer 是谷歌官方出品的一个通过 DevTools 协议 控制 headless Chrome 的 Node 库。可以通过 Puppeteer 的提供的 api 直接控制 Chrome 模拟大部分用户操作来进行 UI Test 或者 作为 爬虫 访问页面 来 收集数据

Puppeteer(中文翻译”木偶”) 是 Google Chrome 团队官方的无界面(Headless)Chrome 工具,它是一个 Node 库,提供了一个高级的 API 来控制 DevTools协议上的无头版 Chrome 。也可以配置为使用完整(非无头)的 Chrome。Chrome 素来在浏览器界稳执牛耳,因此,Chrome Headless 必将成为 web 应用自动化测试的行业标杆。使用 Puppeteer,相当于同时具有 Linux 和 Chrome 双端的操作能力,应用场景可谓非常之多。此仓库的建立,即是尝试各种折腾使用 GoogleChrome Puppeteer;以期在好玩的同时,学到更多有意思的操作。

Puppeteer 是什么,以及能做些什么

Puppeteer is a Node library which provides a high-level API to control headless Chrome or Chromium over the DevTools Protocol. It can also be configured to use full (non-headless) Chrome or Chromium.

简而言之,这货是一个提供高级API的node库,能够通过devtool控制headless模式的chrome或者chromium,它可以在headless模式下模拟任何的人为操作。

你可以在浏览器中手动完成的大部分事情都可以使用 Puppeteer 完成!你可以从以下几个示例开始:

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

总之:chrome 浏览器能干的事情 puppeteer 都能干。puppeteer 通俗来说就是一个 headless chrome浏览器 (当然你也可以配置成有UI的,默认是没有的)。既然是浏览器,那么我们手工可以在浏览器上做的事情 Puppeteer 都能胜任, 另外,Puppeteer 翻译成中文是”木偶”意思,所以听名字就知道,操纵起来很方便,你可以很方便的操纵她去实现:
1) 生成网页截图或者 PDF 
2) 高级爬虫,可以爬取大量异步渲染内容的网页 
3) 模拟键盘输入、表单自动提交、登录网页等,实现 UI 自动化测试 
4) 捕获站点的时间线,以便追踪你的网站,帮助分析网站性能问题如果你用过 PhantomJS 的话,你会发现她们有点类似,但Puppeteer是Chrome官方团队进行维护的,用俗话说就是”有娘家的人“,前景更好。

备注: 鉴于 Puppeteer 需要 Chromium,但,即便处于 Science 上网的姿态, 也会遇到 Chromium 无法成功下载的问题;所以在最新的修改中,已经其替换为 puppeteer-core (默认情况下不下载 Chromium,使用时需要确保您安装的 puppeteer-core 版本与您要连接的浏览器兼容)。在实际使用时候,即便已然按照说明操作,但依旧会报如下错误:

Error: Chromium revision is not downloaded. Run “npm install” or “yarn install”

因此只好采取手动下载 Chromium 的方式解决;因此在运行此仓库时候,您需要在 Puppeteer API Tip-Of-Tree 根据指定 Puppeteer 下载对应 Chromium,然后放置到项根目录即可(项目中已对各不同系统做了适配,国内用户可以在 Taobao Mirrors 根据系统按需下载)

Puppeteer 架构图

架构图:

  • Puppeteer 通过 devTools 与 browser 通信
  • Browser 一个可以拥有多个页面的浏览器(chroium)实例
  • Page 至少含有一个 Frame 的页面
  • Frame 至少还有一个用于执行 javascript 的执行环境,也可以拓展多个执行环境

环境和安装

Puppetee r本身依赖 6.4 以上的Node,但是为了异步超级好用的 async/await,推荐使用7.6版本以上的Node。另外headless Chrome本身对服务器依赖的库的版本要求比较高,centos服务器依赖偏稳定,v6很难使用headless Chrome,提升依赖版本可能出现各种服务器问题(包括且不限于无法使用ssh),最好使用高版本服务器。

要在项目中使用 Puppeteer,只需要运行如下命令安装即可;不过要注意的是:Puppeteer 至少需要 Node v6.4.0,如要使用 async / await,只有 Node v7.6.0 或更高版本才支持;另外,安装 Puppeteer 时,它会下载最新版本的 Chromium(〜71Mb Mac,〜90Mb Linux,〜110Mb Win),保证与 API 协同工作。

Puppeteer 因为是一个 npm 的包,所以安装很简单:npm i puppeteer    或者    yarn add puppeteer

Puppeteer 安装时自带一个最新版本的Chromium,可以通过设置环境变量或者 npm config 中的PUPPETEER_SKIP_CHROMIUM_DOWNLOAD 跳过下载。如果不下载的话,启动时可以通过 puppeteer.launch([options]) 配置项中的 executablePath 指定 Chromium 的位置。

Puppeteer 轻松入门

运行环境查看 Puppeteer 的官方 API 你会发现满屏的 async, await 之类,这些都是 ES7 的规范,所以你需要: Nodejs 的版本不能低于 v7.6.0, 需要支持 async, await.
需要最新的 chrome driver,

基本用法先开看看官方的入门的 DEMO

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

上面这段代码就实现了网页截图,先大概解读一下上面几行代码:

  • 1. 先通过 puppeteer.launch() 创建一个浏览器实例 Browser 对象
  • 2. 然后通过 Browser 对象创建页面 Page 对象
  • 3. 然后 page.goto() 跳转到指定的页面
  • 4. 调用 page.screenshot() 对页面进行截图

下面就介绍一下 puppeteer 的常用的几个 API。

示例 1

Puppeteer 类似其他框架,通过操作 Browser 实例 来操作浏览器作出相应的反应。

const puppeteer = require('puppeteer');(async () => {const browser = await puppeteer.launch();const page = await browser.newPage();await page.goto('http://rennaiqian.com');await page.screenshot({path: 'example.png'});await page.pdf({path: 'example.pdf', format: 'A4'});await browser.close();
})();

上述代码通过puppeteer的launch方法生成了一个browser的实例,对应于浏览器,launch方法可以传入配置项,比较有用的是在本地调试时传入{headless:false}可以关闭headless模式。

const browser = await puppeteer.launch({headless:false})

browser.newPage方法可以打开一个新选项卡并返回选项卡的实例page,通过page上的各种方法可以对页面进行常用操作。上述代码就进行了截屏和打印pdf的操作。

一个很强大的方法是 page.evaluate(pageFunction, ...args),可以向页面注入我们的函数,这样就有了无限可能。

const puppeteer = require('puppeteer');(async () => {const browser = await puppeteer.launch();const page = await browser.newPage();await page.goto('http://rennaiqian.com');// Get the "viewport" of the page, as reported by the page.const dimensions = await page.evaluate(() => {return {width: document.documentElement.clientWidth,height: document.documentElement.clientHeight,deviceScaleFactor: window.devicePixelRatio};});console.log('Dimensions:', dimensions);await browser.close();
})();

需要注意的是evaluate方法中是无法直接使用外部的变量的,需要作为参数传入,想要获得执行的结果也需要return出来。因为是一个开源一个多月的项目,现在项目很活跃,所以使用时自行查找api才能保证参数、使用方法不会错。

示例 2

对于如何使用 Puppeteer,这非常之容易;如下简易的示例,即实现了:导航到 https://example.com 并将截屏保存为 example.png;

const puppeteer = require('puppeteer');(async () => {const browser = await puppeteer.launch();  // 创建浏览器实例const page = await browser.newPage();      // 创建新的浏览器页面await page.goto('https://example.com');    //  页面访问地址 http://example.comawait page.screenshot({ path: 'example.png' }); // 页面截图 example.pngawait browser.close(); // 关闭浏览器
})();

Puppeteer 设置浏览器页面为 800像素 x 600像素, 屏幕截图也依据这个大小. 如你需要调整页面大小,可以通过 Page.setViewport().

更多示例可参考 GoogleChrome Puppeteer Usage;在略为熟悉 Puppeteer的 Api 之后,即可用来她操纵浏览器,来为你做些你想搞的事儿;不过值得一提的是,她现在还处于开发阶段,随着版本的更替,Api 接口也有可能会跟着略有变动。Toss Puppeteer,这是在 Github 创建的一个仓库,以承载尝试使用 GoogleChrome Puppeteer 做的各种的折腾,具体如下:

示例 3

举例 - 创建PDF.

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();
})();

上例中waitUntil表示等待的时长,参数定义在这里waitUntil - 搜索waitUntil
Page.pdf() 访问这里有更多关于创建PDF的信息.

示例 4

举例 - 通过页面上下文 (context) 获取页面信息

const puppeteer = require('puppeteer');(async () => {const browser = await puppeteer.launch();const page = await browser.newPage();await page.goto('https://example.com');// Get the "viewport" of the page, as reported by the page.const dimensions = await page.evaluate(() => { // 通过evaluate执行页面jsreturn {width: document.documentElement.clientWidth, // 页面宽度height: document.documentElement.clientHeight, // 页面高度deviceScaleFactor: window.devicePixelRatio // 设备像素比};});console.log('Dimensions:', dimensions);await browser.close();
})();

访问 Page.evaluate() 获得更多关于 evaluate 和相关功能例如 evaluateOnNewDocumentand exposeFunction的介绍。

调试技巧

  1. 显示界面 - 最直观的调试方法就是看到界面上发生了什么. 通过创建完整浏览器来实现,选项 headless: false:

    const browser = await puppeteer.launch({headless: false});
    
  2. 让执行慢下来 - slowMo 选项 可以指定毫秒值,让 Puppeteer 的执行慢下来 ,也对调试有帮助

    const browser = await puppeteer.launch({headless: false,slowMo: 250 // slow down by 250ms
    });
    
  3. 获取Console的输出 - 你既可以监听 console 事件, 也可以通过 page.evaluate()来打印。

    page.on('console', msg => console.log('PAGE LOG:', ...msg.args));await page.evaluate(() => console.log(`url is ${location.href}`));
    
  4. 启用详细日志 - 所有API调用和内部协议交互都会被记录在 puppeteer 名字空间的 debug 模式下.

    # 所有详细的日志
    env DEBUG="puppeteer:*" node script.js# 通过名字空间来控制调试日志的输出
    env DEBUG="puppeteer:*,-puppeteer:protocol" node script.js # 除了protocol外的所有消息
    env DEBUG="puppeteer:session" node script.js # 只需要protocol session 消息
    env DEBUG="puppeteer:mouse,puppeteer:keyboard" node script.js # 只输出鼠标和键盘日志# Protocol 的交互消息会很多. 这里的例子说明了如何过滤掉所有Netwok的消息。
    env DEBUG="puppeteer:*" env DEBUG_COLORS=true node script.js 2>&1 | grep -v '"Network'
    

自定义运行的 Chromium

默认情况下, Puppeteer 会选择自行选择下载 Chromium 来确保其API 在当前环境下正常运行. 如果确认需要运行不同版本的 Chromium, 在创建浏览器的时候传入executablePath参数,值为目标浏览器的可执行路径:

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

额外的例子

这些例子从 Issue 页面归纳而来,如果有额外的需要请留言。

  1. 如何模拟页面点击?

    通过以下page的接口, 相关 issue

    page.mouseMoved(x, y, options = {})
    page.mousePressed(x, y, options = {})
    page.mouseReleased(x, y, options = {})
    page.tap(x, y, options = {})
    page.touchmove()
    page.touchend()
    
  2. 如何上下翻动页面?

    通过调用page.evaluate中的 window.scrollBy来实现, 相关 issue

    page.evaluate(_ => { window.scrollBy(0, window.innerHeight);
    
  3. 避免页面ssl认证错误信息
    通过puppeteer option ignoredHTTPErrors 实现

  4. page.evalute 能否返回page DOM?
    你可以传入 ObjectHandle到page.evaluate中成为DOM元素,但当DOM被返回的时候则成 为对应的 ObjectHandle. issue
    如果需要返回,也可以返回实际需要的值,例如:

    const list = await page.evaluateHandle(() => {
    return Array.from(document.getElementsByTagName('a')).map(a => a.href);
    });
    console.log(await list.jsonValue());
    

    相关 iusse

  5. 如何读取和设置cookies?
    通过page.setCookie 和 page.cookies 接口。 目前有一些关于该功能的使用问题, 相关 issue

  6. 如何上传文件?
    通过elementHandle.uploadFile(...filePaths) 接口。 目前只支持 input type="file" 类
    型的文件提交。 相关issue

  7. 如何获得页面html代码?
    通过 page.content()

  8. 如何关闭javascript弹框
    通过 dialog.accept, 相关 issue

        page.on('dialog', dialog => {dialog.accept('test');});
    
  9. 如何监控页面的网络请求?

    const page = await browser.newPage();
    await page.setRequestInterceptionEnabled(true);page.on('request', request => {request.continue(); // pass it through.
    });page.on('response', response => {const req = response.request();console.log(req.method, response.status, req.url);
    });
    
  10. 如何输入内容?
    方法1 page.type

    // ...
    await page.focus('#lst-ib')
    page.type('China')
    // ...
    

    方法2 page.evaluate 后 element.value =

    await page.evaluate((a, b) => {document.querySelector('#a').value = a;document.querySelector('#b').value = b;document.querySelector('#c').click();}, a, b);
    
  11. 如何在页面中不同的Frame中切换
    通过page.frames()获得frame的数组,使用 iframe.$ 来获得对应frame中的handle
    例如:

    const browser = await puppeteer.launch({headless: false});
    const page = await browser.newPage();
    await page.setContent('<iframe></iframe>');// the page.frames()[0] is always a main frame.
    const iframe = page.frames()[1];
    // fetch the body element of the iframe
    const body = await iframe.$('body');
    // ...
    // do something with `body`..
    // ...
    browser.close();
    
  12. 获取element中的自定义属性值
    通过page.evaluate 然后使用object.getAttribute

await page.evaluate( (obj) => {return obj.getAttribute('data-src');
}, imgurlEle);

爬虫实践

很多网页通过user-agent来判断设备,可以通过page.emulate(options)来进行模拟。options有两个配置项,一个为userAgent,另一个为viewport可以设置宽度(width)、高度(height)、屏幕缩放(deviceScaleFactor)、是否是移动端(isMobile)、有无touch事件(hasTouch)。

const puppeteer = require('puppeteer');
const devices = require('puppeteer/DeviceDescriptors');
const iPhone = devices['iPhone 6'];puppeteer.launch().then(async browser => {const page = await browser.newPage();await page.emulate(iPhone);await page.goto('https://www.example.com');// other actions...await browser.close();
});

上述代码则模拟了iPhone6访问某网站,其中devices是puppeteer内置的一些常见设备的模拟参数。

很多网页需要登录,有两种解决方案:

  1. 让puppeteer去输入账号密码
    常用方法:点击可以使用page.click(selector[, options])方法,也可以选择聚焦page.focus(selector)。
    输入可以使用page.type(selector, text[, options])输入指定的字符串,还可以在options中设置delay缓慢输入更像真人一些。也可以使用keyboard.down(key[, options])来一个字符一个字符的输入。

  2. 如果是通过cookie判断登录状态的可以通过page.setCookie(...cookies),想要维持cookie可以定时访问。

Tip:有些网站需要扫码,但是相同域名的其他网页却有登录,就可以尝试去可以登录的网页登录完利用cookie访问跳过扫码。

简单例子

示例代码:

const puppeteer = require('puppeteer');(async () => {const browser = await puppeteer.launch({headless: false});const page = await browser.newPage();await page.goto('https://baidu.com');await page.type('#kw', 'puppeteer', {delay: 100});page.click('#su')await page.waitFor(1000);const targetLink = await page.evaluate(() => {return [...document.querySelectorAll('.result a')].filter(item => {return item.innerText && item.innerText.includes('Puppeteer的入门和实践')}).toString()});await page.goto(targetLink);await page.waitFor(1000);browser.close();
})()

运行截图:

puppeteer( Nodejs 版 selenium )快速入门相关推荐

  1. python快速入门第三版-Python 快速入门:第3版 配套资源 PDF 完整版

    给大家带来的一篇关于Python入门相关的电子文档资源,介绍了关于Python.快速入门方面的内容,本书是由Python官网出版,格式为PDF,资源大小23 MB,码小辫编写,目前豆瓣.亚马逊.当当. ...

  2. mca版Quiver快速入门

    Quiver快速入门 装载自:https://github.com/HappenApps/Quiver/wiki/Quiver%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8 ...

  3. web自动化测试-第一讲:selenium快速入门

    一.selenium目前住主流的web自动化测试框架: 1.资料丰富 资料丰富        2.测试岗位招聘要求,上板率非常之高        3.支持多语言(iava/ pythan/ go /j ...

  4. UI自动化基础 - selenium快速入门教学

    前言 自上次更新了xpath路径的查找,这几天又完成了一些关于selenium里方法的学习,感觉selenium确实不失为一个好的自动化入门软件.所以秉着不断学习的过程,也顺带记录一下selenium ...

  5. python快速入门第三版-Python3快速入门

    --<趣学Python-教孩子学编程>学习笔记 1.注释 (1)单行注释以 # 开头注释 #这是一个注释 print("Hello, World!") (2)多行注释可 ...

  6. 《嵌入式 Linux应用程序开发标准教程(第2版)》——第1章 Linux快速入门 1.1 嵌入式Linux基础...

    本节书摘来自异步社区<嵌入式 Linux应用程序开发标准教程(第2版)>一书中的第1章,第1.1节,作者 华清远见嵌入式培训中心,更多章节内容可以访问云栖社区"异步社区" ...

  7. python初学者代码示例_Selenium 快速入门笔记和代码示例(Python版)

    链接 文档链接: 安装 selenium 模块和 Chrome 浏览器驱动 步骤: 安装 Selenium 模块: pip install selenium 下载浏览器驱动(下载即可,无需安装,使用时 ...

  8. [官版翻译ing]OpenStack云计算快速入门之一:OpenStack及其构成简介

    转自:http://blog.chinaunix.net/uid-22414998-id-3263551.html <OpenStack Starter Guide for Ubuntu 12. ...

  9. 《Python数据分析基础教程:NumPy学习指南(第2版)》笔记1:第一章 NumPy快速入门

    NumPy快速入门 1.1 Python NumPy是基于Python的,因此在安装NumPy之前,需要先安装Python.某些操作系统已经默认安装有Python环境,但仍需检查Python的版本是否 ...

最新文章

  1. vue实战之前期准备
  2. 643 Maximum Average Subarray I
  3. 聚焦“裂变”,又拍云推出直播云等多场景解决方案
  4. JS_13原型与原型链
  5. opencv基于DNN的人脸检测
  6. Microsoft经典平面广告we see
  7. Visual C#中父窗口和子窗口之间实现控件互操作
  8. 为什么说干实业的玩不过干金融的?
  9. Office365下部署SharePoint站点集
  10. plsql本机不安装数据库连接远程数据库
  11. MySQL:设置字段默认为当前时间
  12. GridView中使用DropDownList的OnSelectedIndexChanged事件
  13. 专业破解各种版本的IDEA
  14. 暗通道去雾算法原理及实现
  15. USB3.0视频输出方案
  16. 2021年末大盘点。IT行业那些薪资高前景好的岗位,你知道几个?
  17. 慕名而来的博客(小白)
  18. 数据加解密之Java实现Base64加密
  19. 利用for语句,编程输出如下图形:* *** *****
  20. android-studio安装过程详解

热门文章

  1. 史上最强多线程面试44题和答案:线程锁+线程池+线程同步等
  2. 领域应用 | 知识图谱在小米的应用与探索
  3. 论文浅尝 | 用于低资源条件下知识图谱补全的关系对抗网络
  4. 关于PaddleNLP如何加载训练好的模型进行NER
  5. (设计模式)简单工厂模式之通过配置文件动态创建实现类
  6. “知识图谱+”系列:知识图谱+图神经网络
  7. c++ 字符串转数字
  8. mysql报错:Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggre
  9. 读书笔记007:《伤寒论》- 手少阴心经
  10. Laravel 代码开发最佳实践(持续更新)