我知道
await page.evaluateOnNewDocument(fs.readFileSync('./helperFunctions.js', 'utf8'));
将函数添加到evaluate()
上下文,这非常方便。
但是,是否有人可以提供任何示例在主要上下文中具有相同的内容?例如,我说要添加一个
page.existsText()
或
existsText()
使用此代码从要包含/来源的文件中 :
existsText = (string) => {
// code goes here
}
要走的路是什么?
答案 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");
});
使用浏览器范围进行操作