How to select a parent element in Puppeteer?

I’m working on a Puppeteer project and I’m stuck. I need to click on an odds value based on a team name, but these elements must be within a specific parent container. The tricky part is that this structure repeats on the page with identical classes.

Here’s what I’m trying to do:

  1. Find a container with the text “1st Goal”
  2. Get its parent element
  3. Within that parent, locate the second div (class “parent2”)
  4. Inside “parent2”, find and click on a specific odds value (like 200)

I’ve attempted using parentElement and parentNode, but I always get ‘undefined’ when trying to get the parent of a child element. The child element is found correctly, but I can’t seem to navigate up the tree to the parent.

Here’s a simplified version of the HTML structure I’m dealing with:

<div class="main-group">
  <div class="top-level"><span>1st Goal</span></div>
  <div class="sub-level">
    <div class="inner-box">
      <div>
        <div><span>Team A</span><span class="score">250</span></div>
        <div><span>No Goal</span><span class="score">350</span></div>
        <div><span>Team B</span><span class="score">450</span></div>
      </div>
    </div>
  </div>
  <div></div>
</div>

Any ideas on how to solve this parent-child navigation issue in Puppeteer?

Having worked extensively with Puppeteer, I can offer some insights on selecting parent elements. The key is to use XPath or a combination of CSS selectors and JavaScript evaluation.

For your specific case, you could try this approach:

const element = await page.$x('//span[text()="1st Goal"]/ancestor::div[contains(@class, "main-group")]//div[contains(@class, "sub-level")]//span[text()="Team A"]/following-sibling::span[contains(@class, "score")]');
if (element.length > 0) {
    await element[0].click();
}

This XPath query navigates up to the main-group div, then down to the specific score element. It is more reliable than using parentElement or parentNode directly in Puppeteer.

Remember to adjust the XPath based on your exact HTML structure. This method has served me well in complex scraping tasks.

I’ve dealt with similar parent-child navigation challenges in Puppeteer before. One approach that’s worked well for me is using the $$eval method. It allows you to run a callback function in the context of the page, which can be really powerful for complex selections.

Here’s a snippet that might help:

const result = await page.$$eval('.main-group', (groups, targetText) => {
  const targetGroup = groups.find(g => g.textContent.includes(targetText));
  if (!targetGroup) return null;
  const scoreElement = targetGroup.querySelector('.sub-level .score');
  return scoreElement ? scoreElement.textContent : null;
}, '1st Goal');

console.log(result); // This should log the score, e.g. '250'

This approach first finds all .main-group elements, then filters to the one containing ‘1st Goal’, and finally selects the score within that group. It’s flexible and can be adapted to click the element instead of just getting the text. Hope this helps solve your issue!

hey mate, i’ve had similar issues. try using evaluateHandle() method in puppeteer. it lets u run JavaScript in the browser context. something like:

const parentElement = await page.evaluateHandle((el) => el.closest('.main-group'), childElement);

this should grab the closest parent with class ‘main-group’. hope it helps!