> 使用selenium时会遇到很多的坑,这里分享一些经验给大家。
[TOC]
#### 1.wait ~ until的使用
> 要勤使用wait~until,由于我们打开的网页有时候会比较慢时,查找调用某个元素时就比较容易报NoSuchElementException异常。或者有时候一些JS是动态生成的,也需要用到wait~until,不然也会报错。
#### 2.switchToEndWindow勤使用
> switchToEndWindow是我们自定义的一个方法,由于我们使用selenium访问某个网页,然后又点击了其中一个链接,谁知道这个链接是否含有target="_blank"呢。做爬虫类程序尤为如此。所以我们增加一个方法,每次点击了某个链接跳转后,执行一下switchToEndWindow方法。
~~~
<?php
//切换至最后一个window
function switchToEndWindow($driver){
$arr = $driver->getWindowHandles();
foreach ($arr as $k=>$v){
if($k == (count($arr)-1)){
$driver->switchTo()->window($v);
}
}
}
?>
~~~
#### 3.异常处理
> 使用selenium过程中,会碰到各种意想不到的报错。比如做爬虫过程中,都要用try包含起来处理异常,这样可以防止一旦异常报错后,终止了程序的执行。那么在测试的每个节点的健康状态,可在数据库中记录查询。
#### 4.定位异常解决
> 元素在网页第一次加载后,就会确定他的坐标,当我们进行了某种操作,改变了宽度或高度,则很容易引起相关元素的坐标改变,从而报错。
> 报错信息:Element is not clickable at point (284, 11).
> 解决保存就是在调用click或submit方式之前先调用sendKeys方法,让其重绘坐标
~~~
$elemA->sendKeys('xxx')->click();
$elemB->sendKeys('xxx')->submit();
~~~
> 有时候,以上使用sendKeys方式还是没办法解决问题时,则很可能是因为网页中含有浮动DIV,导致各个元素定位变化了。
> 这个时候只需要找到那个浮动的DIV,隐藏掉就可以了。
~~~
$js = <<<js
var nav = document.getElementsByClassName("nav_m");
nav[0].style.display = 'none';
js;
$driver->executeScript($js);
~~~
>如果以上两种方式结合都还有问题的情况下,就建议用JS来解决。
~~~
//设置屏幕滚动到当前元素
$elems = $driver->findElements(WebDriverBy::className('n'));
foreach ($elems as $elem){
if(CommonUtil::contain($elem->getText(), '下一页')){
$elem->sendKeys('xxx'); //设置焦点
}
}
$js = <<<js
var next = document.getElementsByClassName('n');
for (i = 0; i < next.length; i++) {
if(next[i].innerHTML == '下一页>'){
//next[i].click();
next[i].style.backgroundColor = "red";
}
}
js;
$driver->executeScript($js); //JS执行点击下一页
~~~
#### 5.执行时间的设置
> 使用自动化测试或爬虫程序,往往程序执行的时间会比较长。为了防止timeout,我们需要设置如下
~~~
set_time_limit(0);
ignore_user_abort(true);
~~~