Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/380.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何获取Puppeter访问的页面的所有DOM元素上的所有事件-基本上是getEventListeners_Javascript_Puppeteer_Cdp - Fatal编程技术网

Javascript 如何获取Puppeter访问的页面的所有DOM元素上的所有事件-基本上是getEventListeners

Javascript 如何获取Puppeter访问的页面的所有DOM元素上的所有事件-基本上是getEventListeners,javascript,puppeteer,cdp,Javascript,Puppeteer,Cdp,我正在做一些木偶游戏驱动的网站分析,真的需要在一个页面上列出所有事件 使用“普通”JavaScript很容易,所以我想我可以在木偶师中对其进行评估,然后开始其他任务 嗯,这并不容易,例如“getEventListeners”就不起作用。因此,下面的代码不起作用(但如果我接受评估的代码,将其复制到浏览器控制台并运行-它工作得很好) (src:) 但当我想检查每个DOM元素的事件并将它们添加到数组中时,这看起来太复杂了。我怀疑有比循环页面元素并为每个元素运行CDP更好的方法。或者更好地说——我希望:

我正在做一些木偶游戏驱动的网站分析,真的需要在一个页面上列出所有事件

使用“普通”JavaScript很容易,所以我想我可以在木偶师中对其进行评估,然后开始其他任务

嗯,这并不容易,例如“getEventListeners”就不起作用。因此,下面的代码不起作用(但如果我接受评估的代码,将其复制到浏览器控制台并运行-它工作得很好)

(src:)

但当我想检查每个DOM元素的事件并将它们添加到数组中时,这看起来太复杂了。我怀疑有比循环页面元素并为每个元素运行CDP更好的方法。或者更好地说——我希望:)

有什么想法吗

我想要一个包含所有元素的数组,其中包含(JS)事件,例如:

let allEventsOnThePage : [
   {el: "blutton", events : ["click"]},
   {el: "input", events : ["click", "blur", "focus"]},
   /* you get the picture */
];

我很好奇,所以我研究了如何扩展您发现的CDP示例,并得出以下结论:

异步函数描述(会话,选择器='*')){ //允许轻松清理资源的唯一值 常量对象组='dc24d2b3-f5ec-4273-a5c8-1459b5c78ca0'; //在浏览器中计算查询选择器 const{result:{objectId}}=wait session.send('Runtime.evaluate'{ 表达式:`document.querySelectorAll(${selector})`, 对象组 }); //使用返回的远程对象ID,实际获取描述符列表 const{result}=wait session.send('Runtime.getProperties',{objectId}); //过滤掉函数和任何非节点的内容 常量描述符=结果 .filter(x=>x.value!==未定义) .filter(x=>x.value.objectId!==未定义) .filter(x=>x.value.className!=='Function'); 常量元素=[]; for(描述符的常量描述符){ const objectId=descriptor.value.objectId; //添加事件侦听器和节点描述(用于属性) assign(描述符,wait session.send('DOMDebugger.getEventListeners',{objectId})); assign(描述符,wait session.send('DOM.descripbenode',{objectId})); 元素push(描述符); } //打扫干净 wait session.send('Runtime.releaseObjectGroup',{objectGroup}); 返回元素; } 它将返回一个对象数组,每个对象(至少)具有
节点
侦听器
属性,可以按如下方式使用:

/**Helper函数,用于将键/值对的平面数组转换为对象*/
函数属性(数组){
常量结果=[];
for(设i=0;i{
const browser=wait puppeter.launch();
const page=wait browser.newPage();
等待页面。转到('https://chromedevtools.github.io/devtools-protocol“,{waitUntil:'networkidle0'});
const session=wait page.target().createCDPSession();
const result=等待描述(会话);
for(结果的const{node:{localName,attributes},listeners}){
如果(listeners.length==0){continue;}
const{id,class:_class}=parseAttributes(attributes);
让描述符=localName;
如果(id!==未定义){descriptor+=`${id}`}
如果(_类!==未定义){descriptor+=`.${u类}`;}
log(`${descriptor}:`);
for(侦听器的常量{type,处理程序:{description}}}){
log(`${type}:${description}`);
}   
}
等待浏览器关闭();
})();
这将返回类似于:

button.aside-close-button:
单击:函数W(){I.classList.contains(“显示”)和&(I.classList.remove(“显示”),P.focus())}
主要内容:
单击:函数W(){I.classList.contains(“显示”)和&(I.classList.remove(“显示”),P.focus())}
按钮。菜单链接:
单击:e=>{e.stopPropagation(),I.addEventListener(“transitionend”,()=>{O.focus()},{once:!0}),I.classList.add(“显示”)}

可能会有帮助。看起来非常有希望,将进行一些测试,看看它的性能如何(这将在数百或数千个URL上运行)。谢谢,这非常有效,我很惊讶它的速度有多快。需要更多的测试,但也许你可以把它传给木偶师:)令人惊讶的是CDP有多快。也将使用复杂页面进行测试
 const cdp = await page.target().createCDPSession();
  const INCLUDE_FN = true;
  const { result: {objectId} } = await cdp.send('Runtime.evaluate', {
    expression: 'foo',
    objectGroup: INCLUDE_FN ?
      'provided' : // will include fn
      '' // wont include fn
  });
  const listeners = await cdp.send('DOMDebugger.getEventListeners', { objectId });
  console.dir(listeners, { depth: null });
let allEventsOnThePage : [
   {el: "blutton", events : ["click"]},
   {el: "input", events : ["click", "blur", "focus"]},
   /* you get the picture */
];