先必读一个链接 www.tools4testing.com/contents/pu…
澄清几个问题
page.waitForSelector(
selector: string,
options ?: WaitForSelectorOptions,
): Promise<ElementHandle>;
- page.waitForSelector method returns the promise with the element handle which is represented by the selector expression and null if element is not found after timeout, hence it is always better to use
方法返回的是一个promise。显然,不然的话没有必要await,promise就是一个特殊的object而已,内部有自己的状态,注意跟函数区分开来噢。
options:{
visible: true , //包括display:none和visibility:hidden (这个也需要注意一下,详解下)
timeout: 30000 //默认超时30s
}
promise有结果后,返回两种情况,注意(非常重要)
A)如果在超时时间内,找到了元素,皆大欢喜,resolve为element!
B) 如果超时没有找到,怎么办?? 注意了!!这里会reject一个error!你需要catch一下噢
【偷偷说下,这里测试try-puppeteer.appspot.com/】
客官会问,Frank你激动什么啊,那么多感叹号干嘛?很正常啊,如果超时找不到,当然要throw了。其实不然,超时找不到不一定要throw噢!比如:超时找不到我可以resolve(false||null)啊。你要说,显然不是专业程序员做法吧。事实上,之前版本的pptr确实是这样的,不信看这里 github.com/johntitus/n…
客官又会问,这点小事情,你到底想说什么?
其实我想说,怎么解决下面这个问题:
假设我pptr访问一个网页(page),这个网页上可能会出现多个情况(dynamic页面很流行):
比如页面上面的一个按钮(btn)有可能会出现,也可能压根不会出现;
但是:
但是:
但是:
我的需求是:如果这个按钮出现我就点击,如果不出现,我也无所谓。比如这个按钮是个
遮罩,挡住了我的页面视线,如果出现我就点掉它,不出现更好。
请,仔细理解下我的需求!
【专业】程序员做法:
try{
await page.waitForSelector('btn',{visible:true,timemout:"很长时间"});
await page.click('btn');
}catch(e){
//压制error继续剩下代码,不阻止执行
//我不需要知道错误信息,不出现btn就拉倒。
}
这个做法是可以。但是,如果页面上有很多这种情况呢?能否有一个懒人的做法,不管三七二十八,我也不管什么try catch,写个函数套进去一了百了。比如:
async function findAndClick (page, selector, timeout){
try{
await page.waitForSelector(selector,{visible:true,timemout});
await page.click('btn');
}catch(e){
console.log('Sorry selecotor '+selector+' does not exist after '+timeout);
}
}
或者为了简化书写,方便逻辑判断:(本身已经是promise,没有必要再套上一层,除非是callback)
async function findElement (page, selector, {timeout, visible}){
return new Promise((resolve, reject)=>{
page.waitForSelector(selector,{visible,timeout}).then(e=>resolve(e)).catch(e=>{
console.log('Sorry selecotor '+selector+' does not exist after '+timeout);
resolve(null); //注意这里不是reject,要火力压制错误。见下面例子。
})
})
}
或者更简单一些:
async function findElement (page, selector, {timeout, visible}){
let el;
try{
el=await page.waitForSelector(selector,{visible,timeout});
}catch(e){
console.log('Sorry selecotor '+selector+' does not exist after '+timeout);
//什么都不做,就是为了火力压制,气死你~~
el= Promise.resolve(null);
}
return el;
}
const el= await findElement(page, "div", { //这里依然需要await一些,因为await返回promise永远还是promise
timeout: 400,
visible: true,
})
console.log(!!el);
-
visible很重要;别忘了要设置,不容易出错。
-
visible的input没有出现在页面上,无法有page.type这个输入方法的!!因为不展示就能输入文字。需要这样办:
await page.$eval(
"#g_recaptcha_response",
(el, value) => (el.value = value),
text //这里是传输的输入文字
);