「selenium实战专栏」将记录selenium实战(Python版)过程,以及各类问题的解决方案。
大致规划如下:
- 利用Element UI组件库联系对各种元素的操作
- 利用一个真实网站进行部分页面UI自动化实战
使用版本如下:
- Python 3.10.6
- selenium 4.0.5
selenium操作按钮组件
上章已经成功运行了一个demo,本章开始进入实战环节,
首先访问Element UI官网找到按钮组件。
接下来的任务是通过多种方式获取到「基础用法」中的4个【Success】按钮,如下图所示:
从selenium的源码中可以看到它支持8种方式获取元素,
基本用法如下:
- ID:根据元素标签的id获取元素
- XPATH:根据元素在DOM结构中的xpath路径获取元素
- LINK_TEXT:定位超链接元素,完全匹配
- PARTIAL_LINK_TEXT:定位超链接元素,模糊匹配
- NAME:根据元素标签的name获取元素
- TAG_NAME:根据标签名称获取元素
- CLASS_NAME:根据元素标签的class获取元素
- CSS_SELECTOR:通过CSS选择器获取元素
其实继续查看selenium源码就会发现ID、CLASS_NAME、NAME最终都是通过CSS_SELECTOR,只是selenium给这三种方式提供了更简单的调用方式。
接下来详细讲解获取「基础用法」中4个【Success】按钮的几种方式,以及操作遇到问题的解决方案。
根据ClassName获取元素
首先在按钮上右键,选择【检查】,开发者工具就会跳转到按钮对应的元素标签上,以便对元素进行分析。
在元素标签上可以看到对应的属性。
因为按钮标签上存在class,首先尝试从ClassName来获取元素。先不着急写selenium代码,js本身提供了获取组件的方法,我们可以先通过浏览器开发者工具打开控制台,先尝试通过js代码获取到想要的元素。
可以看到通过ClassName获取到的是一组元素,鼠标移动到对应的元素上,左侧会实时看到定位的是哪个元素。通过观察可以看到除了第一个按钮元素,剩下三个想要定位的元素都有自己的ClassName,可以再次通过js尝试获取。
通过尝试发现下面两个ClassName可以定位我们想要的元素。
这里注意是el-button--success is-round
两个类名而不是单个类名is-round
,单个类名is-round
同样获取的是一组元素,可以自己在控制台进行测试。
接下来使用selenium获取元素,下面这个代码咋一看没问题,但其实是有问题的,大家可以先自己尝试。
运行上面的代码会发现无法定位到元素,下面告诉大家什么有问题,以及如何解决。回到上面的源码部分,下面两种方式其实是等价的。
熟悉CSS的伙伴应该很快就清楚问题出在哪里了,在CSS选择器中空格代表的是后代选择器,现在需要的是通过两个类名确定一个元素,所以CSS选择器正确的语法是.el-button--success.is-round
,对应也就知道ClassName的获取方式了,如下:
完整代码如下:
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
service = Service(executable_path='/Users/huyanping/Softwares/chromedriver')
driver = webdriver.Chrome(service=service)
driver.get("https://element-plus.gitee.io/zh-CN/component/button.html")
# 隐式等待,暂时可以先不用管
driver.implicitly_wait(10)
# element-ui页面会请求一些外部页面,导致需要很长时间的等待,
# 可以设置超时时间避免需要等待很长时间,但是可能会导致元素还没加载出来,可以根据自己的网络对超时时间进行调整
driver.set_page_load_timeout(6)
driver.find_element(By.CLASS_NAME, 'el-button--success.is-round').click()
# 等价于
# driver.find_element(By.CSS_SELECTOR, '.el-button--success.is-round').click()
# 因为点击操作执行完成后,很快就会关闭浏览器无法看到效果,调试的时候可以先注释掉
# 但是要记得自己手动关闭浏览器,避免开很多的浏览器未关闭消耗电脑内存
# driver.quit()
获取多个元素
继续分析在控制台通过js查找的元素,可以看到el-button--success is-plain
获取到的元素组中第一个元素就是想要的,
因此可以结合上面的ClassName的方式,获取到多个元素后,再从列表内获取到第一个元素。
elements = driver.find_elements(By.CLASS_NAME,'el-button--success.is-plain')
elements[0].click()
根据xpath获取(含xpath优化思路)
现在已经获取了下面的三个元素,最上面的元素采用一种新的方案,即xpath,右键元素后可以点击【检查】,在元素标签上【右键】,选择拷贝xpath如下。
最“简单”的方式就是通过拷贝的xpath路径直接进行元素查找:
driver.find_element(By.XPATH,'//*[@id="app"]/div/main/div/div/div[1]/div/div[1]/div[1]/div[1]/button[3]').click()
但是这个方式是很不稳定的,一旦DOM结构改变了,比如多加了一层<div>标签,上面这个方法就无法获取到元素了,因此通过xpath的获取元素的方式还是要对xpath进行优化,主要思路如下:先找到确定的元素,然后使用相对路径进行搜索。通过可以在控制台通过$x('xpath')
语法先进行调试,如下:
//*[@id='app']
:找到任意一个id为app的元素。具体xpath语法可在菜鸟教程上学习。通过分析元素的DOM路径,可以修改为下面这个xoath路径:
控制台调试通过后就可以通过代码去访问了。
driver.find_element(By.XPATH,'//*[@id="app"]//*[@class="example-showcase"]//*[@class="el-button el-button--success"]').click()
以上就获取「基础用法」中4个【Success】按钮组件元素的方案和思路,大家可以自己动手试试~