admin 管理员组文章数量: 1086019
今天下午处理了一个ui自动化工程师提交给 我们测试技术委员会的 关于 selenium+pytthon 的疑难杂症。
经过一番思考后成功解决,且方法极为简单可靠,具体代码在最后。
先看下这个疑难问题:
访问一个内部平台登陆页面,
然后弹出证书弹窗:
必须点击确定按钮。否则无法继续加载登陆页面
手动点击一次之后,关浏览器下次打开仍然会弹出。
需求是想每次代码能自动点击确定关闭弹窗,然后继续执行
对于成熟的测开来说,需要在大脑中先思考解决这个问题的几种可能办法,然后迅速判断出每条方法的难度,复杂度,麻烦程度,成功概率,后续维护等。
首先思路有俩条大方向:
1.设置浏览器方向,让浏览器自己永远不用弹这个证书弹窗。
2.在自动化代码里动手脚,让每次到这之后自动点击确定好关闭弹窗。
先说说方法1: 从浏览器自身下手。可是作者对各种浏览器的证书设置实在是不精通,甚至百度都不知道怎么搜。而且要设置的不只有一个浏览器,谷歌/火狐/ie等等,很多。换台电脑,或者部署在服务器的时候,都是个问题。而且以自身的经验来说,可能要弄一下午,最终还是不成功。所以此路可行,但是成功率太低,优先级最后把。
所以马上想方法2:从代码中处理,这种情况跨平台性好,而且也不会因机而异。方便快捷还省时省力。
方法2:从代码里动手脚 有以下几个子思路
1.利用alert.accept() 方法,但是对于自动化工程师而言,想都不用想,这个肯定不好使。因为这次不是一个简单的alert弹窗,而是一个复杂的证书选择器。所以此路不可行。
2.利用autoIt3: autoit3最早被selenium工程师熟知基本是因为其可以处理文件上传框,但是作者目前情况是:电脑没有安装autoit3,且电脑是mac,基本无法使用,即便换成windows,也需要先到处找安全的下载地址,然后下载,然后研究破解,然后录制脚本,然后打包成.exe,然后在python代码中 运行.exe。这个过程估计弄完,天都黑了。而且程序运行速度也会受制于.exe的启动执行速度。所以判断此路可行,但是不优先。
3.利用selenium的鼠标/键盘操作,强制点击确定或按回车功能。
此方法简单可靠快速,是最佳选择。所以作者立即进行可行性调研。
这种方法利用起来有个前提,就是浏览器没有在缓冲中,python代码可以在弹窗出来后继续执行。但是实际发现,在证书弹窗出现的全部时间内,浏览器都是一直在缓冲转啊转,别说后面什么点击回车,移动鼠标操作了,连个print都无法执行。
所以在此思路上引出新问题:如何能在弹窗出现后,点击回车。
解决方向有:
1.利用超时,强制运行driver.execute_script("window.stop()") 用js的强制停止页面
这种方法使用后,的确可以停止网页,然后程序点击了回车,关闭了证书弹窗,但是结果就是,浏览器不在继续加载了。登陆页面所有的东西都没有出来,相当于你为了把受伤人身上的子弹取出来,就把人给开肠破肚的解刨了,子弹是拿出来了,人也没了~
最终作者开始用另一种子思维:
2.利用多线程,新建一个小弟去帮你点回车
这种方法是先生成一个子线程,子线程干什么呢?就只有 等待2秒,然后点击键盘回车。就这么简单。
当主线程走到 driver.get() 方法打开网页的同时,子线程start。
然后主线程 使浏览器弹出了证书选择弹窗。子线程也在刚刚等待了2秒后,按下了回车,使浏览器证书选择弹窗成功确认并关闭,然后子线程死亡。浏览器成功加载出登陆页面,主流程开始接下来的 输入用户名/密码等工作。
最后把这个方法封装了一下,以后就不用driver.get()方法了,直接调用封装好的zs_get()即可。上面的2s为啥要等待呢,因为子线程相当于你的小弟,但是个瞎子,只能自己默数2秒然后挥刀。如果不等待,那就会导致子线程先按下回车,主流程才使浏览器弹出证书选择弹窗导致无法关闭。所以最后 奉上原码:
def zs_get(url):
from selenium.webdrivermon.keys import Keys #导入键盘按键方法,有很多这里随便举例一种
import threading #导入多线程模块
def press_enter(): #定义子线程函数
time.sleep(2) #可以多等待几秒
#ActionChains(driver).send_keys(Keys.ENTER).perform() : #按下回车代码
#pyautogui 注意这里必须使用第三方界面工具,原ActionChains方法会被阻塞
t = threading.Thread(target=press_enter) #初始化子线程
t.setDaemon(True)
driver.get(url) #drver访问网址登陆页面
t.start() #子线程启动
zs_get("http://xxxx/xxxx/xxxx") #调用此方法来代替driver.get() 即可自动处理上述难题
其实作者还想了好多办法,只是在测试这种的时候直接就成功了,所以后续方法没有再进行测试和过多思考。
珍贵的不只是这个方法,而是面对一个陌生的难题的时候,要做到临危不惧,不自暴自弃,坚信没有解决不了难题,然后通过科学的方法一步一步最终 用最短的时间,确定出最好的那个方法。
有兴趣的小伙伴可以留言讨论。
版权声明:本文标题:记一次 selenium 处理浏览器证书弹窗的经历 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://roclinux.cn/b/1737923943a1896902.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论