puppeteer是什么?

Puppeteer 是一个 JavaScript 库,它提供了一个高级 API 来通过 开发工具协议 或 WebDriver 双向 控制 Chrome 或 Firefox。Puppeteer 默认在无UI模式下运行

puppeteer是用来干嘛的?
  • 自动化表单提交、UI 测试、键盘输入等
  • 使用最新的 JavaScript 和浏览器功能创建自动化测试环境
  • 捕获网站的时间线痕迹以帮助诊断性能问题
怎么使用puppeteer?

npm i puppeteer

当安装 puppeteer 时,它会自动下载最新版本的Chrome

如果已有Chrome,推荐下载puppeteer-core,

如果下载的是puppeteer-core,则需要在launch中指定chrome路径

mac的chrome安装路径通常是/Applications/Google Chrome.app/Contents/MacOS/Google Chrome

  const browser = await puppeteer.launch({
    executablePath:
      "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
    headless: false,
  });
puppeteer的核心操作
  • 管理浏览器
// 启动浏览器
const browser = await puppeteer.launch(); 
// 创造上下文,隔离运行环境,不同的运行环境Cookie和本地存储不在浏览器上下文之间共享
const context = await browser.createBrowserContext(); 

const page1 = await context.newPage();
  • 页面交互
// puppeteer推荐
page.locator('.button').click()
// 快捷
page.click('.button')
  • 在浏览器中执行JavaScript代码
// evaluate函数的作用是将函数传入浏览器的上下文中执行
// 该函数的上下文是浏览器中的window对象
await page.evaluate(() => {
  console.log('windows', this);
  return 1 + 2;
});
  • 网络日志记录
const page = await browser.newPage();
page.on('request', request => {
  console.log(request.url());
});

page.on('response', response => {
  console.log(response.url());
});

以下几个示例帮忙我们更好理解puppeteer怎么使用

示例

示例一:模拟自动化表单提交

  • page.type
  • page.click
const puppeteer = require("puppeteer-core");
(async () => {
   const browser = await puppeteer.launch({
    executablePath:
      "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
    headless: false,
  });
  const page = await browser.newPage();
  await page.goto(
    "file:///Users/umi/Desktop/code/test/puppeteer-demo/src/example1/index.html"
  );
  await page.type("#input-username", "test", {delay: 100});
  await page.type("#input-password", "test", {delay: 100});
  await page.click("#btn-submit");
})();

示例二:选取DOM元素与键盘输入

  • page.evaluate
  • page.focus
  • page.keyboard
const puppeteer = require("puppeteer-core");
(async () => {
  const browser = await puppeteer.launch({
    executablePath:
      "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
    headless: false,
  });
  const page = await browser.newPage();
  await page.goto(
    "file:///Users/umi/Desktop/code/test/puppeteer-demo/src/example2/index.html"
  );
  
  // evaluate函数的作用是将函数传入浏览器的上下文中执行
  // 该函数的参数是浏览器上下文中的window对象
  await page.evaluate(() => {
    console.log("windows", this);
    console.log("img-baidu", document.querySelector("#img-baidu"));
  });

  //将第一个输入框设置为焦点元素,如果对通过操作键盘对输入框输入内容,首先需要将输入框设置为焦点元素
  await page.focus("#search");

  //按住shift的同时,输入字母A,可以看到输入的字母A是大写状态
  await page.keyboard.down("Shift");
  await page.keyboard.press("KeyA");
  await page.keyboard.up("Shift");
})();

示例三:诊断性能问题

  • page.tracing

使用tracing方法来追踪页面加载时间线,使用 tracking.start 和 tracking.stop创建一个可以在 chrome devtools 打开的跟踪文件,执行下述代码会生成一个 testTrace.json 文件, 然后我们打开chrome devtools中 Performance 标签, 然后把该文件直接拖进去即可。

const puppeteer = require('puppeteer');
(async () => {
  const broswer = await puppeteer.launch();
  const page = await broswer.newPage();
  await page.tracing.start({
    path: 'testTrace.json',
  });
  await page.goto('https://www.baidu.com/');
  await page.tracing.stop();
  await broswer.close();
})();

示例四:生成PDF与截屏

const puppeteer = require("puppeteer-core");
(async () => {
  const browser = await puppeteer.launch({
    executablePath:
      "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
    headless: false,
    // 全屏
    args: ["--start-maximized"],
  });
  const page = await browser.newPage();

  // 设置视窗
  await page.setViewport({ width: 2537, height: 1159 });
  await page.goto(
    "file:///Users/umi/Desktop/code/test/puppeteer-demo/src/example4/index.html"
  );

  // 整个截屏
  page.screenshot({
    path: "example4.png",
    fullPage: true,
  });

  // 单个元素截屏
  const el = await page.$("#screenshot-img");
  el.screenshot({
    path: "example4-single.png",
  });

  // 生成pdf
  page.pdf({
    path: "example4.pdf",
    printBackground: true,
    width: "2537px",
    height: "1159px",
    margin: {
      top: "0px",
      right: "0px",
      bottom: "0px",
      left: "0px",
    },
  });
})();

使用中可能遇到的问题

  • PDF和截屏的样式不一致问题
    PDF文件和截屏的样式不一致可能是因为没有设置printBackground,指定环境为 screen。
page.pdf({
    path: "example4.pdf",
    format: "A4",
    printBackground: true,
  });
  • 截屏可能会遇到的问题
    页面元素没有加载完就截屏了,截屏的内容不完全。
    解决办法:在page的goto中加入等待参数waitUntil, networkidle0的意思是至少持续 500 ms没有网络请求了,才继续执行代码
await page.goto('https://example.com’,{
  waitUtil: 'networkidle0'
});

await page.screenshot({path: 'screenshot.png'});

一些建议

  • 通过chrome devtools的recorders可以记录用户行为以生成一个puppeteer文件
    在这里插入图片描述
Logo

中国智能体开发者社区,聚焦智能体与大模型开发,提供前沿资讯、实用工具链、开源项目及行业案例。通过技术沙龙、开发者大赛等活动,促进经验交流与协作,助力开发者快速构建创新智能应用。

更多推荐