Web scraping element selector returning empty result with Puppeteer

I’m having trouble extracting data from certain websites using Puppeteer. The element selector keeps returning empty results even though I can see the elements when I inspect the page manually. I’ve tried different approaches but nothing seems to work.

Here’s my current code:

const puppeteer = require('puppeteer');

(async () => {
    const browserInstance = await puppeteer.launch();
    const newPage = await browserInstance.newPage();

    await newPage.goto('https://example-store.com/product/sample-item');

    const elementData = await newPage.evaluate(() => {
        return document.querySelector('.product-cost');
    });

    console.log(elementData); 

    await browserInstance.close();
})();

The selector seems correct but I’m getting null instead of the actual content. What could be causing this issue?

yeh, it could be that the element isn’t present initially. you might wanna add await newPage.waitForSelector('.product-cost') before you try to evaluate it. it helps to ensure the element is loaded before accessing it.

I ran into this exact problem last month while scraping product data. Your selector might be correct but you’re only getting the DOM element, not its content. Try modifying your evaluate function to actually extract the text: return document.querySelector('.product-cost')?.textContent; The question mark handles cases where the element doesn’t exist. Also check if the site uses shadow DOM or if the content loads via AJAX calls after page load. Some sites deliberately delay price loading to prevent scraping. You might need to monitor network requests and wait for specific API calls to complete before attempting extraction.

This is a common issue with dynamic content loading. The problem is likely that you’re trying to access the element before the page has fully rendered or before JavaScript has populated the content. I’ve encountered this many times when scraping e-commerce sites.

Try adding a delay or waiting for network activity to settle before extracting the data. You can use await newPage.waitForLoadState('networkidle') or add a simple timeout with await newPage.waitForTimeout(2000). Also, make sure you’re getting the actual text content by using .textContent or .innerText in your querySelector. Sometimes the element exists but the content isn’t there yet, which returns the element object but not the data you need.