在自动化测试中Selenium还是简单易学的,为了帮女朋友做一个重复性工作,刚好她也在学就尝试先帮她做出来,刚开始只是摸石头过河,实践中获取经验。把她的关于自动化测试的书翻了翻,知道了一些基本用法。后面构建多浏览器同步协作和鼠标事件以及整合构建工具没有过多研究。
主要注意一下几个点:
1、 当元素定位不到时考虑的种情形:
①动态id定位不到元素
#这里的div根据不同行下标而变化
print("准备获取元素,num_list_index为",self.current_dealWith)
el = self.driver.find_element_by_xpath(f'//*[@id="layui-layer{self.current_dealWith}"]').find_element_by_xpath(
f'//*[@id="layui-layer{self.current_dealWith}"]/div[2]')
{self.current_dealWith} 的值随着访问元素的增多,div标签 id 动态变化
②iframe原因定位不到元素
def turnToTableFram(self):
print(f'即将退出到默认frame')
self.driver.switch_to.default_content()
print(f'即将进入bottomFrame')
self.driver.switch_to.frame("bottomFrame")
print(f'进入bottomFrame')
print(f'即将进入op_frame')
# driver.switch_to.frame("op_frame")
el = self.driver.find_element_by_id('op_frame')
print(f'进入op_frame')
frame = el.find_element_by_name('mainFrame')
print(frame)
self.driver.switch_to.frame(frame)
print(f'进入mainFrame')
# 获取tablewebElement,调用方法
table = self.driver.find_element_by_xpath('//*[@id="ngView"]/gt-container/div/div/div/div[1]/table')
return table
在页面中有iframe、frame时,需要看标签层级,从最外层frame一层一层进入, 关键语句 self.driver.switch_to.frame("bottomFrame")
注意:frameset 可以跳过,不需要进入在访问其中frame,如果frameSet中的frame无法定位,id动态变化,可以观察需要元素是否始终在某特定位置的frame,若是可以用下标的方式去访问。
③.点击速度过快 页面没有加载出来就需要点击页面上的元素
这里有几种方式,time.sleep(时间)、显示等待、隐式等待
定位方式选错、xpath语句写错等都可能导致定位不到
selenium使用中, 主要使用 ①切换frame或者说是聚焦的页面,把每个frame和alert看成新的一张网页,在定位元素时,要清楚自己走到哪张页面了;②第二个大功能就是定位,定位的方式有很多种,所以实现的方法也有很多种。xpath、类、id、属性、tagName等 ③定位到的元素都会返回一个WebElement的标签对象,当用的是find_element_XXX时, 标签对象唯一,可以取text、tag_name等还有书上没有的方法,比如取它的属性 get_attribute('id')
current_element = self.driver.switch_to_active_element()
print('current_element3',current_element.tag_name,current_element.text,current_element.get_attribute('id')) #当前在弹出框第二个div
④如果使用的find_elements_XXX时, 在页面没刷新时(点击事件就可能导致刷新),可以使用for遍历对每个标签对象操作,但只要DOM域发生变化,找不到这些标签对象时,for 遍历的每一项不能对它进行上述操作,要解决这一问题,需要重新定位到上级元素,重新获取列表。
def for_element(self):
#统计当前页面有多少个不需要处理
WebElem_table = log.turnToTableFram()
#因为操作完一条数据后,页面只要有跳转和刷新,页面dom中获取对象就发生变化,不能用下面方式
print('WebElem_table')
print(WebElem_table.size,WebElem_table.tag_name)
# # 获取table中每行元素
table_tr_list = WebElem_table.find_elements_by_tag_name('tr')
print(table_tr_list)
# for tr in table_tr_list:
print(f"原始table中有{len(table_tr_list)}元素")
for num_list_index in range(1,len(table_tr_list)):
#修改此处,可以检测执行单条处理后,调页是否正常
# for num_list_index in range(1,2):
# 校正页面
log.changePage()
#重新载入存在dom域中的table元素
WebElem_table = log.turnToTableFram()
table_tr_list = WebElem_table.find_elements_by_tag_name('tr')
print(f"table_tr_list当前table中有{len(table_tr_list)}元素")
print(f"num_list_index当前准备处理第{num_list_index}个元素")
print(table_tr_list[num_list_index].size,table_tr_list[num_list_index].tag_name)
其它小点和具体的代码对应的功能不过多赘述,有详细文档 https://www.selenium.dev/selenium/docs/api/py/api.html
非官方中文文档:https://python-selenium-zh.readthedocs.io/zh_CN/latest/