问题
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.
My sample code:
// 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);
})()
回答1:
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)
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.
来源:https://stackoverflow.com/questions/51180994/handling-events-from-puppeteers-page-context-outside-evaluate-method