在评估方法之外处理来自 puppeteer 页面上下文的事件 [英] Handling events from puppeteer's page context outside evaluate method

查看:68
本文介绍了在评估方法之外处理来自 puppeteer 页面上下文的事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的目标是在 nodejs 环境中将 puppeteer-chromium 实例作为子进程打开,并以可从父进程访问这些事件的方式监听用户将进行的所有点击.所以我认为需要事件流,但我不知道如何从评估方法发送它们(在该上下文中无法访问进程对象 - 铬日志中的进程未定义").

My goal is to open puppeteer-chromium instance as a child process in nodejs environment and listen to all clicks that user will make in a way that these events are accessible from parent process. So I think stream of events is needed but I have no idea how to send them from evaluate method (process object is not accessible in that context - 'process is undefined' in logs of chromium).

目前我正在尝试在页面上下文中添加点击侦听器,但有没有办法在评估方法之外获取这些事件?

Currently I'm trying to add click listener inside page's context but is there any way to obtain those events outside of evaluate method?

我知道评估方法可以返回承诺,但它只有一个值所以还不够.我想收集所有点击,直到我关闭铬窗口.

I know evaluate method can return promise but it's only one value so it's not enough. I'd like to gather all clicks until I close chromium window.

提前感谢您的各种建议.

Thanks in advance for all kind of advices.

我的示例代码:

  // parent.js
  const child = require('child_process');
  const childprocess = child.fork('./childprocess.js');
  childprocess.on('message', (msg) => {
      console.log('Message from child', msg);
      // here I'd like to get click events from childprocess
      // eg. saving them in database
  });

  // childprocess.js
  const puppeteer = require('puppeteer');
  (async () => {
      await process.on('message', (m) => {
        process.send(m)
      })
      const browser = await puppeteer.launch(options);
      const page = await browser.newPage();
      await page.goto('http://someurl.com');
      await page.evaluate( (processHandle) => {
        document.addEventListener('click', (event) => {
          console.log(event);  // event is logged in chromium dev console
          processHandle.send({msg: event}); // nothing happens
        })
      }, process);
  })()

推荐答案

示例代码的问题在于 processHandle 不会以文档上下文中的 JavaScript 的方式进行序列化可以使用它.您可以改为 上公开一个函数窗口 会做你想做的:

The issue with the sample code is that processHandle won’t be serialized in such a way that JavaScript in the context of the document can use it. You can instead expose a function on window that will do what you want:

await page.exposeFunction("sendEventToProcessHandle", (event) => {
    processHandle.send({ msg: JSON.parse(event) });
})

await page.evaluate((processHandle) => {
    document.addEventListener('click', function (e) {
        window.sendEventToProcessHandle(JSON.stringify(e));
    });
}, process)

这里,window.sendEventToProcessHandle 是一个将在 Node.JS 进程上下文中运行的函数,您可以在其中访问 processHandle,但可以由文档.

Here, window.sendEventToProcessHandle is a function that will run in the context of the Node.JS process, where you can access processHandle, but can be called by the document.

这篇关于在评估方法之外处理来自 puppeteer 页面上下文的事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆