[网络爬虫] 动态网页抓取 — Selenium 元素定位

发布于:2025-03-14 ⋅ 阅读:(38) ⋅ 点赞:(0)

🌟想系统化学习爬虫技术?看看这个:[数据抓取] 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)