'''
1-异常处理
由于不能执行到driver.quit,需要手动关闭 浏览器。
打开ac.html,里面 没有id是1t的元素
* 打开 lesson7/err1.py , 运行一下, 需要手动关闭 浏览器。
其实还需要关闭chromedriver进程,否则进程不会自动退出,打开进程管理器看看
实际项目中, 自动化case很多,失败也不少。 这样会导致大量的 chromedriver进程。
多出进程没有退出导致内存占用,机器会变卡
怎么办? 有没有同学有好的办法?
建议写在try 里面, finall 后面需要driver.quit() 。 不然会有很多的 chromedriver进程
2-模拟鼠标悬停
通过 ActionChains 类
ActionChains 类 里面提供了 一些特殊的动作,
比如移动鼠标到某个元素,就是其中之一
ActionChains 类 :action 动作 ,Chains 是链的意思
顾名思义 ,就是 支持 一系列的 连续动作,
acInstance.action1().action2().actionN().perform()
acInstance 是ActionChains 类 实例,初始化参数 就是 WebDriver对象
action1..n 是 一个个的动作,比如点击、输入字符、按下鼠标拖动等
注意,要 以 .perform() 结尾
先不说其他方法,就模拟鼠标移动到某个元素上
通过其方法 move_to_element(ele) 实现.
参数是webelement对象,表示你要移动到这个元素对象上
演示代码段:
from selenium.webdriver.common.action_chains import ActionChains
ac = ActionChains(driver)
# 演示的时候,单步调试, 停在这里,再单步,可以看到效果
ac.move_to_element(driver.find_element_by_id('zxnav_1')).perform()
ele= driver.find_element_by_css_selector(
'#zxnav_1 > div.category-panels >ul >li >a')
3-改变窗口大小
可以使用set_window_size这个方法
参数传递宽度和高度,单位是像素
比如,改变窗口宽度:
size = driver.get_window_size()
driver.set_window_size(1100,size['height'])
4-滚动屏幕
如果窗口太长,改变窗口大小都不够,因为屏幕只有那么大,需要滚动到元素的方案 ,可以使用最后一招, 直接让浏览器执行javascript脚本
浏览器执行的语言是js, 如果我们能直接传入js让浏览器执行,就得到了最大的灵活性去控制浏览器。
可以算是终极武器。 比如滚动屏幕,就可以使用 js语言
window.scrollBy(250,0) 就是横向滚动250个像素,让浏览器去执行,selenium里面实用js代码
driver.execute_script('window.scrollBy(200,0)')
二次渲染
案例:
登录 教管系统,http://localhost/mgr/login/login.html
实现一下添加2门课程,再删除2门课程都能正确显示
from selenium import webdriver
import time
driver = webdriver.Chrome()
driver.implicitly_wait(5)
driver.get('http://localhost/mgr/login/login.html')
driver.find_element_by_id('username').send_keys('auto')
driver.find_element_by_id('password').send_keys('sdfsdfsdf')
driver.find_element_by_tag_name('button').click()
def addCourse(driver,name,desc,idx):
driver.find_element_by_css_selector("a[ui-sref='course']").click()
time.sleep(1)
driver.find_element_by_css_selector(
'button[ng-click^=showAddOne]').click()
ele = driver.find_element_by_css_selector(
"input[ng-model='addData.name']")
ele.clear()
ele.send_keys(name)
ele = driver.find_element_by_css_selector(
"textarea[ng-model='addData.desc']")
ele.clear()
ele.send_keys(desc)
ele = driver.find_element_by_css_selector("input[ng-model='addData.display_idx']")
ele.clear()
ele.send_keys(idx)
driver.find_element_by_css_selector('button[ng-click^=addOne]').click()
def DeleteAllTeacher(driver):
delButtons = driver.find_elements_by_css_selector(
'*[ng-click^=delOne]')
for button in delButtons:
button.click()
driver.find_element_by_css_selector(
'.modal-footer .btn-primary').click()
addCourse(driver,'数学','数学',1)
addCourse(driver,'语文','语文',2)
time.sleep(1)
DeleteAllTeacher(driver)
input()
driver.quit()
结果运行发现
selenium.common.exceptions.StaleElementReferenceException: Message: stale element reference: element is not attached to the page document
原来是现在的web应用和以前大不相同,
以前的web应用大都是后端直接产生最终的html界面
而现在呢?很多是页面加载后(也加载javascript前端代码), 由前端代码动态改变界面的内容,比如从后端获取一些数据后,再动态改变界面的内容。
尤其是很多采用了框架像 angular, react, vue这些都会这样做。
这样就有一个问题,开始的时候获取的html只是一个模板一样的文档,里面的数据没有产生,
而是需要等前端js代码动态的 再次向后端查询数据后, 才动态的向html模板中填入数据或者修改数据。
-----------------------
原因是:
一下子获取了多个删除按钮 元素, 然后用循环点击 每个删除按钮
但是当点击第一个按钮之后,页面有些部分被更新了, 剩余的几个按钮,
虽然看起来还是原来的样子。但是已经是新的界面元素了
所以,你通过原来老的 界面元素点击 ,就会出现这个错误
那么怎么解决这个问题呢?
既然点击 第一个课程的删除按钮 后,页面部分被更新了, 就只好重新获取界面元素。
def DeleteAllCourse(driver):
driver.implicitly_wait(2)
while 1:
delButtons = driver.find_elements_by_css_selector(
'*[ng-click^=delOne]')
if len(delButtons) < 1:
break
delButtons[0].click()
driver.find_element_by_css_selector(
'.modal-footer .btn-primary').click()
time.sleep(1)
半自动化的用途
selenium 属于图形界面自动化的测试,图形界面自动化的难度是比较大的。
模拟难:
有些特殊的输入,比如12306 点击图片的某个部分
打开 https://kyfw.12306.cn/otn/login/init
检查难:
打开 https://www.vmall.com/
比如检查菜单有没有,
我们经常是检查某些输出的字符,
应该还有:
界面的整体是否布局有错乱,
图片显示logo是否正确
为什么会有这些难度, 因为界面操作者是人 , 有很多操作需要人的智能,才方便输入,检查输出。
比如 难自动化的 操作 包括 模拟输入,检查输入 。 都提示(beep)让人去做
#打开浏览器代码
#系统提示,手动输入验证吗
import time
import winsound
winsound.Beep(1500,30000)
time.sleep(10)
'''''
python+selenium学习笔记:使用技巧二
猜你喜欢
转载自blog.csdn.net/qq_44891948/article/details/103054590
今日推荐
周排行