当前位置: 首页 > article >正文

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

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

相关文章:

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

&#x1f31f;想系统化学习爬虫技术&#xff1f;看看这个&#xff1a;[数据抓取] Python 网络爬虫 - 学习手册-CSDN博客 在使用 Selenium 时&#xff0c;往往需要先定位到指定元素&#xff0c;然后再执行相应的操作。例如&#xff0c;再向文本输入框中输入文字之前&#xff0c;…...

静态网页的爬虫(以电影天堂为例)

一、电影天堂的网址&#xff08;url&#xff09; 电影天堂_免费电影_迅雷电影下载_电影天堂网最好的迅雷电影下载网&#xff0c;分享最新电影&#xff0c;高清电影、综艺、动漫、电视剧等下载&#xff01;https://dydytt.net/index.htm 我们要爬取这个页面上的内容 二、代码…...

将图片存储至阿里云 OSS

将图片存储至阿里云 OSS 一、概述 在项目开发中&#xff0c;我们常常需要处理用户上传的图片。本文将介绍如何使用前端的 el-upload 组件将照片上传到后端&#xff0c;后端再将照片存储到阿里云 OSS&#xff0c;并最终返回图片的 URL 给前端。 二、前端实现 1. 安装依赖 确…...

Android设备是如何进入休眠的呢?

首先我们手机灭屏后&#xff0c;一般需要等一段时间CPU才真正进入休眠。即Android设备屏幕暗下来的时候&#xff0c;并不是立即就进入了休眠模式&#xff1b;当所有唤醒源都处于de-avtive状态后&#xff0c;系统才会进入休眠。在手机功耗中从灭屏开始到CPU进入休眠时间越短&…...

ctfshow做题笔记—栈溢出—pwn65~pwn68

目录 前言 一、pwn65(你是一个好人) 二、pwn66(简单的shellcode&#xff1f;不对劲&#xff0c;十分得有十二分的不对劲) 三、pwn67(32bit nop sled)&#xff08;确实不会&#xff09; 四、pwn68(64bit nop sled) 前言 做起来比较吃力哈哈&#xff0c;自己还是太菜了&…...

高效处理 List<T> 集合:更新、查找与优化技巧

引言 在日常开发中,List<T> 是我们最常用的数据结构之一。无论是批量更新数据、查找特定项还是进行复杂的集合操作,掌握 List<T> 的高级用法可以显著提高代码的效率和可读性。本文将详细介绍如何使用 List<T> 进行批量更新、查找匹配项以及优化性能的方法…...

Java基础系列:深入解析final与static关键字的奥秘与避坑指南

目录 一、final关键字的四重境界 1. 修饰常量&#xff08;成员变量/局部变量&#xff09; 2. 修饰方法&#xff08;禁止重写&#xff09; 3. 修饰类&#xff08;禁止继承&#xff09; 4. 并发控制&#xff08;内存屏障&#xff09; 二、static关键字的四维空间 1. 静态变…...

django各种mixin用法

在 Django 中,Mixin 是一种用于扩展类功能的设计模式。通过 Mixin,可以在不修改原有类的情况下,为其添加新的方法或属性。Django 中的 Mixin 广泛应用于视图(View)、表单(Form)、模型(Model)等组件中。以下是 Django 中常见 Mixin 的用法和示例: 一、视图(View)中的…...

JS中的闭包(closures)一种强大但易混淆的概念

JavaScript 中的闭包&#xff08;closures&#xff09;被认为是一种既强大又易混淆的概念。闭包允许函数访问其外部作用域的变量&#xff0c;即使外部函数已执行完毕&#xff0c;这在状态维护和回调函数中非常有用。但其复杂性可能导致开发者的误解&#xff0c;尤其在变量捕获和…...

Element使用

Element(美化网页&#xff09; ElementUI的使用注意事项&#xff1a; Element.ui的使用基于Vue环境&#xff0c;于是Element相关组件的使用必须放在Vue对象绑定的视图中去 ElementUI的JS库的引入必须放在vue.js库的后面 <!-- 引入样式 --><link rel"styleshee…...

基于YOLO11深度学习的电瓶车进电梯检测与语音提示系统【python源码+Pyqt5界面+数据集+训练代码】

《------往期经典推荐------》 一、AI应用软件开发实战专栏【链接】 项目名称项目名称1.【人脸识别与管理系统开发】2.【车牌识别与自动收费管理系统开发】3.【手势识别系统开发】4.【人脸面部活体检测系统开发】5.【图片风格快速迁移软件开发】6.【人脸表表情识别系统】7.【…...

R语言的基础命令及实例操作

> T & F [1] FALSE > T & T [1] TRUE > T | F [1] TRUE > F | F [1] FALSE > a <- c(T,F,T) > b <- c(F,F,T) > a & b [1] FALSE FALSE TRUE > a | b [1] TRUE FALSE TRUE 在 R 中&#xff0c;大小写是敏感的&#xff0c;也就是说…...

AI视频生成工具清单(附网址与免费说明)

以下是一份详细的AI视频制作网站总结清单&#xff0c;包含免费/付费信息及核心功能说明&#xff1a; AI视频生成工具清单&#xff08;附网址与免费说明&#xff09; 1. Synthesia 网址&#xff1a;https://www.synthesia.io是否免费&#xff1a;免费试用&#xff08;生成视频…...

知识蒸馏综述Knowledge Distillation: A Survey解读

论文链接&#xff1a;Knowledge Distillation: A Survey 摘要&#xff1a;近年来&#xff0c;深度神经网络在工业界和学术界都取得了成功&#xff0c;尤其是在计算机视觉任务方面。深度学习的巨大成功主要归功于它能够扩展以对大规模数据进行编码&#xff0c;并且能够处理数十…...

第十五届蓝桥杯省赛电子类单片机学习过程记录(客观题)

客观试题: 01.典型的BUCK电源电路包含哪些关键器件(ABCD) A. 电容 B. 二极管 C. 电感 D. MOSFET 解析: 典型的 BUCK 电源电路是一种降压型的直流-直流转换电路,它包含以下关键器件: A.电容:电容在电路中起到滤波的作用。输入电容用于平滑输入电压的波动,减少电源噪声对…...

【C++】:STL详解 —— 红黑树封装map和set

目录 红黑树的源代码 正向迭代器的代码 反向迭代器的代码 set的模拟实现 map的模拟实现 红黑树的源代码 #pragma once #include <iostream>using namespace std; // set ->key // map ->key/value// set ->key // map ->key/valueenum Colour {RED,BLAC…...

【QWEN】机器人控制器的控制周期越短精度越高吗

好的&#xff0c;用户问的是“机器人控制器的控制周期越短精度越高吗”。我需要根据提供的知识库内容来回答这个问题。首先&#xff0c;我得回忆一下知识库里的相关信息。 知识库里有几篇相关的文章。比如&#xff0c;[3]提到控制周期越短&#xff0c;控制性能的上限越高&…...

使用数据库和缓存的时候,是如何解决数据不一致的问题的?

1.缓存更新策略 1.1. 缓存旁路模式&#xff08;Cache Aside&#xff09; 在应用里负责管理缓存&#xff0c;读取时先查缓存&#xff0c;如果命中了则返回缓存&#xff0c;如果未命中就查询数据库&#xff0c;然后返回缓存&#xff0c;返回缓存的同时把数据给写入缓存中。更新…...

【c++】平移字符串

说明 实现字符串的左移与右移 示例代码 #include <iostream> #include <string> using namespace std;int main() {string str1 "12345";//左移2位string str2 str1.substr(2) str1.substr(0, 2);cout << str2 << endl;//右移2位&…...

基于Spring Boot的多级缓存架构实现

基于Spring Boot的多级缓存架构实现 以下是一个基于Spring Boot的多级缓存架构实现示例 多级缓存架构实现方案 1. 依赖配置&#xff08;pom.xml&#xff09; <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-star…...

为什么DDPG需要目标网络而A2C不需要?

在强化学习中&#xff0c;DDPG需要目标网络而A2C不需要的主要原因在于算法架构、更新方式和目标稳定性需求的差异&#xff1a; Q值估计的稳定性需求不同 DDPG的Critic网络需要估计状态-动作值函数 Q ( s , a ) Q(s,a) Q(s,a)&#xff0c;其目标值的计算涉及下一个状态的最大Q值…...

蓝桥杯 C++ b组 统计子矩阵深度解析

题目大意&#xff1a;给定一个 NM 的矩阵 A&#xff0c;请你统计有多少个子矩阵 (最小11&#xff0c;最大NM) 满足子矩阵中所有数的和不超过给定的整数 K&#xff1f; 前言&#xff1a;这题很容易想到二维前缀和优化&#xff0c;然后枚举子矩阵&#xff0c;但这样时间复杂度为…...

YOLOv12本地部署教程——42%速度提升,让高效目标检测触手可及

YOLOv12 是“你只看一次”&#xff08;You Only Look Once, YOLO&#xff09;系列的最新版本&#xff0c;于 2025 年 2 月发布。它引入了注意力机制&#xff0c;提升了检测精度&#xff0c;同时保持了高效的实时性能。在保持速度的同时&#xff0c;显著提升了检测精度。例如&am…...

每天五分钟深度学习PyTorch:向更深的卷积神经网络挑战的ResNet

本文重点 ResNet大名鼎鼎,它是由何恺明团队设计的,它获取了2015年ImageNet冠军,它很好的解决了当神经网络层数过多出现的难以训练的问题,它创造性的设计了跳跃连接的方式,使得卷积神经网络的层数出现了大幅度提升,设置可以达到上千层,可以说resnet对于网络模型的设计具…...

C++11新特性 11.基于范围的for循环

一.简介 基本概念&#xff1a; 在 C 中&#xff0c;基于范围的 for 循环&#xff08;Range-based for loop&#xff09;是一种简化容器遍历的语法糖&#xff0c;适用于所有支持 begin() 和 end() 的容器&#xff08;如 vector、map、array 等&#xff09;。以下是其核心用法和…...

Linux搜索---locate

locate locate 是 Linux 系统中用于快速查找文件和目录的命令。它并非实时遍历文件系统&#xff0c;而是通过搜索预先建立的文件数据库来定位文件。该数据库由 updatedb 程序定期&#xff08;通常是每天&#xff09;更新&#xff0c;收录了系统中所有文件的路径信息&#xff0…...

c语言笔记 一维数组与二维数组

1.一维数组和二维数组名加1代表什么意思&#xff0c;偏移多少单位&#xff1f; 方法&#xff1a;1就是以数组的元素类型的字节为单位去偏移。 先看结论再代码验证&#xff1a; 一维数组名&#xff0b;1表示加一个整型单位的偏移量&#xff0c;也可以这么理解1就是以数组的元…...

认识Event Loop【1】

前言 这应该是一个系列文章&#xff0c;因为我觉得Event Loop&#xff08;事件循环&#xff09;是一件很抽象也很重要的一个机制。eventloop这个知识点处于非常杂糅的位置&#xff0c;和很多其他知识&#xff0c;如运行时、浏览器、渲染流程、数据结构、线程等等&#xff0c;也…...

《Linux栈破坏了,如何还原》

【栈破坏导读】栈破坏有了解过吗&#xff1f;何为栈破坏&#xff0c;栈破坏了&#xff0c;程序会立刻引发崩溃&#xff0c;我们通过gdb去调试coredump&#xff0c;栈被破坏的栈帧是没法被恢复的&#xff0c;这也给我们调试程序带来很大的困难&#xff0c;那如何还原栈破坏的第一…...

环形链表问题的探究与代码实现

在数据结构与算法的学习中&#xff0c;环形链表是一个经典的问题。它不仅考察对链表这种数据结构的理解&#xff0c;还涉及到指针操作和逻辑推理。本文将结合代码和图文&#xff0c;深入分析如何判断链表中是否有环以及如何找到环的入口点。 目录 一、判断链表中是否有环 …...