一个非常简单的问题。
在某些情况下,我的网络应用会打开一个新标签页。
但是当我尝试获取所有标签(await browser.pages())
时,我只返回一个初始页面。
如何在我的代码中获取新页面的对象?
当您没有使用await browser.newPage()
的木偶操纵者创建新标签时会发生这种情况,但是当您执行以下操作时:
await (await browser.pages())[0].evaluate(() => {
window.open('http://www.example.com', '_blank');
});
该页面在browser.pages()
回复中无法使用。
谢谢!
答案 0 :(得分:3)
当应用程序打开新标签页时,如果没有了解您的条件,那就太难了。它对我来说非常好。这是一个代码,演示了如何使用它。阅读评论以了解相关步骤。
<强>更新:强>
window.open()
不会返回承诺,因此browser.pages()的执行速度比浏览器创建和报告事件的速度快。我们可以使用targetcreated
事件来了解是否创建了任何新标签。
browser.on('targetcreated', function(){
console.log('New Tab Created');
})
如果您等待一段时间或退回承诺,您会看到它在browser.pages()
次内报告。
await tabOne.evaluate(() => {
window.open('http://www.example.com', '_blank');
});
await tabOne.waitFor(2000); // await for a while
console.log("current page count ", (await browser.pages()).length); // 3
这是最终的代码。
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
browser.on('targetcreated', function(){
console.log('New Tab Created');
})
// get current tab count
console.log("current page count ", (await browser.pages()).length); // 3
// create a new tab
await browser.newPage();
// lets see if tab increased
console.log("current page count ", (await browser.pages()).length); // 3
// use destructuring for easier usage
const [tabOne, tabTwo] = (await browser.pages());
// use the tabs aka Page objects properly
await tabOne.goto('https://example.com');
console.log("Tab One Title ",await tabOne.title()); // Example Domain
// use the tabs aka Page objects properly
await tabTwo.goto('https://example.com');
console.log("Tab Two Title ",await tabTwo.title()); // Example Domain
await tabOne.evaluate(() => {
window.open('http://www.example.com', '_blank');
});
await tabOne.waitFor(2000); // wait for a while
console.log("current page count ", (await browser.pages()).length); // 3
// close the browser
await browser.close();
})();
如果你运行它,你将按以下顺序得到结果。
/*
current page count 1
New Tab Created
current page count 2
Tab One Title Example Domain
Tab Two Title Example Domain
New Tab Created
current page count 3
*/
答案 1 :(得分:3)
如果通过单击原始页面中的链接打开了此代码,则该代码将在新标签页中捕获新页面。
//save target of original page to know that this was the opener:
const pageTarget = page.target();
//execute click on first tab that triggers opening of new tab:
await page.click('#selector');
//check that the first page opened this new page:
const newTarget = await browser.waitForTarget(target => target.opener() === pageTarget);
//get the new page object:
const newPage = await newTarget.page();
答案 2 :(得分:0)
this (perfectly fine!) approach 的替代方法是承诺浏览器的 "targetcreated"
事件,如对 Puppeteer issue #386 的评论中所述:
const puppeteer = require("puppeteer");
const { once } = require('events');
(async () => {
const html = `<a href="https://news.ycombinator.com" target="_blank">click</a>`;
const browser = await puppeteer.launch({headless: false});
const [page] = await browser.pages();
await page.setContent(html);
await page.waitForSelector("a", {visible: true});
console.log((await browser.pages()).length); // => 1
const newPagePromise = once("targetcreated", browser).then(x => x.page());
await page.click("a");
const newPage = await newPagePromise;
console.log((await browser.pages()).length); // => 2
console.log((await newPage.content()));
await browser.close();
})();
另一种写法是使用 Promise.all
和一个解构赋值来从结果数组中获取第一个元素:
const [newPage] = await Promise.all([
once(browser, "targetcreated").then(x => x.page),
page.click("a")
]);