Intermittent Puppeteer crashes with 'Target Close' error during web scraping

I’m having trouble with a Puppeteer script for web scraping. It’s supposed to grab info from a website, go through pages, and print data. But it keeps failing at random spots with a ‘Target Close’ error.

Here’s a simplified version of what I’m trying to do:

const scrape = async () => {
  const browser = await launchBrowser();
  const page = await openNewPage(browser);

  await goToWebsite(page, 'http://example.com');

  for (let i = 1; i <= 50; i++) {
    console.log(`Scraping page ${i}`);
    await getPageData(page);
    await goToNextPage(page);
  }

  await browser.close();
};

scrape().catch(console.error);

The error I’m getting is:

TargetCloseError: Protocol error (DOM.describeNode): Target closed

I’ve tried adding delays and using different Node versions, but no luck. Any ideas on what might be causing this and how to fix it?

I faced similar issues with Puppeteer and found that the ‘Target Close’ error is often linked to intermittent connectivity problems or measures implemented by the website to block automated tools. In my experience, ensuring that each page is fully loaded before proceeding helped improve reliability. I added extra error handling routines and delays to reattempt page interactions when a problem occurred. Running the browser in headful mode instead of headless sometimes avoided abrupt closures. Monitoring the page for crash events and logging detailed information also allowed me to better diagnose and address these issues.

yo, i’ve run into this before. try addin a page.waitForNavigation() after each page load. also, make sure ur not overloading the site - they might be blocking u. maybe add some randomized delays between requests. if that don’t work, try using a proxy or rotating user agents. good luck man!

Have you considered implementing a retry mechanism? In my experience, adding a wrapper function that attempts the operation multiple times can significantly improve reliability. Something like this:

const retry = async (fn, retries = 3, delay = 1000) => {
  try {
    return await fn();
  } catch (err) {
    if (retries <= 0) throw err;
    await new Promise(resolve => setTimeout(resolve, delay));
    return retry(fn, retries - 1, delay);
  }
};

Then wrap your page operations with this retry function. Also, setting a longer timeout for navigation might help:

page.setDefaultNavigationTimeout(60000);

These adjustments have helped me overcome similar issues in my Puppeteer scripts.