2

I'm having trouble finding a way to iterate subnodes of a given node in puppeteer. I do not know the html structure beforehand, just the id of the parent element.

var elemId = "myelemid";

const doc = await page._client.send('DOM.getDocument');
const node = await page._client.send('DOM.querySelector', {
    nodeId: doc.root.nodeId,
    selector: '#' + elemId
});
//node.children empty
//node['object'].children empty

//try requesting childnodes
var id = node.nodeId;   
var childNodes = await page._client.send('DOM.requestChildNodes', {
   nodeId: id
});         
//childNodes empty

//try requesting by resolveNode?
var aNode = await page._client.send('DOM.resolveNode', {
   nodeId: id
});      
//aNode.children is empty

Is there a way to get the children of a node if you don't know the html structure in puppeteer?

  • You can specify the child node(s) in your initial selector directly, either by using an XPath query (`//*[@id="myElemId"]/*[1]` ) or a CSS selector ( `#elemId *:first-child` ). How do these fail for you? Also, for `DOM.requestChildNodes`, you will need to wait for the asynchronous answers in `setChildNodes` events (see [the documentation](https://chromedevtools.github.io/devtools-protocol/tot/DOM/#method-requestChildNodes) on that). – Corion Dec 10 '18 at 10:03

2 Answers2

3

What I would do here is to use the evaluate method of Puppeteer to return the children elements of your node to your script as follows:

const nodeChildren = await page.$eval(cssSelector, (uiElement) => {
  return uiElement.children;
});
console.log(nodeChildren); // Outputs the array of the nodes children

Hope this helps!

AJC24
  • 3,280
  • 2
  • 19
  • 30
3

I ended up using page.evaluate to run some js that adds unique classnames to every element and subelement I want analyzed and then pass that back as JSON string since page.evaluate only returns a string. Then I just call DOM.querySelector on each of those unique selectors and loop through them that way.

Returning children from page.$eval doesn't give me protocol nodes that I can run more dev protocol functions on, and xpath doesn't solve my real problem because it can't recursively loop through all sub-children, then the sub-children of those children.

I'm closing the issue since labeling using unique classnames solves my problem.