作者:Gakki_0725
前言
- selenium对网页的操作是基于对前端元素的。所以只有准确的定位到对应的元素才可以进行自动化的操作。
selenium定位方法
-
selenium通过以下方式来定位元素:
定位方式 含义 class name 元素ClassName定位 id 元素id定位 name 元素name定位 tag name 元素标签名称定位 link text 元素链接全部文字定位 partial link text 元素链接部分文字定位 xpath xpath定位 css selector css定位 -
因此,selenium提供了下面的方法来进行元素定位:
- find_element_by_class_name
- find_element_by_id
- find_element_by_name
- find_element_by_tag_name
- find_element_by_link_text
- find_element_by_partial_link_text
- find_element_by_xpath
- find_element_by_css_selector
-
下列方法只是会返回一个list,其余使用跟上诉方法相同:
- find_elements_by_class_name
- find_elements_by_id
- find_elements_by_name
- find_elements_by_tag_name
- find_elements_by_link_text
- find_elements_by_partial_link_text
- find_elements_by_xpath
- find_elements_by_css_selector
异常
- 如果没有元素匹配,会抛出NoSuchElementException异常。
定位方法的使用
- 注:以下均已百度首页为例
通过class定位
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("https://www.baidu.com")
driver.find_element_by_class_name("s-top-login-btn").click() # 点击"登录"按钮
通过id定位
driver.find_element_by_id("s-usersetting-top").click() # 点击"设置"按钮
通过name定位
driver.find_element_by_name("wd").send_keys("测试") # 在搜索框中输入"测试"
通过标签(tag)定位
driver.find_elements_by_tag_name('p')[0].click()
# 定位标签为<p>的元素,并点击
# 这里使用的是find_elements_by_xx,返回的是一个list,根据下标索引来进行点击等操作
通过链接文本(link_text )定位
driver.find_element_by_link_text("使用百度前必读").click()
# 通过元素的link文本定位元素,点击"使用百度前必读"
driver.find_element_by_partial_link_text("百度前必读").click()
# 通过元素的部分link文本定位元素,点击"使用百度前必读"
通过xpath定位
注:xpath的定位 同一级别的多个标签 索引从1开始 而不是0
XML实力文档,我们将在下面的例子中使用这个XML文档。
<!-- Edited by XMLSpy® -->
<CATALOG>
<CD>
<TITLE>Empire Burlesque</TITLE>
<COUNTRY>USA</COUNTRY>
<PRICE id="p501">10.90</PRICE>
<YEAR>1985</YEAR>
</CD>
<CD>
<TITLE>Hide your heart</TITLE>
<COUNTRY>UK</COUNTRY>
<PRICE id="p502">9.90</PRICE>
<YEAR>1988</YEAR>
</CD>
</CATALOG>
-
在xpath中,有七种类型的节点:元素、属性、文本、命名空间、处理指令、注释以及文档节点(或根节点)
-
XPath即为XML路径语言(XML Path Language),它是一种用来确定XML文档种某部分位置的语言。
-
XPath的基本形式:
- Xpath=//tagname[@attribute='value']
- //:选择当前的节点
- tagname:特定节点的标记名
- @:选中属性的标记符
- Attribute:节点的属性名字
- Value:属性值
- Xpath=//tagname[@attribute='value']
-
调试方法
- Chrome按F12,在Console控制台进行Xpath的调试, 以 $x(“Xpath表达式”) 进行
-
基础语法
- 路径表达式
表达式 描述 nodename 选取此节点的所有子节点 / 从根节点选取 // 从匹配选择的当前 . 选取当前节点 .. 选取当前节点的父节点 @ 选取属性 1.1 实例
表达式 描述 CATALOG 选取 CATALOG 元素的所有子节点 /CATALOG 选取根元素 CATALOG。
注:假如路径起始于正斜杠( / ),则此路径始终代表到某元素的绝对路径!CATALOG/CD 选取属于 CATALOG的子元素的所有 CD元素 //PRICE 选取所有 PRICE子元素,不需要管它们在文档中的位置 CATALOG //YEAR 选择属于 CATALOG 元素的后代的所有 YEAR元素,不需要管它们位于 CATALOG 之下的什么位置 //@id 选取名为 id 的所有属性
- 谓语(Predicates):谓语用来查找某个特定的节点或者包含某个指定的值的节点;谓语被嵌在方括号中。
表达式 | 描述 |
---|---|
/CATALOG/CD[2] | 选取属于 CATALOG子元素的第二个 CD元素 |
/CATALOG/CD[last()] | 选取属于 CATALOG子元素的最后一个 CD元素 注:last()-n,n=0或者不写last()默认倒数第一个,n=1倒数第二,以此类推 |
/CATALOG/CD[last()-1] | 选取属于 CATALOG子元素的倒数第二个 CD元素 |
/CATALOG/CD[position()<3]" | 选取最前面的两个属于 CATALOG元素的子元素的 CD元素 注:position()=n,n表示第几个元素,n从1开始 |
//PRICE[@id] | 选取所有拥有名为 PRICE 的属性的 id 元素 |
//PRICE[@id='p501'] | 选取所有 PRICE 元素,且这些元素拥有值为 p501 的 id 属性 |
/CATALOG/CD[PRICE>10.00] | 选取 CATALOG 元素的所有 CD 元素,且其中的 PRICE 元素的值须大于 10.00 |
/CATALOG/CD[PRICE>10.00]/TITLE | 选取 CATALOG 元素中的 CD 元素的所有 TITLE 元素,且其中的 PRICE 元素的值须大于 10.00 |
- 通配符:XPath通配符可用来选取未知的XML元素
通配符 | 描述 |
---|---|
* | 匹配任何元素节点 |
@* | 匹配任何属性节点 |
node() | 匹配任何类型的节点 |
- 选取若干个路径:通过在路径表达式中使用“|”运算符,您可以选取若干个路径,比如:
表达式 | 描述 |
---|---|
//CD/TITLE | //CD/YEAR | 选取 CD元素的所有 TITLE 元素和 YEAR元素 |
//TITLE | //YEAR | 选取文档中的所有 TITLE 元素 和 YEAR元素 |
/CATALOG/CD/COUNTRY | //PRICE | 选取属于 CATALOG元素的 CD元素的所有 COUNTRY元素,以及文档中所有的 PRICE元素 |
- 关键字:使用模糊的属性值匹配
通配符 | 描述 |
---|---|
starts-with() | 匹配一个属性开始位置的关键字 |
ends-with() | 匹配一个属性结束位置的关键字 |
contains() | 匹配一个属性值中包含的字符串 |
text() | 根据文本信息匹配元素位置 |
last()-n | 函数位置定位,n=0或者不写last()默认倒数第一个,n=1倒数第二,以此类推 |
position()=n | 根据位置定位元素位置, n表示第几个元素,n从1开始 |
- 代码展示:
- 注:以【百度】首页为例
import selenium
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("https://www.baidu.com")
# starts-with():匹配class以mnav开头的元素并将定位信息打印在控制台,注意:这里使用的是find_elements定位,返回list
print(driver.find_elements_by_xpath("//a[starts-with(@class,'mnav')]"))
# ends-with(): 匹配class以c-color-t结尾的元素
# 注:如果报错可能是因为ends-with是xpath2.0的语法,而你的浏览器还只支持1.0的语法
print(driver.find_elements_by_xpath("//div[ends-with(@class,'c-color-t')]"))
# contains():定位text为hao的链接并点击
driver.find_element_by_xpath("//a[contains(text(),'hao')]").click()
# text():根据文本信息【地图】匹配元素位置并点击
driver.find_element_by_xpath("//a[text()='地图']").click()
driver.find_element_by_xpath("//a[contains(text(),'地图')]").click()
# last()-1:定位倒数第二个链接
driver.find_element_by_xpath("//div[starts-with(@id,'s-top-left')]/a[last()-1]").click()
# position()=3:定位第三个链接
driver.find_element_by_xpath("//div[starts-with(@id,'s-top-left')]/a[position()=3]").click()
- XPath的类型
- 绝对路径
- 以 / 开头。从根目录开始,比较繁琐,一般不建议使用。如: /html/body/div/div/div/div/div/form/span/input
- 相对路径
- 以 // 开头。表示从当前节点往下寻找所有的后代元素,不管它在什么位置。如://div/div/a
通过css选择器定位
By定位元素
- 除了上面这些公有的定位方法,我们也可以使用以下两种私有方法来对页面的元素定位:
- find_element
- find_elements
- 代码展示:
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.get("https://www.baidu.com")
driver.find_element(By.NAME, "wd").send_keys("测试") # 在搜索框输入"测试"
driver.find_element(By.CLASS_NAME, 's_btn').click() # 点击搜索按钮
- 使用By定位需要导入By类:
from selenium.webdriver.common.by import By
-
By可用的属性:
ID = "id"
XPATH = "xpath"
LINK_TEXT = "link text"
PARTIAL_LINK_TEXT = "partial link text"
NAME = "name"
TAG_NAME = "tag_name"
CLASS_NAME = "class name"
CSS_SELECTOR = "css selector"
杂谈
css和xpath的区别?
- css用的是标签匹配来定位
- xpath使用路径来定位
网友评论