我试图点击页面中的多个元素,但前提是它们是可见的。使用硒(使用is_displayed
)非常容易,但我似乎无法在木偶操作中找到方法。
我试图使用像
try {
await page
.waitForSelector(id, visible=true, timeout=0)
.then(() => {
element.click()
});
...
但是,如果它是一个简单的元素,则无效:
<a class="cookie-close" href="#">
OK
</a>
我也似乎无法在puppeteer中使用element.click
方法找到方法。
答案 0 :(得分:0)
与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);
}
答案 1 :(得分:0)
const element = await page.waitForSelector('a.cookie-close', { visible: true });
await element.click();
这使用page.waitForSelector
函数通过选择器a.cookie-close
选择可见元素。查询选择器后,代码使用elementHandle.click
单击它。
只有函数page.waitForSelector
和page.waitForXPath
内置有一个选项,用于检查元素是否不仅存在而且可见。如果使用样式属性visibility
不是hidden
,并且元素具有will check,则使用伪造者visible bounding box。
即使该元素是可见的,它也可能为空(例如<span></span>
)。如果还希望元素也不为空,则可以改用以下查询:
const element = await page.waitForSelector('SELECTOR:not(:empty)', { visible: true });
此外,这还将使用伪选择器:empty
和:not
来确保元素包含子节点或文本。如果要查询元素内的特定文本,则可能要签出this answer。
答案 2 :(得分:0)
这是一种更加惯用的方式,可在单击之前等待元素“显示”。结果应该与@joquarky解释的结果相同:
click() {
let retries = 5;
const hoverAndClick = () => {
return this._element!.hover() // this._element is ElementHandle
.then(() => {
return this._element!.click();
})
.catch(err => {
if (retries <= 0) {
throw err;
}
retries -= 1;
sleep(1000).then(hoverAndClick);
});
};
return hoverAndClick();
}
此处略有不同,是由于元素的任何父元素将其隐藏,因此我们在元素等待转换之前会重试几次。
答案 3 :(得分:-1)
您应该使用page.click()来实现点击。
请参阅Puppeteer的API文档中的page.click(selector,[options]):https://github.com/GoogleChrome/puppeteer/blob/HEAD/docs/api.md#pageclickselector-options
答案 4 :(得分:-1)
不确定它是否是最有效的方式,但你可以尝试这样的事情:
// 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);
}
答案 5 :(得分:-1)
我遇到了同样的问题,并提出了这个解决方案:
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
。
请注意,如果元素被非常规手段隐藏,例如巨大的负边距/填充,这可能无效。