I’m working with Puppeteer and need to extract the text content from DOM elements. I also want to know if it’s possible to click on an element based on its text content.
Here’s what I’m trying to achieve with regular JavaScript:
let elementFound = false;
$('.my-selector').each(function() {
if (elementFound) return;
const cleanText = $(this).html().replace(/\D/g, '');
if (cleanText === '10') {
$(this).click();
elementFound = true;
}
});
Can someone help me figure out how to do something similar in Puppeteer? I need to grab the inner content of elements and potentially interact with them based on that content.
you could also try page.$eval() with textContent instead of innerHTML. Something like const text = await page.$eval('.my-selector', el => el.textContent.replace(/\D/g, '')); then check if it matches what you need. for clicking based on text content, xpath’s your best bet: await page.$x("//div[contains(@class,'my-selector') and contains(text(),'10')]") then click the element it returns.
Use page.evaluate() to run JavaScript directly in the browser context. Here’s how I handle this:
const elementClicked = await page.evaluate(() => {
const elements = document.querySelectorAll('.my-selector');
for (const element of elements) {
const cleanText = element.innerHTML.replace(/\D/g, '');
if (cleanText === '10') {
element.click();
return true;
}
}
return false;
});
You can also extract text content first, then click based on conditions outside the evaluate function. I’ve had good luck with page.$$eval() for grabbing text from multiple elements, then using XPath selectors with page.$x() to click elements with specific text. Just remember that Puppeteer operations need to be wrapped in evaluate functions to run in the browser context.
I’ve found page.$$eval() really handy for this since it grabs elements and extracts content in one go. Extract all the text first, then handle clicking separately:
const textContents = await page.$$eval('.my-selector', elements =>
elements.map(el => el.innerHTML.replace(/\D/g, ''))
);
const targetIndex = textContents.findIndex(text => text === '10');
if (targetIndex !== -1) {
await page.click(`.my-selector:nth-child(${targetIndex + 1})`);
}
Separating text extraction from clicking makes debugging way easier. I’ve hit timing issues cramming everything into one evaluate function, especially with dynamic content that loads after the page renders.