Puppeteer page.waitForNavigation() 超时错误处理
Puppeteer page.waitForNavigation() timeout error handling
使用 puppeteer,我在输入值时打开一个页面 - 它输出结果。
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)
但只有当输入的值有效时才能正常工作。如果不是,它会抛出错误,但没有任何网络 activity 或加载事件。
这意味着,如果值不正确,我正在等待的元素将不会出现并将抛出错误,关闭程序。
Navigation Timeout Exceeded: 30000ms exceeded
问题是:如何处理错误,所以如果它抛出超时错误,我可以捕获它并调用另一个函数?
只需将其包装在 try catch
块中:
try {
await page.waitForSelector('#element', { timeout: 1000 });
// do what you have to do here
} catch (e) {
console.log('element probably not exists');
}
这是一个完整的示例:
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();
})();
尝试使用它可以解决您的问题。
page.waitForNavigation({ 超时: 1000, waitUntil: 'domcontentloaded' });
当我试图抓取一些页面时,我遇到了类似的问题,因为默认超时为 30000 毫秒,即 30 秒,页面加载时间超过 30 秒,所以基本上有 2 个主要问题。
- 脚本在 nodejs 抛出后没有被杀死
page.waitForNavigation() 超时错误,所以一直保持 mysql
与服务器的连接处于活动状态并且正在建立新连接
由 cronjob 创建,它们都处于睡眠状态。
- 页面未被抓取,因此需要增加超时时间。
这是我的最终代码。
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();
})();
这里我们解决了 2 个问题。
- 第一个问题是使用 try 和 catch 块并在 catch 块中终止 script/ending mysql 连接。
将页面超时从默认的 30 秒增加到 2 分钟。
page.setDefaultNavigationTimeout(120000);
try catch
块是一个解决方案。
但是,在已接受的答案上 所有错误都已消除!!
您应该只捕获 Puppeteer TimeOut 错误。
try {
await page.waitForSelector('.foo');
} catch (e) {
if (e instanceof puppeteer.errors.TimeoutError) {
// Do something if this is a timeout.
}
}
您可以在单击按钮后使用 waitForNavigation 方法并附加如下所示的 catch 块来处理导航超时错误,以防输入的值不正确并且导航没有发生
page.waitForNavigation({waitUntil:"domcontentloaded"}).catch(error => {
// handler code here
});
使用 puppeteer,我在输入值时打开一个页面 - 它输出结果。
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)
但只有当输入的值有效时才能正常工作。如果不是,它会抛出错误,但没有任何网络 activity 或加载事件。
这意味着,如果值不正确,我正在等待的元素将不会出现并将抛出错误,关闭程序。
Navigation Timeout Exceeded: 30000ms exceeded
问题是:如何处理错误,所以如果它抛出超时错误,我可以捕获它并调用另一个函数?
只需将其包装在 try catch
块中:
try {
await page.waitForSelector('#element', { timeout: 1000 });
// do what you have to do here
} catch (e) {
console.log('element probably not exists');
}
这是一个完整的示例:
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();
})();
尝试使用它可以解决您的问题。 page.waitForNavigation({ 超时: 1000, waitUntil: 'domcontentloaded' });
当我试图抓取一些页面时,我遇到了类似的问题,因为默认超时为 30000 毫秒,即 30 秒,页面加载时间超过 30 秒,所以基本上有 2 个主要问题。
- 脚本在 nodejs 抛出后没有被杀死 page.waitForNavigation() 超时错误,所以一直保持 mysql 与服务器的连接处于活动状态并且正在建立新连接 由 cronjob 创建,它们都处于睡眠状态。
- 页面未被抓取,因此需要增加超时时间。
这是我的最终代码。
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();
})();
这里我们解决了 2 个问题。
- 第一个问题是使用 try 和 catch 块并在 catch 块中终止 script/ending mysql 连接。
将页面超时从默认的 30 秒增加到 2 分钟。
page.setDefaultNavigationTimeout(120000);
try catch
块是一个解决方案。
但是,在已接受的答案上 所有错误都已消除!!
您应该只捕获 Puppeteer TimeOut 错误。
try {
await page.waitForSelector('.foo');
} catch (e) {
if (e instanceof puppeteer.errors.TimeoutError) {
// Do something if this is a timeout.
}
}
您可以在单击按钮后使用 waitForNavigation 方法并附加如下所示的 catch 块来处理导航超时错误,以防输入的值不正确并且导航没有发生
page.waitForNavigation({waitUntil:"domcontentloaded"}).catch(error => {
// handler code here
});