news 2026/6/15 15:21:20

Puppeteer 实践笔记

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Puppeteer 实践笔记

概念理解

Puppeteer 是一个 Node.js 库,提供了高级 API 来控制无头(headless)Chrome 或 Chromium 浏览器。它通过 Chrome DevTools Protocol(CDP)与浏览器通信,可以实现页面自动化、爬虫、性能测试等功能。

Puppeteer 默认会安装对应版本的浏览器,如果只是想使用 Puppeteer 提供的高级 API 去控制浏览器 ,可以直接使用puppeteer-core而不是puppeteerpuppeteer具体安装的浏览器版本可以查看 支持的浏览器。

核心概念

  • Browser(浏览器实例):通过puppeteer.launch()创建的浏览器实例,可以管理多个页面。
  • Page(页面实例):代表浏览器中的一个标签页,每个页面都是独立的执行环境。
  • ElementHandle(元素句柄):通过选择器获取的 DOM 元素引用,可以对其进行操作。
  • CDP(Chrome DevTools Protocol):Chrome 开发者工具协议,Puppeteer 通过该协议与浏览器通信。

应用场景

  • 自动化脚本操作:自动化表单填写、页面操作等。
  • 爬虫:抓取网页数据,处理动态内容。
  • 自动化测试:端到端测试、UI 测试。
  • 性能分析:页面性能监控、性能报告生成,小推一下自己在维护的 MCP Server 项目 puppeteer-debugger-mcp-server。
  • 截图和 PDF 生成:页面截图、PDF 导出。

基础使用

创建浏览器实例

constbrowser=awaitpuppeteer.launch({headless:'new',defaultViewport:{width:1920,height:1080,},executablePath:path.resolve(EXCUTABLE_PATH),});// 关闭浏览器awaitbrowser.close();

参数说明

  • headless:无头浏览器设置,可选值:
    • false:显示浏览器窗口。
    • 'new':启用新的无头浏览器模式(推荐)。
    • true:已废弃,因为旧版无头浏览器存在各种问题。
    • 无头浏览器(不显示浏览器页面)有更少的内存占用和 CPU 消耗,适合命令行环境,但可能触发反爬机制,需要手动添加userAgent等参数。
  • defaultViewport:浏览器内的页面视窗大小。
  • executablePath:浏览器的运行路径,不填则使用 Puppeteer 安装时自带的 Chromium 浏览器。

创建页面实例

constpage=awaitbrowser.newPage();// 关闭页面awaitpage.close();

执行操作后,Puppeteer 会在当前浏览器内新建一个页面,每个page代表一个标签页,每个标签页的操作都是独立开的。

页面跳转

awaitpage.goto(url,options);

参数说明

  • url:要跳转的页面地址
  • options(可选):配置选项,如waitUntil(等待条件)、timeout(超时时间)等

元素操作

选中元素

Puppeteer 提供了两种方式来选中和操作元素:

1. 使用 CDP 协议选中元素
constelementHandle=awaitpage.$(selector);

Puppeteer 调用底层 CDP 协议去选中元素,会根据元素类型返回相应的ElementHandle对象,此时可以直接使用对象来进行元素相关操作。

2. 使用 JavaScript 代码操作 DOM
constresult=awaitpage.evaluate(()=>{returndocument.querySelector(selector);});

page.evaluate()是在页面内执行代码的函数,通过返回值来获取元素或执行操作。

注意page.evaluate()内部是一个独立于 Node.js 进程的浏览器环境,外部变量无法直接在函数内使用,需要通过page.evaluate()的第二个参数传入:

constname='Aliex';awaitpage.evaluate((name)=>{console.log(name);},name);

输入内容

awaitpage.type(selector,text,options);

参数说明

  • selector:被输入的元素选择器。
  • text:输入到浏览器中的内容。
  • options(可选):配置选项,如输入延迟等。

page.type()可以模拟键盘操作,在特定元素中键入内容。也可以模拟键盘快捷键操作。

点击元素

awaitpage.click(selector,options);

参数说明

  • selector:被点击的元素选择器。
  • options(可选):配置选项,如点击次数、延迟等。

通过该方法可以点击页面上的元素,不过有时行不通,需要借助page.evaluate()这种原生操作去实现点击。

等待操作

由于页面加载会涉及很多脚本执行,通常需要一些等待操作来确保页面或元素已加载完成。Puppeteer 提供了各种环境下的waitFor函数供我们使用。

等待一段时间

awaitpage.waitForTimeout(timeout);

可以控制一定的等待时间,在这之后才继续执行后面的函数。

等待元素存在于页面

awaitpage.waitForSelector(selector,options);

可用于等待当前页面元素出现,支持 query 选择方式。

但在测试中发现有时候会选不到相应的元素,所以可以使用另外一种方式:

awaitpage.waitForFunction(()=>{returndocument.querySelector(selector);});

waitForFunction()是一种较为灵活的等待方式,我们可以用它来等待元素加载完毕,或者实现一些其他操作,例如等待元素显示出来:

awaitpage.waitForFunction(()=>{returndocument.querySelector(selector).style.display!=='none';});

只要返回的结果为true,函数就会停止继续等待。

等待页面加载完毕

awaitpage.waitForNavigation(options);

可以等待页面加载完毕后再执行后面的函数,即页面左上角的刷新图标停止转动之后,才执行后面的代码。

设置等待超时时间

有时候因为网络问题导致出现网卡的情况,会导致等待时间过长。Puppeteer 本身会在等待超过 30s 之后停止等待,因此在需要的情况下,可以重新设置超时等待时间:

page.setDefaultTimeout(timeout);

等待网络请求

waitForRequest()是 Puppeteer 中的一个方法,用于等待特定的请求发出:

awaitpage.waitForRequest(urlOrPredicateOrPattern,options);

参数说明

  • urlOrPredicateOrPattern:可接受字符串、正则表达式或预定义的请求匹配器函数来指定需要等待的请求。
  • options(可选):可传递一个对象来指定附加选项,如超时时间等。

示例用法

// 等待特定 URL 的请求awaitpage.waitForRequest('https://example.com/api/data');// 使用正则表达式awaitpage.waitForRequest(/api/data$/);// 使用自定义匹配器函数awaitpage.waitForRequest((request)=>request.url().includes('api')&&request.method()==='POST');

在上述示例中,waitForRequest()会等待发出匹配条件的请求。一旦请求被发出,waitForRequest()会立即返回。

高级技巧

文件上传

如果页面比较遵守 W3C 开发规范,通常上传元素会使用<input type="file" />去实现。这时就可以通过 Puppeteer 原生的元素获取方式来进行文件上传:

constvideoInputHandle=awaitpage.$(inputSelector);// uploadFile 是 ElementHandle input 对象特有的方法awaitvideoInputHandle.uploadFile(path);

参数说明

  • path:需要上传的本地文件路径,不支持网络文件。

这样就可以触发本地上传功能。

将函数注入到页面内

使用page.exposeFunction()将本地函数暴露到页面的window对象上:

// 注入函数awaitpage.exposeFunction('handleMutation',(str)=>{console.log('DOM mutated!',str);console.log(page);// 这里可以拿到外部内容});awaitpage.evaluate(()=>{constobserver=newMutationObserver(()=>{window.handleMutation('params');// 可以传递参数到注入的函数中});observer.observe(document.querySelector('.element-class'),{childList:true,subtree:true,attributes:true,});});

页面跳转时注入/执行代码

在页面跳转时调用page.evaluate(),可能会因为 page 的上下文环境不同,导致代码执行崩溃。

解决方式是保存 URL 地址,在执行之前进行比较判断:

consturl1=page.url();// ... 其他操作consturl2=page.url();// 避免执行时上下文环境不同导致 Puppeteer 崩溃if(url1===url2){awaitpage.evaluate(fn);}

清空浏览器 Cookie

利用 CDP (Chrome DevTools Protocol) 清除 Cookie

constpage=awaitbrowser.newPage();constclient=awaitpage.target().createCDPSession();awaitclient.send('Network.clearBrowserCookies');

提升浏览器运行性能

constbrowser=awaitpuppeteer.launch({headless:'new',defaultViewport:{width:1920,height:1080,},args:['--disable-gpu','--disable-dev-shm-usage','--disable-setuid-sandbox','--no-first-run','--no-sandbox','--no-zygote',],});

这些参数可以禁用一些不必要的功能,减少资源消耗,提升浏览器运行性能。

分支流程处理

当有两个 Puppeteer 异步流程时,可以使用Promise.any()来实现异步分支:

constres=awaitPromise.any([page.waitForNavigation(),page.waitForTimeout(15000),]);

这样可以实现 “等待导航完成或超时 15 秒” 的逻辑。

思考

1. 为什么需要使用无头浏览器模式?

无头浏览器模式(headless)不显示浏览器窗口,有更少的内存占用和 CPU 消耗,适合在服务器环境或命令行界面中使用。但可能会触发一些网站的反爬机制,需要手动添加userAgentviewport等参数来模拟真实浏览器。

2.page.evaluate()page.$()的区别是什么?

  • page.$()使用 CDP 协议选中元素,返回ElementHandle对象,可以直接调用 Puppeteer 提供的方法进行操作。
  • page.evaluate()在页面内执行 JavaScript 代码,可以访问页面的 DOM 和全局对象,但返回的是序列化后的值,无法直接操作 DOM 元素。

3. 如何避免页面跳转时的上下文丢失问题?

在页面跳转时,页面的上下文环境会发生变化,如果在跳转过程中调用page.evaluate()可能会失败。解决方式是保存跳转前后的 URL,在执行代码前比较 URL 是否一致,或者使用page.waitForNavigation()等待跳转完成后再执行操作。

总结

  • Puppeteer 核心概念:通过 Browser、Page、ElementHandle 等对象实现对浏览器的控制,使用 CDP 协议与浏览器通信。
  • 基础操作:创建浏览器实例、新建页面、页面跳转、元素操作(选中、输入、点击)是 Puppeteer 的基础功能。
  • 等待机制:提供了多种等待函数(waitForSelectorwaitForNavigationwaitForFunction等)来确保页面或元素已加载完成。
  • 高级技巧:文件上传、函数注入、性能优化、分支流程处理解决复杂场景下的问题。
  • 注意事项:需要注意页面上下文环境的变化、无头浏览器可能触发反爬机制、等待超时等问题。

参考内容

  • Puppeteer 官方文档
  • Chrome DevTools Protocol
  • Puppeteer性能优化与执行速度提升
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/15 7:11:19

解锁AMD Ryzen性能密码:5大SDT工具实战技巧揭秘

解锁AMD Ryzen性能密码&#xff1a;5大SDT工具实战技巧揭秘 【免费下载链接】SMUDebugTool A dedicated tool to help write/read various parameters of Ryzen-based systems, such as manual overclock, SMU, PCI, CPUID, MSR and Power Table. 项目地址: https://gitcode.…

作者头像 李华
网站建设 2026/6/15 5:52:01

终极PPT演讲时间管理神器:智能悬浮计时器

终极PPT演讲时间管理神器&#xff1a;智能悬浮计时器 【免费下载链接】ppttimer 一个简易的 PPT 计时器 项目地址: https://gitcode.com/gh_mirrors/pp/ppttimer 还在为演讲超时而烦恼&#xff1f;这款基于AutoHotkey开发的智能悬浮计时器&#xff0c;让你在任何演讲场景…

作者头像 李华
网站建设 2026/6/15 11:30:35

城通网盘直连解析工具:告别限速困扰的智能解决方案

城通网盘直连解析工具&#xff1a;告别限速困扰的智能解决方案 【免费下载链接】ctfileGet 获取城通网盘一次性直连地址 项目地址: https://gitcode.com/gh_mirrors/ct/ctfileGet 还在为城通网盘下载速度慢而烦恼吗&#xff1f;每天面对漫长的等待时间&#xff0c;工作效…

作者头像 李华
网站建设 2026/6/15 12:28:28

MouseTester:你的鼠标性能检测专家

MouseTester&#xff1a;你的鼠标性能检测专家 【免费下载链接】MouseTester 项目地址: https://gitcode.com/gh_mirrors/mo/MouseTester 你是否曾经在玩游戏时觉得鼠标反应迟钝&#xff1f;或者在做设计工作时感觉光标不够精准&#xff1f;这些困扰很可能源于你的鼠标…

作者头像 李华
网站建设 2026/6/15 0:31:50

ncmdumpGUI终极指南:轻松实现NCM转MP3的完整解决方案

ncmdumpGUI终极指南&#xff1a;轻松实现NCM转MP3的完整解决方案 【免费下载链接】ncmdumpGUI C#版本网易云音乐ncm文件格式转换&#xff0c;Windows图形界面版本 项目地址: https://gitcode.com/gh_mirrors/nc/ncmdumpGUI 你是否曾经从网易云音乐下载了心爱的歌曲&…

作者头像 李华
网站建设 2026/6/15 5:43:19

小程序springboot基于Android的酒店预订系统App的设计与实现_100paa93

文章目录具体实现截图主要技术与实现手段关于我本系统开发思路java类核心代码部分展示结论源码lw获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01;具体实现截图 同行可拿货,招校园代理 小程序springboot基于Android的酒店预订系统App的设计与实…

作者头像 李华