在 chrome 开发工具中选择元素之后,Puppeteer 无法使用 xPath contains(text()) 找到元素
Puppeteer unable to find element using xPath contains(text()) until after element has been selected in chrome dev tools
我正在尝试单击 fakebook download your information page 上的“创建文件”按钮。我目前可以转到该页面,并等待登录过程完成。但是,当我尝试使用
检测按钮时
page.$x("//div[contains(text(),'Create File')]")
未找到任何内容。当我试图在 chrome 开发工具控制台中找到它时,同样的事情发生了,无论是在 puppeteer window 中还是在 chrome puppeteer 实例之外的常规 window 中正在控制:
这是元素的 html 信息:
但是在我使用 chrome 开发工具检查器工具单击它之后,我能够找到该元素:
(第二个打印语句是我用元素检查器工具点击它之后的)
我应该如何 select 这个元素? 我是 puppeteer 和 xpath 的新手,如果我错过了一些明显的东西,我深表歉意。
我现在记得以前看过的几个链接:
- puppeteer cannot find element
我的代码:
const StealthPlugin = require("puppeteer-extra-plugin-stealth");
(async () => {
let browser;
try {
puppeteer.use(StealthPlugin());
browser = await puppeteer.launch({
headless: false,
// path: "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe",
args: ["--disable-notifications"],
});
const pages = await browser.pages();
const page = pages[0];
const url = "https://www.facebook.com/dyi?referrer=yfi_settings";
await page.goto(url);
//Handle the login process. Since the login page is different from the url we want, I am going to assume the user
//has logged in if they return to the desired page.
//Wait for the login page to process
await page.waitForFunction(
(args) => {
return window.location.href !== args[0];
},
{ polling: "mutation", timeout: 0 },
[url]
);
//Since multifactor auth can resend the user temporarly to the desired url, use a little debouncing to make sure the user is completely done signing in
// make sure there is no redirect for mfa
await page.waitForFunction(
async (args) => {
// function to make sure there is a debouncing delay between checking the url
// Taken from:
function delay(delayInms) {
return new Promise((resolve) => {
setTimeout(() => {
resolve(2);
}, delayInms);
});
}
if (window.location.href === args[0]) {
await delay(2000);
return window.location.href === args[0];
}
return false;
},
{ polling: "mutation", timeout: 0 },
[url]
);
// await page.waitForRequest(url, { timeout: 100000 });
const requestArchiveXpath = "//div[contains(text(),'Create File')]";
await page.waitForXPath(requestArchiveXpath);
const [requestArchiveSelector] = await page.$x(requestArchiveXpath);
await page.click(requestArchiveSelector);
page.waitForTimeout(3000);
} catch (e) {
console.log("End Error: ", e);
} finally {
if (browser) {
await browser.close();
}
}
})();
@vsemozhebuty 和 使用上面的评论解决了问题。只有 try 中的最后几行必须更改:
const iframeXpath = "//iframe[not(@hidden)]";
const requestArchiveXpath = "//div[contains(text(),'Create File')]";
//Wait for and get iframe
await page.waitForXPath(iframeXpath);
const [iframeHandle] = await page.$x(iframeXpath);
//content frame for iframe => https://devdocs.io/puppeteer/index#elementhandlecontentframe
const frame = await iframeHandle.contentFrame();
//Wait for and get button
await frame.waitForXPath(requestArchiveXpath);
const [requestArchiveSelector] = await frame.$x(requestArchiveXpath);
//click button
await requestArchiveSelector.click();
await page.waitForTimeout(3000);
我正在尝试单击 fakebook download your information page 上的“创建文件”按钮。我目前可以转到该页面,并等待登录过程完成。但是,当我尝试使用
检测按钮时page.$x("//div[contains(text(),'Create File')]")
未找到任何内容。当我试图在 chrome 开发工具控制台中找到它时,同样的事情发生了,无论是在 puppeteer window 中还是在 chrome puppeteer 实例之外的常规 window 中正在控制:
这是元素的 html 信息:
但是在我使用 chrome 开发工具检查器工具单击它之后,我能够找到该元素:
我应该如何 select 这个元素? 我是 puppeteer 和 xpath 的新手,如果我错过了一些明显的东西,我深表歉意。
我现在记得以前看过的几个链接:
- puppeteer cannot find element
我的代码:
const StealthPlugin = require("puppeteer-extra-plugin-stealth");
(async () => {
let browser;
try {
puppeteer.use(StealthPlugin());
browser = await puppeteer.launch({
headless: false,
// path: "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe",
args: ["--disable-notifications"],
});
const pages = await browser.pages();
const page = pages[0];
const url = "https://www.facebook.com/dyi?referrer=yfi_settings";
await page.goto(url);
//Handle the login process. Since the login page is different from the url we want, I am going to assume the user
//has logged in if they return to the desired page.
//Wait for the login page to process
await page.waitForFunction(
(args) => {
return window.location.href !== args[0];
},
{ polling: "mutation", timeout: 0 },
[url]
);
//Since multifactor auth can resend the user temporarly to the desired url, use a little debouncing to make sure the user is completely done signing in
// make sure there is no redirect for mfa
await page.waitForFunction(
async (args) => {
// function to make sure there is a debouncing delay between checking the url
// Taken from:
function delay(delayInms) {
return new Promise((resolve) => {
setTimeout(() => {
resolve(2);
}, delayInms);
});
}
if (window.location.href === args[0]) {
await delay(2000);
return window.location.href === args[0];
}
return false;
},
{ polling: "mutation", timeout: 0 },
[url]
);
// await page.waitForRequest(url, { timeout: 100000 });
const requestArchiveXpath = "//div[contains(text(),'Create File')]";
await page.waitForXPath(requestArchiveXpath);
const [requestArchiveSelector] = await page.$x(requestArchiveXpath);
await page.click(requestArchiveSelector);
page.waitForTimeout(3000);
} catch (e) {
console.log("End Error: ", e);
} finally {
if (browser) {
await browser.close();
}
}
})();
@vsemozhebuty 和
const iframeXpath = "//iframe[not(@hidden)]";
const requestArchiveXpath = "//div[contains(text(),'Create File')]";
//Wait for and get iframe
await page.waitForXPath(iframeXpath);
const [iframeHandle] = await page.$x(iframeXpath);
//content frame for iframe => https://devdocs.io/puppeteer/index#elementhandlecontentframe
const frame = await iframeHandle.contentFrame();
//Wait for and get button
await frame.waitForXPath(requestArchiveXpath);
const [requestArchiveSelector] = await frame.$x(requestArchiveXpath);
//click button
await requestArchiveSelector.click();
await page.waitForTimeout(3000);