木偶:在page.evaluate中使用函数

时间:2019-06-05 10:08:08

标签: puppeteer

我需要在page.evaluate中使用带有伪造物的函数。我使用exposeFunction,并且需要将完整的Element发送到我的函数中

我有一个简单的例子:

const puppeteer = require('puppeteer');    

const myFunction = (content) => {
    console.log(content.outerHTML); // empty
}

(async () => {    
    const browser = await puppeteer.launch()     
    const page = await browser.newPage()  
    page.on('console', msg => console.log('PAGE LOG:', msg.text()));      

    const url =  "https://www.google.com";

    await page.goto(url,{
        waitUntil: 'networkidle2'
    })

    await page.exposeFunction('myFunction', myFunction);

    const content = await page.$('.content')

    await page.evaluate( (content) => {    

        myFunction (content); // I need to send full Element

        //console.log(content.outerHTML); // here works fine
        //my_function (JSON.stringify(content)); // sends {}

    }, content )      
})()

我尝试使用JSON.stringify / JSON.parse发送但没有结果。

2 个答案:

答案 0 :(得分:1)

简短答案: 你不能。

详细答案: 您无法通过exposeFunction在浏览器外部发送DOM元素。

此外,您发送的所有内容都会被序列化,不能有任何循环引用。 NodeJS没有DOM。

解决方法是

  • 要么只传递没有任何循环引用的字符串和对象,要么
  • 或使用伪造的ElementHandle处理元素。在您的代码中,content变量是ElementHandle。

答案 1 :(得分:0)

page.exposeFunction仅限于序列化数据,其他答案已经指出。

但是您可以在page.execute块中定义一个函数。请注意,在那里定义的功能只会出现在浏览器环境中,而不会出现在Node.js脚本中。

代码示例

以下代码在myFunction函数内部实现了evaluate,可在下面使用:

await page.evaluate((content) => {
    const myFunction = (content) => {
        return content.outerHTML;
    };

    const result = myFunction(content);
    return result; // or whatever you want to do with the result
}, content);