传递的函数不能很好地序列化

时间:2019-11-24 19:45:28

标签: node.js puppeteer

我正在使用Puppeteer从包含订单数据的文件模板中抓取网页。

为此,我正在使用伪造的评估函数,当文件位于.js中时,该函数可以正常工作

但是,当使用“ pkg”包来编译.exe文件或评估执行并启动返回或错误时:“ 传递的函数不是可序列化的!

下面是代码:

const dados = {name: 'foo', year: 1}
  await page.evaluate(dados => {
    let dom = document.querySelector('body');
    const tags = Object.keys(dados);

    for (let i = 0; i < tags.length; i++) {
      const tag = tags[i];
      dom.innerHTML = dom.innerHTML.split(`{{${tag}}}`).join(dados[tag]);
    }
  }, dados);

3 个答案:

答案 0 :(得分:0)

对我来说最简单的解决方案是用eval()包装它:

async getText(selector: string) {
    await this.page.waitForSelector(selector);
    let text = await eval(`this.page.$eval('${selector}', el => el.textContent)`)

    return text;
}

或者这个:

await eval(`this.page.evaluate(
      (selector) => { (document.querySelector(selector).value = ''); },
       selector);`);

答案 1 :(得分:0)

我遇到了与puppeteerpkg有关的确切问题。由于某些原因,pkg无法正确解释回调的内容。对我有用的解决方案是将字符串传递给evaluate而不是函数:

更改:

const dados = {name: 'foo', year: 1}
  await page.evaluate(dados => {
    let dom = document.querySelector('body');
    const tags = Object.keys(dados);

    for (let i = 0; i < tags.length; i++) {
      const tag = tags[i];
      dom.innerHTML = dom.innerHTML.split(`{{${tag}}}`).join(dados[tag]);
    }
  }, dados);

await page.evaluate(`
    (() => {
        const dados = {name: 'foo', year: 1};
        let dom = document.querySelector('body');
        const tags = Object.keys(dados);

        for (let i = 0; i < tags.length; i++) {
          const tag = tags[i];
          dom.innerHTML = dom.innerHTML.split(`{{${tag}}}`).join(dados[tag]);
        }

        // return dom to do something with the data in node
        return dom.innerHTML
     })()`);

This answer on github提出了另一种解决方案-使用pkg api在编译时注入回调,但这对我不起作用。

答案 2 :(得分:0)

我尝试将--public的参数添加到pkg中。

赞:pkg start.js -t node14-win-x64 --public

然后我可以自由使用ElementHandle.evaluate( (elem)=> elem.textContent );

使用pkg手册,--public意味着:加快并公开顶级项目的来源。

顺便说一句

要修复,无法找到Chrome二进制文件

browser = await puppeteer.launch({
    executablePath: "node_modules/puppeteer/.local-chromium/win64-782078/chrome-win/chrome.exe"
});

(上面的路径可以随意设置。)

要修复,start.exe无法运行

有时输出二进制exe无法执行。它 输入start.exe时,总是会弹出一个新的cmd提示窗口。 (或双击)。

  • 只需删除输出exe,然后重新运行pkg
  • 检查代码是否可与node start.js一起运行