可以在nodejs + puppeteer中包含一个源文件来添加函数吗?

时间:2018-05-23 10:03:53

标签: javascript node.js puppeteer

我知道

await page.evaluateOnNewDocument(fs.readFileSync('./helperFunctions.js', 'utf8'));

将函数添加到evaluate()上下文,这非常方便。

但是,是否有人可以提供任何示例在主要上下文中具有相同的内容?例如,我说要添加一个

page.existsText()

existsText()

使用此代码从要包含/来源的文件中

existsText = (string) => {
    // code goes here
}

要走的路是什么?

2 个答案:

答案 0 :(得分:1)

您可以从页面对象中添加Page类的一些方法,以便快速入侵。

const puppeteer = require("puppeteer");

puppeteer.launch().then(async browser => {
  const page = await browser.newPage();

  // page constructor is Page, 
  // and we can add some other methods to it's prototype
  page.constructor.prototype.myCustomMethod = function() {
    return this._frameManager.mainFrame().url();
  };

  await page.goto("https://example.com");
  const customUrl = await page.myCustomMethod();

  console.log({ customUrl }); // Returns { customUrl: 'https://example.com/' }
  await browser.close();
});

对于一些快速黑客来说,这很简单。所以,让我们添加一些exists方法。

// get all arguments
page.constructor.prototype.existsText = function(...args) {
  // let's assume the argument as a variable called string
  return this._frameManager.mainFrame().evaluate(string => {
    // create a new regex to find global multiline insensitive results
    const searchRegex = new RegExp(string, "gmi");
    // find all matchs
    return document.querySelector("body").outerHTML.match(searchRegex);
  }, args); // pass all arguments
};
const foundText = await page.existsText("more");
console.log({ foundText }); 
// Result: { foundText: [ 'More' ] }

同样,这些都是快速攻击并且有其自身的局限性。随意探索。

答案 1 :(得分:1)

如果我正确理解意图,您希望将函数从文件导入到全局命名空间,而不必将它们分配给中间变量。这是在节点中执行此操作的简单方法。

<强> helperFunctions.js

(function(){
    // Assign the function to the scope from where it's called
    this.existsText = (string) => {
        console.log("Do stuff with " + string);
    }
})()

然后当你在node.js / puppeteer脚本中需要它时,它会立即执行从中分配函数到全局范围:

require("./helperFunctions");

existsText("global scope");

结果:

  

做全球范围的事情

奖金:在page.evaluate中使用相同的功能

如果需要,可以在浏览器范围中使用相同的帮助文件:

await page.evaluateOnNewDocument(fs.readFileSync('./helperFunctions.js', 'utf8'));

await page.evaluate(() => { 
    existsText("browser scope");
});
  

使用浏览器范围进行操作