跳转到主要内容
版本:23.11.1

JavaScript 执行

Puppeteer 允许在 Puppeteer 驱动的页面上下文中评估 JavaScript 函数

// Import puppeteer
import puppeteer from 'puppeteer';

(async () => {
// Launch the browser
const browser = await puppeteer.launch();

// Create a page
const page = await browser.newPage();

// Go to your site
await page.goto('YOUR_SITE');

// Evaluate JavaScript
const three = await page.evaluate(() => {
return 1 + 2;
});

console.log(three);

// Close browser.
await browser.close();
})();
注意

尽管该函数是在您的脚本上下文中定义的,但它实际上会被 Puppeteer 转换为字符串,发送到目标页面并在那里进行评估。这意味着该函数无法访问作用域变量或调用在您的 Puppeteer 脚本中定义的其他函数,并且您需要在函数体中定义整个函数逻辑。

或者,您可以提供一个函数体作为字符串

// Evaluate JavaScript
const three = await page.evaluate(`
1 + 2
`);
注意

上面的示例产生了等效的结果,但它也说明了可用于评估函数的类型和全局变量是未知的。特别是在 TypeScript 中,您应该注意确保评估函数引用的对象是正确的。

返回类型

您评估的函数可以返回值。如果返回的值是原始类型,它会被 Puppeteer 自动转换为脚本上下文中的原始类型,如前面的示例所示。

如果脚本返回一个对象,Puppeteer 会将其序列化为 JSON 并在脚本端重新构造它。这个过程可能并不总是产生正确的结果,例如,当您返回一个 DOM 节点时

const body = await page.evaluate(() => {
return document.body;
});
console.log(body); // {}, unexpected!

为了处理返回的对象,Puppeteer 提供了一种按引用返回对象的方式

const body = await page.evaluateHandle(() => {
return document.body;
});
console.log(body instanceof ElementHandle); // true

返回的对象要么是 JSHandle,要么是 ElementHandleElementHandle 扩展了 JSHandle,它仅为 DOM 元素创建。

有关句柄的可用方法的更多详细信息,请参阅 API 文档

返回 Promise

如果您从评估调用返回一个 Promise,该 Promise 将被自动等待。例如,

await page.evaluate(() => {
// wait for 100ms.
return new Promise(resolve => setTimeout(resolve, 100));
});
// Execution continues here once the Promise created in the page context resolves.

将参数传递给 evaluate 函数

您可以为您的函数提供参数

const three = await page.evaluate(
(a, b) => {
return a + b; // 1 + 2
},
1,
2,
);

参数可以是原始值或 JSHandle

注意

Page、JSHandle 和 ElementHandle 提供了几种不同的辅助函数来评估 JavaScript,但它们都遵循本指南中概述的基本原则。