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
或 ElementHandle
。ElementHandle
擴充了 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,但它們都遵循本指南中概述的基本原則。