今天使用Python+Selenium+PyCharm写了一个Web自动化小程序练习Xpath定位,在调试程序的过程中发现代码未执行完浏览器就关闭了,但是后台并没有报错。经过百度后推测是等待时间的问题,访问官网查阅Selenium-Python-API,查阅隐式等待和显示等待用法,修改脚本完善代码,继续调试。调试过程中发现脚本在不同窗口进行切换时报NoSuchElementException异常,经问题分析和定位,使用switch_to.window()方法完美解决。整个代码调试过程花费了很长时间,但在整个问题解决过程,一步一步的探索,在解决一个问题的同时发现新的问题,环环相扣,颇有成就感。本来一个简单的小程序,靠着敏锐的直觉,嗅到了一丝bug的气息,一路过关斩将,既锻炼了问题分析的能力,也顺便学习了Selenium-Python-API。我把整个问题定位的过程记录下来,便于后面的学习。
一,Web自动化环境配置
Python3.8.3+PyCharm 2020.2.1+Selenium+Win10 64位
二,Web自动化小程序功能
程序功能:访问百度首页,点击新闻超链接,进入新闻页面后退出浏览器。
网站地址:
百度首页,如图:
百度新闻,如图:
三,问题定位过程
整个调试过程中,代码共经历了V1.0.0-V1.0.4五个版本,其中V1.0.0和V1.0.2代码存在问题,V1.0.1(强制等待),V1.0.3(隐式等待)和V1.0.4(显示等待)调试成功,分别为强制等待,隐式等待和显示等待的代码实现方法,效果是一样的。
3.1 版本V1.0.0
存在问题: 代码未执行完,浏览器就关闭了。
问题分析: 推测是点击“新闻”超链接进入下一个页面时,未加等待时间,页面未加载完成,就执行退出浏览器语句了。
代码如图:
3.2 版本V1.0.1 【强制等待调试成功】
强制等待:在脚本中设置固定时间的休眠,程序中导入time模块,使用sleep()即可。
代码优化:进入下一个页面时添加等待时间,引入time模块,使用sleep()方法,强制等待几秒钟。
调试结果: 程序调试正常,前台网页成功打开,点击“新闻”超链接,进入新闻页面,浏览器正常退出并关闭,版本V1.0.0问题解决。
问题定位: V1.0.0版本代码,新闻页面未进入浏览器就退出的问题确实是未加等待时间的原因导致。
代码如图:
3.3 版本V1.0.2
隐式等待:设置一定的时长等待页面上的某元素加载完成,如果超过了设置的时长,元素仍未被加载,则抛出NoSuchElementException异常。WebDriver提供了implicitly_wait()方法来实现隐式等待,默认等待时间设置为0秒。设置的等待时长并非一个固定的等待时间,它并不影响脚本的执行速度。其次,它并不针对页面上的某一元素进行等待。
代码优化:在V1.0.1基础上添加等待时间,使用implicitly_wait()方法,并判断页面元素是否存在,然后退出浏览器。
调试结果: 前台跳转正常,后台报NoSuchElementException异常,selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element。
问题分析: “贴吧”超链接Xpath定位语法写错,等待时间不够长,或者其他别的错误。
代码如图:
问题定位:新建py文件,修改代码,浏览器直接访问“http://news.baidu.com”,验证Xpath语法是否正确。
代码如图:
经验证在百度新闻页面,代码没有问题。如图:
分析结论:通过百度首页,点击超链接进入百度新闻页面,百度新闻页面的元素定位报NoSuchElementException异常,推测是未切换窗口导致的。
3.4 版本V1.0.3 【隐式等待调试成功】
代码优化:在V1.0.2基础上使用switch_to.window()方法,实现在不同的窗口之间切换。
调试结果: 前台跳转正常,后台无报错,调试成功。
代码如图:
3.5 版本V1.0.4【显示等待调试成功】
显示等待:需要使用WebDriver提供的WebDriverWait类,显示等待将等待时间设置为一个固定的时长,在设置时间内,默认每隔一段时间检测一次当前页面上的某一元素是否存在,如果超过设置时间检测不到则抛出异常。
代码优化:页面加载采用显示等待方式,使用WebDriverWait类,实现不同窗口切换,使用switch_to.window()方法。
调试结果: 前台跳转正常,后台无报错,调试成功。
代码如图:
程序调试成功!