How to get puppeteer to simply load a web page?

Viewed 1951

I can't get puppeteer to do anything. I'm simply trying to get it to show google.com and I can't even get it to do that. Here's my code:

console.log('Loading puppeteer...');
const puppeteer = require('puppeteer');

async function test() {
    console.log('Launching browser...');
    const browser = await puppeteer.launch({headless: false});
  
    console.log('Creating new page...');
    const page = await browser.newPage();
    
    console.log('Requesting url...');
    await page.goto('https://www.google.com');

    console.log('Closing browser...');
    await browser.close();
}

test().catch(e=>{console.log(e)});

Chromium crashes every single time I try do do anything...

Chromium Crashes

Then I get a timeout error:

Loading puppeteer...
Launching browser...
TimeoutError: waiting for target failed: timeout 30000ms exceeded
...
...

I've been searching for a solution for literally weeks. Does this thing just not work anymore?

2 Answers

After looking at this thread, which identifies this as a well-known issue with Puppeteer, here is some more information on Puppeteer timeout problems.

Puppeteer.launch() has two parts that can cause timeout problems. One is goto timing out, and the other is waitfor timing out. Since I don't know what could be causing your specific issue, I'll give you potential solutions for both.

Possible issue #1: Goto is timing out.

I'll directly quote the person who posted this solution, rudiedirkx:

In my case the goto timeout happens because of a forever-loading blocking resource (js or css). That'll never trigger the page's load or domcontentloaded. A bug in Puppeteer IMO, but whatever.

My fix (FINALLY!) is to do what Lighthouse does in its Driver: a Promise.race() for a custom 'timeout'-ish. The shorter version I used:

    const LOAD_FAIL = Math.random();
const sleep = options => new Promise(resolve => {
    options.timer = setTimeout(resolve, options.ms, options.result === undefined ? true : options.result);
});

const sleepOptions = {ms: TIMEOUT - 1000, result: LOAD_FAIL};
const response = await Promise.race([
    sleep(sleepOptions),
    page.goto(url, {timeout: TIMEOUT + 1000}),
]);
clearTimeout(sleepOptions.timer);
const success = response !== LOAD_FAIL;

Possible issue #2: Waitfor is timing out.

Alternatively you can try the solution to a waitfor timeout given by dealeros, adding --enable-blink-features=HTMLImports in args:

browser = await puppeteer.launch({
        //headless: false,
        'args': [
            '--enable-blink-features=HTMLImports'
        ]
    });

If neither of those worked

If neither of these solutions work, I recommend browsing that thread to find more solutions people have suggested and see if you can narrow down the problem. Use this code to generate some console logs and see if you can find what's going wrong:

page
    .on('console', message =>
    console.log(`${message.type().substr(0, 3).toUpperCase()} ${message.text()}`))
    .on('pageerror', ({ message }) => console.log(message))
    .on('response', response =>
    console.log(`${response.status()} ${response.url()}`))
    .on('requestfailed', request =>
    console.log(`${request.failure().errorText} ${request.url()}`));

These options both resolved the issue for me:

  1. Kill all Chromium processes

    • pkill -o chromium
  2. Reinstall node packages (if step 1 doesn't help)

    1. rm -rf node_modules
    2. npm install
Related