🌟想系统化学习爬虫技术?看看这个:[数据抓取] Python 网络爬虫 - 学习手册-CSDN博客
在使用 Selenium 时,往往需要先定位到指定元素,然后再执行相应的操作。例如,再向文本输入框中输入文字之前,我们需要先定位到文本框对应的元素 <input>
之后,再对该元素对应的对象执行输入文本的操作。
0x01:WebDriver 类元素定位方法
Selenium 的 WebDriver 类中提供了多种定位元素的方法,这些方法有的可以定位单个元素,有的可以直接定位多个元素,WebDriver 类中定位单个元素的方法如下表所示:
方法 | 解析 |
---|---|
find_element() | 通过指定方式定位元素 |
find_element_by_id() | 通过 ID 属性定位元素 |
find_element_by_name() | 通过 name 属性定位元素 |
find_element_by_xpath() | 通过 XPath 的路径表达式定位元素 |
find_element_by_link_text() | 通过链接文本定位元素 |
find_element_by_partial_link_text() | 通过部分链接文本定位元素 |
find_element_by_tag_name() | 通过标签名定位元素 |
find_element_by_class_name() | 通过 class 属性定位元素 |
find_element_by_css_selector() | 通过 CSS 选择器定位元素 |
上面表中所有方法都会返回一个 WebElement
类的对象(通过 text
属性可以打印文本内容),该对象用于描述网页上的一个元素。需要注意的是,上面表中所有的方法只能定位第一次符合要求的元素。
如果你希望定位符合要求的所有元素,就需要使用定位多个元素的方法。定位多个元素的方法名称与用法都与单个元素的定位名称相似,仅需要将 element
设为复数形式 elements
即可。定位多个元素的方法返回值是包含所有符合元素的列表。
0x02:通过 id 属性定位元素
在 HTML 中,id
属性用于规定元素的唯一 ID 值。例如,百度搜索首页,左上角的那些外链,就对应着 id 属性值为 s-top-left
的标签,通过这个 id 我们就可以精确定位这一片的内容:
在 Selenium 中,通过 find_element_by_id()
方法可以通过 id
属性定位页面元素,并返回对应的元素内容:
from selenium import webdriver
import time
driver = webdriver.Chrome() # 创建浏览器对象
driver.get("https://www.baidu.com") # 访问百度首页
# 通过 id 属性定位元素
element = driver.find_element_by_id('s-top-left')
# 通过 text 属性输出元素的文本内容
print(element.text)
0x03:通过 class 属性定位元素
在 HTML 中,class
属性用于规定元素的一个或多个类名,大多数情况下用于指向样式表中的类。我们继续以百度首页为例,如下,通过在 “开发者工具” 中输入 .mnav
即可筛选出一堆 Class 属性中含有 mnav
的标签:
在 Selenium 中,通过 find_element_by_class_name()
方法我们可以通过 class
属性定位元素,并返回匹配的元素,代码如下:
from selenium import webdriver
driver = webdriver.Chrome() # 创建浏览器对象
driver.get("https://www.baidu.com") # 访问百度首页
# 通过 class 属性定位所有属性含有 mnav 的标签
element_list = driver.find_elements_by_class_name('mnav')
# 打印 class 中含有 mnav 元素的内容
for element in element_list:
print(element.text)
0x04:通过指定方法定位元素 — find_element()
Selenium 提供了一个通用的 find_element()
方法来定位元素(想要定位多个元素的话需要使用 find_elements()
)。与其它几个方法相比,它有更加灵活的使用方式,我们可以通过指定参数,来选择定位的方法。find_element()
声明如下:
find_element(self, by=By.ID, value=None)
该方法接收两个参数,参数 value
表示元素的名称或者属性的值,亦或者对应查询方式的传参。参数 by
支持的取值及其说明如下表所示:
取值 | 说明 |
---|---|
By.ID | 通过 id 属性定位元素 |
By.NAME | 通过 name 属性定位元素 |
By.CLASS_NAME | 通过 class 属性定位元素 |
By.TAG_NAME | 通过标签名定位元素 |
By.LINK_TEXT | 通过链接文本定位元素 |
By.PARTIAL_LINK_TEXT | 通过部分链接文本定位元素 |
By.CSS_SELECTOR | 通过 CSS 选择器定位元素 |
By.XPATH | 通过 XPath 的路径表达式定位元素 |
例如,使用 find_element()
方法定位百度搜索首页中 class 属性值包含 mnav 的第一个元素:
from selenium.webdriver.common.by import By # 导入 By 类
from selenium import webdriver
driver = webdriver.Chrome() # 创建浏览器对象
driver.get("https://www.baidu.com") # 访问百度首页
# 通过 class 属性定位第一个属性中含有 mnav 的标签
element = driver.find_element(by=By.CLASS_NAME, value='mnav')
# element_list = driver.find_elements(by=By.CLASS_NAME, value='mnav') # 定位多个元素
print(element.text)
0x05:通过标签名定位元素
这里所说的标签就是指 HTML 标签,比如超链接的 <a>
标签,又比如常见的块 <div>
。我们依旧以百度首页为例,可以看到,百度首页中包含很多超链接标签:
假设我们要获取当前页面所有的 <a>
标签,此时我们就可以通过 find_elements_by_tag_name()
函数实现:
from selenium import webdriver
driver = webdriver.Chrome() # 创建浏览器对象
driver.get("https://www.baidu.com") # 访问百度首页
# 获取当前页面中所有的 <a> 标签
element_list = driver.find_elements_by_tag_name('a')
print(f"[ + ] 当前页面共捕获 <a> 标签: {len(element_list)} 个")
# 打印每个标签中的文本
for element in element_list:
print(element.text)
0x06:通过链接文本定位元素
超链接即 <a>
标签,超链接文本,即被 <a>
标签包裹的内容。Selenium 提供了两种方式,可以直接通过超链接文本定位元素,一种是完全匹配,即 <a>
标签内部的内容要与预期内容完全相同才匹配成功;另一种是模糊匹配,比如你想匹配 “新” 字,那么包含 “新闻”,“新鲜” 等这类的标签都会被选中:
from selenium import webdriver
driver = webdriver.Chrome() # 创建浏览器对象
driver.get("https://www.baidu.com") # 访问百度首页
# 通过链接文本定位元素
element = driver.find_element_by_link_text("新闻") # 完全匹配
print(element) # 打印元素
element = driver.find_elements_by_partial_link_text("新") # 模糊匹配,只要里面包含了 "新" 的标签就会被匹配上
print(element)
0x07:通过 XPath 路径表达式定位元素
XPath 即 XML 路径查询语言(XML Path Language),是一种用于确定 XML 文档中部分节点位置的语言。它起初只支持搜索 XML 文档,更新后能支持搜索 HTML 文档。
关于 XPath 的语法,笔者在前面的章节中介绍过了(如果没有,一定是笔者还没发)。所以这里笔者就不详细介绍它的语法了,直接上演示,假设我们要选中百度首页的 “新闻”,通过 “XPATH 测试插件”,我们可以直接获取其 XPath 定位语法:
//div[@id='s-top-left']/a[@class='mnav c-font-normal c-color-t'][1]
在 Selenium 中,我们可以通过 find_element_by_xpath()
来使用 XPath 语法定位元素:
from selenium import webdriver
driver = webdriver.Chrome() # 创建浏览器对象
driver.get("https://www.baidu.com") # 访问百度首页
# 通过 XPath 定位元素
element = driver.find_element_by_xpath("//div[@id='s-top-left']/a[@class='mnav c-font-normal c-color-t'][1]")
print(element.text)