我试图单击页面中的多个元素,但仅在它们可见时才会出现。这很容易使用硒(使用is_displayed
),但我似乎无法在木偶戏中找到方法。我试图用类似的东西
try {
await page
.waitForSelector(id, visible=true, timeout=0)
.then(() => {
element.click()
});
...
但如果它是一个简单的元素,这不起作用:
<a class="cookie-close" href="#">
OK
</a>
我也似乎无法在puppeteer中使用element.click
方法看到这样做的方法。
与Selenium类似,正确的答案是使用Puppeteer的waitForSelector,它可以测试DOM元素的存在和可见性。
try {
// Will throw err if element is not present and visible.
await chromePage.waitForSelector("div.hello", {
visible: true
});
await chromePage.click("div.hello");
} catch(err) {
console.log(err);
}
const element = await page.waitForSelector('a.cookie-close', { visible: true });
await element.click();
这使用page.waitForSelector
函数用选择器a.cookie-close
选择可见元素。查询选择器后,代码使用elementHandle.click
单击它。
只有函数page.waitForSelector
和page.waitForXPath
内置了一个选项,用于检查元素是否不仅存在而且是可见的。使用时,如果风格属性will check不是visibility
并且元素有hidden
,则使用puppeteer visible bounding box。
即使该元素是可见的,它也可能是空的(例如<span></span>
)。如果您还希望元素也不为空,则可以使用以下查询:
const element = await page.waitForSelector('SELECTOR:not(:empty)', { visible: true });
此外,还将使用伪选择器:empty
和:not
来确保元素包含子节点或文本。如果要查询元素内的特定文本,可能需要查看this answer。
您应该使用page.click()来实现点击。
请参阅Puppeteer的API文档中的page.click(selector,[options]):https://github.com/GoogleChrome/puppeteer/blob/HEAD/docs/api.md#pageclickselector-options
不确定这是否是最有效的方法,但你可以尝试这样的事情:
// returns null if element not present
let element = await page.evaluate(() => {
return document.querySelector(id);
});
// use jQuery to check if element is not hidden
if (element && !$(element).is(':hidden') {
await page.click(id);
}
我遇到了同样的问题,并提出了这个解决方案:
await page.waitForSelector('#clickable');
await page.evaluate(() => {
let el = document.querySelector('#clickable');
if (isVisible(el)) {
el.click();
return true;
}
return false;
function isVisible(el) {
if (el.offsetParent === null && el !== document.body) {
return false; // not connected to document
}
if (el.offsetWidth <= 0 || el.offsetHeight <= 0) {
return false; // no width or height
}
let style = el.style;
if (style.display === "none" || style.visibility === "hidden" || style.opacity === "0") {
return false; // has a 'hidey' css attribute
}
if (el === document.body) {
return true;
}
return isVisible(el.offsetParent);
}
});
这将检查元素是否实际附加到文档,它至少具有一些宽度和高度,并且元素或其任何祖先都被CSS样式display:none
,visibility:hidden
或opacity:0
隐藏。
请注意,如果元素被非常规方法隐藏,例如巨大的负边距/填充,则这可能不起作用。