跳至主要內容
版本: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

傳回的物件是 JSHandleElementHandleElementHandle 擴充了 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.

將引數傳遞給評估函數

您可以為您的函數提供引數

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

引數可以是原始值或 JSHandle

注意

Page、JSHandle 和 ElementHandle 提供了幾個不同的輔助程式來評估 JavaScript,但它們都遵循本指南中概述的基本原則。