如何使用evaluateOnNewDocument和exposeFunction?

use*_*191 5 javascript puppeteer

最近,我在一个新项目中使用了 Puppeteer。

我对 API 的一部分有一些我不明白的问题。文档对于这些API的介绍非常简单:

  1. page.exposeFunction
  2. page.evaluateOnNewDocument

可以给我一个详细的演示以便更好地理解吗?

Gra*_*ler 2

概括:

Puppeteer 函数page.exposeFunction()本质上允许您访问页面 DOM 环境中的 Node.js 功能。

另一方面,page.evaluateOnNewDocument()在创建新文档时以及执行其任何脚本之前评估预定义函数。


Puppeteer文档的page.exposeFunction()状态:

page.exposeFunction(名称, puppeteerFunction)

  • name< string > 窗口对象上的函数名称
  • puppeteerFunction<function>将在 Puppeteer 上下文中调用的回调函数
  • 返回:<承诺>

name该方法添加了一个在页面对象上调用的函数window。调用时,该函数puppeteerFunction在 node.js 中执行并返回一个Promise,该 Promise 解析为 的返回值puppeteerFunction

如果puppeteerFunction返回一个Promise,它将被等待。

注意通过page.exposeFunction生存导航安装的功能。

md5在页面中添加功能的示例:

const puppeteer = require('puppeteer');
const crypto = require('crypto');

puppeteer.launch().then(async browser => {
  const page = await browser.newPage();
  page.on('console', msg => console.log(msg.text()));
  await page.exposeFunction('md5', text =>
    crypto.createHash('md5').update(text).digest('hex')
  );
  await page.evaluate(async () => {
    // use window.md5 to compute hashes
    const myString = 'PUPPETEER';
    const myHash = await window.md5(myString);
    console.log(`md5 of ${myString} is ${myHash}`);
  });
  await browser.close();
});
Run Code Online (Sandbox Code Playgroud)

window.readfile在页面中添加功能的示例:

const puppeteer = require('puppeteer');
const fs = require('fs');

puppeteer.launch().then(async browser => {
  const page = await browser.newPage();
  page.on('console', msg => console.log(msg.text()));
  await page.exposeFunction('readfile', async filePath => {
    return new Promise((resolve, reject) => {
      fs.readFile(filePath, 'utf8', (err, text) => {
        if (err)
          reject(err);
        else
          resolve(text);
      });
    });
  });
  await page.evaluate(async () => {
    // use window.readfile to read contents of a file
    const content = await window.readfile('/etc/hosts');
    console.log(content);
  });
  await browser.close();
});
Run Code Online (Sandbox Code Playgroud)

此外,Puppeteer 文档page.evaluateOnNewDocument解释道:

page.evaluateOnNewDocument(pageFunction, ...args)

  • pageFunction<功能| string > 要在浏览器上下文中评估的函数
  • ...args<...可序列化> 要传递给的参数pageFunction
  • 返回:<承诺>

添加将在以下场景之一调用的函数:

  • 每当页面被导航时
  • 每当附加或导航子框架时。在这种情况下,该函数在新附加的框架的上下文中调用

在创建文档之后但在运行其任何脚本之前调用该函数。这对于修改 JavaScript 环境很有用,例如种子Math.random

在页面加载之前覆盖 navigator.languages 属性的示例:

// preload.js

// overwrite the `languages` property to use a custom getter
Object.defineProperty(navigator, "languages", {
  get: function() {
    return ["en-US", "en", "bn"];
  }
});

// In your puppeteer script, assuming the preload.js file is in same folder of our script
const preloadFile = fs.readFileSync('./preload.js', 'utf8');
await page.evaluateOnNewDocument(preloadFile);
Run Code Online (Sandbox Code Playgroud)

  • 复制并粘贴文档是否被视为答案? (8认同)
  • @mawburn 正要写同样的东西。 (2认同)