Viv*_*ipo 29 javascript node.js google-chrome-devtools puppeteer
我想知道我是否可以告诉木偶操作员等到显示的元素.
const inputValidate = await page.$('input[value=validate]');
await inputValidate.click()
//I want to do something like that
waitElemenentVisble('.btnNext ')
const btnNext = await page.$('.btnNext');
await btnNext.click();
Run Code Online (Sandbox Code Playgroud)
有什么方法可以做到这一点吗?
tur*_*uka 32
我认为你可以page.waitForSelector(selector[, options])为此目的使用功能.
const puppeteer = require('puppeteer');
puppeteer.launch().then(async browser => {
const page = await browser.newPage();
page
.waitForSelector('#myId')
.then(() => console.log('got it');
browser.close();
});
Run Code Online (Sandbox Code Playgroud)
fin*_*inn 18
如果要确保元素实际可见,则必须使用
page.waitForSelector('#myId', {visible: true})
Run Code Online (Sandbox Code Playgroud)
否则,您只是在DOM中寻找元素,而不在检查可见性。
eww*_*ink 17
注意,以上所有答案均不正确!
因为它回答一个元素,如果存在或位于 but NOT 可见或显示
正确的答案是使用page.waitFor()或检查元素的大小或可见性page.waitForFunction(),请参见下面的说明。
// wait until present on the DOM
// await page.waitForSelector( css_selector );
// wait until "display"-ed
await page.waitForFunction("document.querySelector('.btnNext') && document.querySelector('.btnNext').clientHeight != 0");
// or wait until "visibility" not hidden
await page.waitForFunction("document.querySelector('.btnNext') && document.querySelector('.btnNext').style.visibility != 'hidden'");
const btnNext = await page.$('.btnNext');
await btnNext.click();
Run Code Online (Sandbox Code Playgroud)
如果具有CSS属性,则页面DOM上存在的元素并不总是可见的,display:none或者visibility:hidden为什么使用page.waitForSelector(selector)不是一个好主意,让我们在下面的代码片段中看到不同的内容。
// wait until present on the DOM
// await page.waitForSelector( css_selector );
// wait until "display"-ed
await page.waitForFunction("document.querySelector('.btnNext') && document.querySelector('.btnNext').clientHeight != 0");
// or wait until "visibility" not hidden
await page.waitForFunction("document.querySelector('.btnNext') && document.querySelector('.btnNext').style.visibility != 'hidden'");
const btnNext = await page.$('.btnNext');
await btnNext.click();
Run Code Online (Sandbox Code Playgroud)
function isExist(selector) {
let el = document.querySelector(selector);
let exist = el.length != 0 ? 'Exist!' : 'Not Exist!';
console.log(selector + ' is ' + exist)
}
function isVisible(selector) {
let el = document.querySelector(selector).clientHeight;
let visible = el != 0 ? 'Visible, ' + el : 'Not Visible, ' + el;
console.log(selector + ' is ' + visible + 'px')
}
isExist('#idA');
isVisible('#idA');
console.log('=============================')
isExist('#idB')
isVisible('#idB')Run Code Online (Sandbox Code Playgroud)
.bd {border: solid 2px blue;}Run Code Online (Sandbox Code Playgroud)
在上面的代码片段上,isExist()模拟
page.waitForSelector('#myId');
Run Code Online (Sandbox Code Playgroud)
我们可以看到,同时运行isExist()两个元素#idA的#idB是回报存在。
但是在运行时isVisible(), #idA看不见或布局。
这里还有其他对象来检查元素是否显示或使用CSS属性display。
scrollWidth
scrollHeight
offsetTop
offsetWidth
offsetHeight
offsetLeft
clientWidth
clientHeight
Run Code Online (Sandbox Code Playgroud)
visibility用not 进行样式检查hidden。
注意:我的Java语言或英语不佳,请随时改善此答案。
lus*_*chn 11
更新了一些优化的答案:
const puppeteer = require('puppeteer');
(async() => {
const browser = await puppeteer.launch({headless: true});
const page = await browser.newPage();
await page.goto('https://www.somedomain.com', {waitUntil: 'networkidle2'});
await page.click('input[value=validate]');
await page.waitForSelector('#myId');
await page.click('.btnNext');
console.log('got it');
browser.close();
})();
Run Code Online (Sandbox Code Playgroud)
您可以使用page.waitFor(),, page.waitForSelector()或page.waitForXPath()等待页面上的元素:
// Selectors
const css_selector = '.btnNext';
const xpath_selector = '//*[contains(concat(" ", normalize-space(@class), " "), " btnNext ")]';
// Wait for CSS Selector
await page.waitFor( css_selector );
await page.waitForSelector( css_selector );
// Wait for XPath Selector
await page.waitFor( xpath_selector );
await page.waitForXPath( xpath_selector );
Run Code Online (Sandbox Code Playgroud)
注:在参照框架,你也可以使用
frame.waitFor(),frame.waitForSelector()或frame.waitForXPath().
虽然我同意@ewwink 的回答。Puppeteer 的 API 默认检查未隐藏,因此当您执行以下操作时:
await page.waitForSelector('#id', {visible: true})
Run Code Online (Sandbox Code Playgroud)
你不会被 CSS 隐藏和可见。为了确保渲染,您可以像@ewwink 的waitForFunction. 但是,要完全回答您的问题,这里有一个使用 puppeteer 的 API 的片段:
async waitElemenentVisble(selector) {
function waitVisible(selector) {
function hasVisibleBoundingBox(element) {
const rect = element.getBoundingClientRect()
return !!(rect.top || rect.bottom || rect.width || rect.height)
}
const elements = [document.querySelectorAll(selector)].filter(hasVisibleBoundingBox)
return elements[0]
}
await page.waitForFunction(waitVisible, {visible: true}, selector)
const jsHandle = await page.evaluateHandle(waitVisible, selector)
return jsHandle.asElement()
}
Run Code Online (Sandbox Code Playgroud)
在我自己写了一些这样的方法之后,我发现expect- puppeteer可以做到这一点并且做得更好(参见toMatchElement)。
| 归档时间: |
|
| 查看次数: |
30574 次 |
| 最近记录: |