在自动化元素定位操作中经常使用智能等待来加强定位的强壮性,主要就是因为WebDriver没有提供页面加载场景的方法;在使用JavaScript知识的突然心生灵感,可以使用JavaScript来配合验证页面加载,结果发现我真是井底之蛙。

一、domcument.readyState

首先定位从Document对象出发,而Document对象是在html文档加载完成便可操作使用,所以判断文件装载完成即可;Document对象的readyState属性返回当前文档装载状态:

  1. uninitialized 表示未开始载入
  2. loading 载入中,下载了html并且开始加载
  3. interactive 已加载完html内容
  4. complete 已加载完html内容和下载解析了子资源(js、css、image),不包含ajax异步。

public static void pageDOMLoadComplete(){

JavascriptExecutor JS=(JavascriptExecutor) SeleniumMethod.ThreadDriver.get();

try {

while(!"complete".equals(JS.executeScript("return document.readyState"))){

Thread.sleep(2000);

}

logger.info("页面元素加载完成");

} catch (Exception e) {

// TODO: handle exception

e.printStackTrace();

logger.info("判断页面元素加载异常");

}

}

如上代码,如果结果返回的complete表示加载完成,这时候就可以开始元素定位操作。返回不是complete则使用线程循环等待,直到加载完成才跳出循环。

详细了解的建议去脑补一下浏览器对页面加载的过程。通过浏览器发送请求到服务器响应先得到html形成Document对象,浏览器解析html形成dom树开始加载,当加载dom树遇到外部资源时去请求外部资源,但加载dom树并不会等待会继续加载,当资源如JavaScript、Css、图片等等加载完成这时候document.readyState的值变成complete。

二、Selenium加载策略

因为Selenium从头到位都没有任何判断页面加载完成的关键字;而结合document.readyState的返回来确定页面加载成功,然后再去执行定位操作,这样来说是个合理的思想。根据想法编写下面的代码:

WebDriver driver = new ChromeDriver();

driver.get("https://www.sina.com.cn/");

try {

while(!"complete".equals(((JavascriptExecutor)driver).executeScript("return document.readyState"))){

Thread.sleep(1000);

}

} catch (Exception e) {

// TODO: handle exception

e.printStackTrace();

}

driver.findElement(By.name("SerchKey")).sendKeys("软件测试");

driver.findElement(By.name("SearchSubButton")).click();

driver.quit();

上面代码利用JavaScript执行一段脚本document.readyState的值返回不是complete则一直循环并线程等待1S,直到返回的值是complete退出循环。

但是在代码运行后发现,从来都没有进入过循环。于是猜测,是get()方法在打开浏览器并访问URL时,是不是就已经判断过页面加载完成了?验证方法很简单,把循环去掉,代码直接打印document.readyState返回的值

System.out.print(((JavascriptExecutor)driver).executeScript("return document.readyState"));

得到的结果每次都是complete,验证确实get()方法后就已经页面加载成功了。在使用WebDriver时,每次打开浏览器都知道它并不会带有任何缓存数据,而是一个全新初始化的浏览器,这点只要用过Selenium的同学,并做过登录功能都应该知道,每次使用都需要重新登录,浏览器并不会保存任何cookie、缓存信息。就是因为这个原因,WebDriver每次调起浏览器并访问URL的时候因为没有缓存所以页面加载会非常慢(当然不仅仅是缓存,WebDriver还会去遍历一些其他东西,如虚拟网卡、代理配置等);这个慢的现象大多数是页面已经展示内容了,然后浏览器还在转圈加载,然而使用document.readyState来判断好像不现实了,因为WebDriver的get()方法默认就会等待页面加载完。所以思路就转化为,get()方法的探究。

通过官方资料查询,发现WebDriver有pageLoadStrategy加载策略这一说,地址如下:https://www.w3.org/TR/webdriver/#dfn-table-of-page-load-strategies,大家可以自己去瞧瞧。加载策略有如下三种:

  1. none:没有说明对应关系
  2. eager:对应ducument readiness state为”interactive”
  3. normal:对应ducument readiness state为”complete”

从上面三种加载策略可以看到,官方除了none这种没有具体说明外,另外两种对应的正式document.readyState返回的状态。而默认的加载策略是normal,所以再次验证为什么使用document.readyState得到的值是complete。验证代码如下:

DesiredCapabilities capabilities = DesiredCapabilities.chrome();

capabilities.setCapability("pageLoadStrategy", "none");

WebDriver driver = new ChromeDriver(capabilities);

driver.get("https://www.sina.com.cn/");

System.out.println(((JavascriptExecutor)driver).executeScript("return document.readyState"));

driver.findElement(By.name("SerchKey")).sendKeys("软件测试");

driver.findElement(By.name("SearchSubButton")).click();

System.out.println(((JavascriptExecutor)driver).executeScript("return document.readyState"));

driver.quit();

执行代码,打印document.readyState返回的结果是loading;在使用findElement查找元素时报错“Unable to locate element”。当加载策略为none时,对应document.readyState结果是loading的时候,页面还在加载中,进行元素查找会报错,这很好理解,Dom树还在加载过程中,是无法解析任何元素的查找的,所以报错。

接下来分别尝试了eager加载策略,需要注意一点的是Chrome浏览器并不支持这种加载策略,所以改为了Firefox验证。

DesiredCapabilities capabilities = DesiredCapabilities.firefox();

capabilities.setCapability("pageLoadStrategy", "eager");

WebDriver driver = new FirefoxDriver(capabilities);

其他代码不变,执行代码打印document.readyState返回的结果是interactive,但是不同的是使用findElement查找元素没有报错,并且全部执行成功。当加载策略为eager,页面加载结果interactive时,整个DOM树加载完成,这时候就已经可以定位元素并执行操作了;根据document.readyState与WebDriver的加载策略得出以下结论:

(1)loading与none

DOM树 载入中,也就是说已经下载了html并且开始加载;这时候是无法查找元素的,get()方法的执行时间非常短,可以马上执行get()方法后面的代码。所以这时候就可以使用下面代码再次进行判断后再执行。

while(!"complete".equals(((JavascriptExecutor)driver).executeScript("return document.readyState"))){}

这样的作法好像与加载策略的默认方法没什么不同,但是WebDriver的get()方法可不仅仅是等待页面为complete而已,它还会去判断一些浏览器其他的配置。

这种情况还有一种不建议使用的方式,就是使用隐式等待,每次查找元素找不到时,等待一定时间。隐式等待在当前driver的整个生命周期中都生效,是非常适合配合none这种加载策略的。

driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

(2)interactive与eager

已加载完html内容,但是没有解析子资源;这时候DOM树加载完成,并且去请求子资源了,是可以查找元素并正确返回了。有个弊端就是如果一些数据是通过JavaScript去赋值的,这时候查找元素某些属性数据可能得到空。

(3)complete与normal

已加载完html内容和下载解析了子资源(JavaScript、css、image),不包含ajax异步。前面应该都没疑问,重要的是ajax异步请求的加载。如果页面上一些数据是通过ajax异步去请求并加载的,同样在ajax请求中数据响应没有及时回来的情况下,拿到的也是空。当然这并不需要担心,只要不是太大数据请求响应还是非常快速的。

百度阅读:https://yuedu.baidu.com/ebook/82a757ec7e192279168884868762caaedd33baa3

探索Selenium打开浏览器加载慢的原因相关推荐

  1. win10浏览器加载很慢_win10加载网页很慢_win10打开浏览器加载网页很慢处理技巧...

    win10加载网页很慢_win10打开浏览器加载网页很慢处理技巧 在当下用电脑办公很普遍了,相当一部份用户经历了xp,win7/win8/系统,现在又出了个win10系统,随着硬件的老化与win7支持 ...

  2. Selenium基础 — 拓展:使用浏览器加载项配置实现用户免登陆

    1.什么是加载项配置 在很多情况下,我们在登录网站的时候,浏览器都会弹出一个是否保存登录账号的信息.如果我们选择保存,那么我们在下次登录时就不用再次输入账号,直接免登录了. 在我们实际的测试过程中,测 ...

  3. win10浏览器加载很慢_Win10 Edge浏览器打开缓慢如何提高加载速度

    升级Win10系统的用户大多都在体验最新的Edge浏览器,为什么Edge能够挑战老牌IE的地位,成为Win10默认浏览器呢?微软官方给出的答案是Edge浏览器访问网页更流畅.耗电更少.集成功能更多.可 ...

  4. 浏览器加载解析渲染机制的全面解析

    (注1:如果有问题欢迎留言探讨,一起学习!本文首发于我的简书,转载请注明出处,喜欢可以点个赞哦!) (注2:更多内容请查看我的目录.) 1. 简介 在前面一篇文章中,讲到了用户从输入url到看到页面的 ...

  5. python3读取网页_python3+selenium获取页面加载的所有静态资源文件链接操作

    软件版本: python 3.7.2 selenium 3.141.0 pycharm 2018.3.5 具体实现流程如下,废话不多说,直接上代码: from selenium import webd ...

  6. ie加载项存在残留是什么_如何用百度杀毒清除IE浏览器加载项残余

    如何用百度杀毒清除IE浏览器加载项残余?很久没有主动查杀毒了,清理了一下,突然发现IE浏览器有加载项残余,一探究竟. 方法/步骤 一般扫描到系统异常,都会仔细查看,寻根溯源,而不是随手清理了之,能自己 ...

  7. 转:浏览器加载页面的过程与页面性能优化

    本文是转帖,原文:http://www.baiduux.com/blog/2011/02/15/browser-loading/ 发布日期:2011年2月15日 作者:nwind 类别:HTML/CS ...

  8. 浏览器加载、解析、渲染的过程

    最近在学习性能优化,学习了雅虎军规 ,可是觉着有点云里雾里的,因为里面有些东西虽然自己也一直在使用,但是感觉不太明白所以然,比如减少DNS查询,css和js文件的顺序.所以就花了时间去了解浏览器的工作 ...

  9. 浏览器加载和渲染html的顺序

    1.浏览器加载和渲染html的顺序 浏览器加载和渲染html的顺序 IE下载的顺序是从上到下,渲染的顺序也是从上到下,下载和渲染是同时进行的. 在渲染到页面的某一部分时,其上面的所有部分都已经下载完成 ...

  10. 加载如下html 写出输出顺序,浏览器加载和渲染html的顺序-结论篇

    我只转载觉得可以使用的. 1.浏览器加载和渲染html的顺序 1.IE下载的顺序是从上到下,渲染的顺序也是从上到下,下载和渲染是同时进行的. 2.在渲染到页面的某一部分时,其上面的所有部分都已经下载完 ...

最新文章

  1. iframe父子页面交互
  2. android activity启动流程_1307页!一线大厂Android面试全套真题解析!
  3. 探究Facebook相似性搜索工具 faiss的原理
  4. 12 - Runtime实用的几个API
  5. Git常用命令与基本操作
  6. 浅谈shell中的clear命令实现
  7. [js] 请使用js实现商品的自由组合,并说说你的思路
  8. JEECG 移动端解决方案
  9. Numpy 通用函数
  10. 转行学AI,如何选择适合的方向
  11. python连接mysql的操作
  12. 菊安酱的机器学习实战
  13. java 输入人名输出_Java 输入汉字姓名 输出 姓名拼音 首字母缩写组合
  14. 世界记忆大师的记忆力训练方法
  15. 1093-A+B for Input-Output Practice (V)
  16. 获取分辨率函数是什么_浅析EDSR——深度学习超分辨率算法
  17. python智能决策系统_智能风控决策引擎系统可落地实现方案(三)模型引擎实现...
  18. Excel·VBA按列拆分工作表、工作簿
  19. 2019天津市计算机等级考试报名时间,天津2020上半年计算机等级考试报名时间已公布...
  20. 暖暖环游世界显示服务器异常,暖暖环游世界

热门文章

  1. 数据挖掘:针对小样本与不均衡样本的机器学习算法实践
  2. php mysql常见面试题_PHP常见面试题总结
  3. PVT论文精读:Pyramid Vision Transformer: A Versatile Backbone for Dense Predictionwithout Convolutions
  4. 使用 RSA 算法进行加解密,签名和验签
  5. python3表白代码弹窗_抖音整蛊表白电脑弹窗代码大全
  6. 从零开始做运营第一课:运营是做什么的?一篇文章解释清楚!
  7. android 6 root权限,安卓一键root(权限获取)
  8. 自动识别快递公司,教你快递查询单号查询物流
  9. 导航栏背景色、标题颜色以及返回键自定义
  10. 逻辑设计基础_第2周-布尔代数及表达式化简