我需要等到新页面加载完毕,点击按钮后在新标签页中打开。也就是说,我点击一个按钮,一个新页面打开(应该加载),然后我点击另一个按钮。我有一些示例代码,但由于某种原因它不起作用:
const page = await browser.newPage();
await page.goto('https://twitter.com/amazon/');
await page.click('.css-1dbjc4n:nth-child(1) > .css-1dbjc4n > .css-1dbjc4n > .css-901oao > .css-4rbku5',{waitUntil: ['load', 'domcontentloaded', 'networkidle0', 'networkidle2']});
const page2 = (await browser.pages())[2];
await page2.click('#nav-main > .nav-fill > #nav-xshop-container > #nav-xshop > .nav-a:nth-child(2)');
答案 0 :(得分:0)
如果我理解正确,问题是检测新标签(“页面”)何时打开并获取与标签关联的新页面对象。
至少有几种可用的技术。一种方法是承诺浏览器的 "targetcreated"
事件,如here 所述:
const puppeteer = require("puppeteer");
(async () => {
const browser = await puppeteer.launch({headless: false});
const [page] = await browser.pages();
await page.goto("https://twitter.com/amazon");
const amzSel = `.css-1dbjc4n:nth-child(1) > .css-1dbjc4n >
.css-1dbjc4n > .css-901oao > .css-4rbku5`;
await page.waitForSelector(amzSel, {visible: true});
console.log((await browser.pages()).length); // => 1
// method 1
const newPagePromise = new Promise(resolve =>
browser.once("targetcreated", target => resolve(target.page()))
);
await page.click(amzSel);
const newPage = await newPagePromise;
// --------
console.log((await browser.pages()).length); // => 2
await newPage.waitForSelector("#nav-link-prime", {visible: true});
await newPage.click("#nav-link-prime");
const sel = "#prime-header-CTA-announce";
await newPage.waitForSelector(sel, {visible: true});
console.log(await newPage.$eval(sel, el => el.innerText.trim())); // => TRY PRIME
//await browser.close();
})();
另一种方法是使用browser.waitForTarget
来检查目标的opener()
何时是上一页目标,如here所述:
const puppeteer = require("puppeteer");
(async () => {
const browser = await puppeteer.launch({headless: false});
const [page] = await browser.pages();
await page.goto("https://twitter.com/amazon");
const amzSel = `.css-1dbjc4n:nth-child(1) > .css-1dbjc4n >
.css-1dbjc4n > .css-901oao > .css-4rbku5`;
await page.waitForSelector(amzSel, {visible: true});
console.log((await browser.pages()).length); // => 1
// method 2
const pageTarget = page.target();
await page.click(amzSel);
const newTarget = await browser.waitForTarget(target =>
target.opener() === pageTarget
);
const newPage = await newTarget.page();
// --------
console.log((await browser.pages()).length); // => 2
await newPage.waitForSelector("#nav-link-prime", {visible: true});
await newPage.click("#nav-link-prime");
const sel = "#prime-header-CTA-announce";
await newPage.waitForSelector(sel, {visible: true});
console.log(await newPage.$eval(sel, el => el.innerText.trim())); // => TRY PRIME
//await browser.close();
})();
顺便说一句,我不确定这个特定的 Twitter/Amazon 示例有多重要/重要,但 #nav-xshop > .nav-a:nth-child(2)
似乎不是一个可靠的选择器(它似乎在“Best Sellers " 和 "Prime")--我会使用 #nav-link-prime
,因为它是一个直接 ID,如果这是您要查找的内容。