Puppeteer 关闭 javascript 警报框
Puppeteer close javascript alert box
我想点击 this website 上的页面按钮,但是当我进入该站点时,会出现一个警告框,我不知道如何关闭它。
我刚开始尝试 Puppeteer,这是我现在使用的简单代码:
const ptr = require('puppeteer');
ptr.launch().then(async browser => {
const page = await browser.newPage();
await page.setViewport({ width: 1280, height: 800 });
await page.goto('https://portaleperiti.grupporealemutua.it/PPVET/VetrinaWebPortalePeriti/');
//This is the alert button selector
await page.click("#BoxAlertBtnOk");
//This is the button on the page i want to click on
await page.click("input[value='Perito RE / G.F.']");
await page.screenshot({
path: 'screenshot.png',
fullPage: true
});
await browser.close();
});
这是我得到的错误:UnhandledPromiseRejectionWarning:错误:节点不可见或不是 HTMLElement
在 ElementHandle._clickablePoint
非常感谢任何帮助,谢谢!
您的按钮 - #BoxAlertBtnOk
稍后会出现在网页上,当您调用 await page.click("#BoxAlertBtnOk");
时,该按钮是不可见的。尝试等到它可见后再采取行动:
await page.waitForSelector("#BoxAlertBtnOk");
await page.click("#BoxAlertBtnOk");
await page.waitForSelector("input[value='Perito RE / G.F.']");
await page.click("input[value='Perito RE / G.F.']");
该页面上的内容很少,
- 警告框仅在页面加载后加载(它在
body
标签上有一个 onload
属性)。所以你应该等到网络空闲。
- 单击那些 "Perito" 按钮会创建一个新的 window/tab,因为
window.open()
代码已放入 onclick
处理程序。
- 如果用户尚未登录,新选项卡会重定向多次并显示登录页面。
解决方案:
1。确保正确加载页面。
只需将 { waitUntil: "networkidle0" }
添加到 .goto
或 .waitForNavigation
。
await page.goto(
"https://portaleperiti.grupporealemutua.it/PPVET/VetrinaWebPortalePeriti/",
{ waitUntil: "networkidle0" }
// <-- Make sure the whole page is completely loaded
);
2。等待元素再点击
已在其他答案中提出建议,请等待使用 waitFor
的元素。
// wait and click the alert button
await page.waitFor("#BoxAlertBtnOk");
await page.click("#BoxAlertBtnOk");
3。可选,点击按钮后在截图之前添加几秒钟。
// optional, add few seconds before taking this screenshot
// just to make sure it works even on slow machine
await page.waitFor(2000);
await page.screenshot({
path: "screenshot_before.png",
fullPage: true
});
4。使用 page.evaluate
和 document.querySelector
获取元素
page.click
不会处理所有类型的点击。有时会有不同的事件绑定到某些元素,您必须分别对待。
// we can click using querySelector and the native
// just page.click does not trigger the onclick handler on this page
await page.evaluate(() =>
document.querySelector("input[value='Perito RE / G.F.']").click()
);
5。单独对待新标签
与 browser.once('targetcreated')
、new Promise
和 browser.pages()
一起,您可以捕获新创建的选项卡并对其进行处理。
注意:使用前阅读答案末尾的最终代码。
// this is the final page after clicking the input on previous page
// https://italy.grupporealemutua.it/FIM/sps/IDPRMA/saml20/login
function newTabCatcher(browser) {
// we resolve this promise after doing everything we need to do on this page
// or in error
return new Promise((resolve, reject) => {
// set the listener before clicking the button to have proper interaction
// we listen for only one new tab
browser.once("targetcreated", async function() {
console.log("New Tab Created");
try {
// get the newly created window
const tabs = await browser.pages();
const lastTab = tabs[tabs.length - 1];
// Wait for navigation to finish as well as specific login form
await Promise.all([
lastTab.waitForNavigation({ waitUntil: "networkidle0" }),
lastTab.waitFor("#div_login")
]);
// browser will switch to this tab just when it takes the screenshot
await lastTab.screenshot({
path: "screenshot_newtab.png",
fullPage: true
});
resolve(true);
} catch (error) {
reject(error);
}
});
});
}
最终代码:
为清楚起见,以下是我如何使用上面指定的所有代码片段。
const ptr = require("puppeteer");
ptr.launch({ headless: false }).then(async browser => {
const page = await browser.newPage();
await page.setViewport({ width: 1280, height: 800 });
await page.goto(
"https://portaleperiti.grupporealemutua.it/PPVET/VetrinaWebPortalePeriti/",
{ waitUntil: "networkidle0" }
// <-- Make sure the whole page is completely loaded
);
// wait and click the alert button
await page.waitFor("#BoxAlertBtnOk");
await page.click("#BoxAlertBtnOk");
// optional, add few seconds before taking this screenshot
// just to make sure it works even on slow machine
await page.waitFor(2000);
await page.screenshot({
path: "screenshot_before.png",
fullPage: true
});
// we can click using querySelector and the native
// just page.click does not trigger the onclick handler on this page
await page.evaluate(() =>
document.querySelector("input[value='Perito RE / G.F.']").click()
);
// here we go and process the new tab
// aka get screenshot, fill form etc
await newTabCatcher(browser);
// rest of your code
// ...
await browser.close();
});
结果:
它完美地工作了!
注:
注意我是如何同时使用新的 Promise 和 async await 的。这可能不是最佳做法,但现在您可以了解在为一些旧网站创建抓取工具时要寻找的内容。
如果它与面对对话框的任何其他人相关,以下代码为我解决了它:
this.page.on('dialog', async dialog => {
await dialog.dismiss();
});
我想点击 this website 上的页面按钮,但是当我进入该站点时,会出现一个警告框,我不知道如何关闭它。
我刚开始尝试 Puppeteer,这是我现在使用的简单代码:
const ptr = require('puppeteer');
ptr.launch().then(async browser => {
const page = await browser.newPage();
await page.setViewport({ width: 1280, height: 800 });
await page.goto('https://portaleperiti.grupporealemutua.it/PPVET/VetrinaWebPortalePeriti/');
//This is the alert button selector
await page.click("#BoxAlertBtnOk");
//This is the button on the page i want to click on
await page.click("input[value='Perito RE / G.F.']");
await page.screenshot({
path: 'screenshot.png',
fullPage: true
});
await browser.close();
});
这是我得到的错误:UnhandledPromiseRejectionWarning:错误:节点不可见或不是 HTMLElement 在 ElementHandle._clickablePoint
非常感谢任何帮助,谢谢!
您的按钮 - #BoxAlertBtnOk
稍后会出现在网页上,当您调用 await page.click("#BoxAlertBtnOk");
时,该按钮是不可见的。尝试等到它可见后再采取行动:
await page.waitForSelector("#BoxAlertBtnOk");
await page.click("#BoxAlertBtnOk");
await page.waitForSelector("input[value='Perito RE / G.F.']");
await page.click("input[value='Perito RE / G.F.']");
该页面上的内容很少,
- 警告框仅在页面加载后加载(它在
body
标签上有一个onload
属性)。所以你应该等到网络空闲。 - 单击那些 "Perito" 按钮会创建一个新的 window/tab,因为
window.open()
代码已放入onclick
处理程序。 - 如果用户尚未登录,新选项卡会重定向多次并显示登录页面。
解决方案:
1。确保正确加载页面。
只需将 { waitUntil: "networkidle0" }
添加到 .goto
或 .waitForNavigation
。
await page.goto(
"https://portaleperiti.grupporealemutua.it/PPVET/VetrinaWebPortalePeriti/",
{ waitUntil: "networkidle0" }
// <-- Make sure the whole page is completely loaded
);
2。等待元素再点击
已在其他答案中提出建议,请等待使用 waitFor
的元素。
// wait and click the alert button
await page.waitFor("#BoxAlertBtnOk");
await page.click("#BoxAlertBtnOk");
3。可选,点击按钮后在截图之前添加几秒钟。
// optional, add few seconds before taking this screenshot
// just to make sure it works even on slow machine
await page.waitFor(2000);
await page.screenshot({
path: "screenshot_before.png",
fullPage: true
});
4。使用 page.evaluate
和 document.querySelector
获取元素
page.click
不会处理所有类型的点击。有时会有不同的事件绑定到某些元素,您必须分别对待。
// we can click using querySelector and the native
// just page.click does not trigger the onclick handler on this page
await page.evaluate(() =>
document.querySelector("input[value='Perito RE / G.F.']").click()
);
5。单独对待新标签
与 browser.once('targetcreated')
、new Promise
和 browser.pages()
一起,您可以捕获新创建的选项卡并对其进行处理。
注意:使用前阅读答案末尾的最终代码。
// this is the final page after clicking the input on previous page
// https://italy.grupporealemutua.it/FIM/sps/IDPRMA/saml20/login
function newTabCatcher(browser) {
// we resolve this promise after doing everything we need to do on this page
// or in error
return new Promise((resolve, reject) => {
// set the listener before clicking the button to have proper interaction
// we listen for only one new tab
browser.once("targetcreated", async function() {
console.log("New Tab Created");
try {
// get the newly created window
const tabs = await browser.pages();
const lastTab = tabs[tabs.length - 1];
// Wait for navigation to finish as well as specific login form
await Promise.all([
lastTab.waitForNavigation({ waitUntil: "networkidle0" }),
lastTab.waitFor("#div_login")
]);
// browser will switch to this tab just when it takes the screenshot
await lastTab.screenshot({
path: "screenshot_newtab.png",
fullPage: true
});
resolve(true);
} catch (error) {
reject(error);
}
});
});
}
最终代码:
为清楚起见,以下是我如何使用上面指定的所有代码片段。
const ptr = require("puppeteer");
ptr.launch({ headless: false }).then(async browser => {
const page = await browser.newPage();
await page.setViewport({ width: 1280, height: 800 });
await page.goto(
"https://portaleperiti.grupporealemutua.it/PPVET/VetrinaWebPortalePeriti/",
{ waitUntil: "networkidle0" }
// <-- Make sure the whole page is completely loaded
);
// wait and click the alert button
await page.waitFor("#BoxAlertBtnOk");
await page.click("#BoxAlertBtnOk");
// optional, add few seconds before taking this screenshot
// just to make sure it works even on slow machine
await page.waitFor(2000);
await page.screenshot({
path: "screenshot_before.png",
fullPage: true
});
// we can click using querySelector and the native
// just page.click does not trigger the onclick handler on this page
await page.evaluate(() =>
document.querySelector("input[value='Perito RE / G.F.']").click()
);
// here we go and process the new tab
// aka get screenshot, fill form etc
await newTabCatcher(browser);
// rest of your code
// ...
await browser.close();
});
结果:
它完美地工作了!
注:
注意我是如何同时使用新的 Promise 和 async await 的。这可能不是最佳做法,但现在您可以了解在为一些旧网站创建抓取工具时要寻找的内容。
如果它与面对对话框的任何其他人相关,以下代码为我解决了它:
this.page.on('dialog', async dialog => {
await dialog.dismiss();
});