如何使用evaluateOnNewDocument和exposeFunction?

时间:2017-09-08 09:35:20

标签: javascript puppeteer

最近,我使用Puppeteer进行了一个新项目。

关于我不理解的API部分,我有几个问题。这些API介绍的文档非常简单:

  1. page.exposeFunction
  2. page.evaluateOnNewDocument
  3. 我是否可以通过详细的演示来获得更好的理解?

1 个答案:

答案 0 :(得分:2)

摘要:

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

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


Puppeteer Documentation for page.exposeFunction()指出:

  

page.exposeFunction(name,puppeteerFunction)

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

该方法在页面的name对象上添加了一个名为window的函数。调用该函数时,该函数在node.js中执行puppeteerFunction,并返回一个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();
});
     

向页面添加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();
});

此外,Puppeteer Documentation for page.evaluateOnNewDocument解释:

  

page.evaluateOnNewDocument(pageFunction,... args)

     
      
  • pageFunction <function | string>在浏览器上下文中评估的功能
  •   
  • ...args <... Serializable>传递给pageFunction的参数
  •   
  • 返回:<Promise>
  •   
     

添加将在以下情况之一中调用的函数:

     
      
  • 在浏览页面时
  •   
  • 附加或导航子框架时。在这种情况下,将在新连接的框架的上下文中调用该函数
  •   
     

在创建文档之后但在运行任何脚本之前调用该函数。这对于修改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);