Reputation: 1658
Using puppeteer, i open up a page when i enter a value - it outputs the result.
await page.click('button[class="button form-button rs-gcbalance-btn"]')
await page.waitForSelector('div[class="small-4 large-4 rs-gcbalance-result-num-col').catch(err => console.log(err))
await page.evaluate((card) => {
console.log(card + " - " + document.querySelectorAll('div[class="small-4 large-4 rs-gcbalance-result-num-col"]')[1].querySelector('span').innerHTML)
}, card)
But that works correctly only if the value on enter is valid. If it's not, it would throw an error, but without any network activity or load event.
That means, that if the value is incorrect, the element i'm waiting for won't appear and will throw an error, closing the program.
Navigation Timeout Exceeded: 30000ms exceeded
The question is: how to handle the error, so if it throw a timeout error, i can catch it and call another function?
Upvotes: 20
Views: 27845
Reputation: 31
you can use waitForNavigation method after button click and attach a catch block like below to handle navigation timeout error in case value entered is incorrect and navigation does not happens
page.waitForNavigation({waitUntil:"domcontentloaded"}).catch(error => {
// handler code here
});
Upvotes: 3
Reputation: 2194
The try catch
block is a solution.
However, on the accepted answer all errors are silenced!!
You should only catch the Puppeteer TimeOut errors.
try {
await page.waitForSelector('.foo');
} catch (e) {
if (e instanceof puppeteer.errors.TimeoutError) {
// Do something if this is a timeout.
}
}
References: https://devdocs.io/puppeteer/
Upvotes: 22
Reputation:
When i was trying to scrape some pages, i was facing similar issue as default timeout was 30000 ms i.e. 30 seconds and page was taking longer than 30 seconds to load, so basically there was 2 main issues.
here is my final code.
const puppeteer = require('puppeteer');
var mysql = require('mysql');
var mysql_con = mysql.createConnection({
host: "",
user: "",
password: "",
database: ""
});
//connect to mysql
mysql_con.connect(function(err) {
if (err) throw err;
console.log("Connected! to MySQL");
});
(async () => {
const args = [
'--no-sandbox',
'--disable-setuid-sandbox',
'--disable-infobars',
'--window-position=0,0',
'--ignore-certifcate-errors',
'--ignore-certifcate-errors-spki-list',
'--ignoreHTTPSErrors=true',
'--user-agent="Mozilla/5.0 (Linux; Android 6.0.1; Nexus 5X Build/MMB29P) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/W.X.Y.Z‡ Mobile Safari/537.36 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"'
];
const browser = await puppeteer.launch({ args });
const page = await browser.newPage();
// Configure the navigation timeout to 2 minutes, becuase sometimes site is too busy
await page.setDefaultNavigationTimeout(120000);
try {
// Now you can go wherever you want
const response = await page.goto('https://www.example.com/');
//print http status code
console.log(response.status());
//do mysql related stuff here
//close mysql connection
mysql_con.end();
} catch (e) {
console.log('cant load the page, maybe server is busy : ' + e);
//close mysql connection
mysql_con.end();
await browser.close();
//double tap to die script
process.exit();
}
// Then when you're done, just close
await browser.close();
})();
here we fixed 2 issues.
increasing page timeout from 30 seconds default to 2 minutes.
page.setDefaultNavigationTimeout(120000);
Upvotes: 1
Reputation: 9
Try uisng this will slove your problem. page.waitForNavigation( { timeout: 1000, waitUntil: 'domcontentloaded' });
Upvotes: -2
Reputation: 16059
Just wrap it in try catch
block:
try {
await page.waitForSelector('#element', { timeout: 1000 });
// do what you have to do here
} catch (e) {
console.log('element probably not exists');
}
Here is a fully working example:
const puppeteer = require('puppeteer');
const html = `
<html>
<body>
<div id="element">element inner html</div>
</body>
</html>`;
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto(`data:text/html,${html}`);
try {
await page.waitForSelector('#element-not-exists', { timeout: 1000 });
const element = await page.$('#element-not-exists');
console.log(await (await element.getProperty('innerHTML')).jsonValue());
} catch (e) {
console.log('element probably not exists');
}
await browser.close();
})();
Upvotes: 9