selenium页面元素定位、操作

news2025/1/13 15:31:20

      • 1 打开 / 关闭浏览器
      • 2 打开URL链接
      • 3 定位单个页面元素
        • 3.1 通过ID定位
        • 3.2 通过name定位
        • 3.3 通过classname定位
        • 3.4 通过CSS定位
        • 3.5 通过链接的文本信息定位
        • 3.6 通过XPath定位
          • 3.6.1 xpath语法
          • 3.6.2 实例
      • 4 操作
        • 4.1 基本操作
        • 4.2 切换窗口、框架
      • 5 封装selenium的基本操作
      • 6 判断元素是否存在

  
1、通过页面开发者工具(点击键盘F12或者空白处右击点击检查)中的element,查看页面html代码;
2、点击开发者工具左上角鼠标按钮;
3、鼠标移动至需要定位元素位置;
4、高亮显示;
5、右击选择定位方式。
在这里插入图片描述

1 打开 / 关闭浏览器

from selenium import webdriver
import time
from selenium.webdriver.common.by import By

browser = webdriver.Chrome()
url = 'https://www.csdn.net/'
browser.get(url)
browser.maximize_window()
time.sleep(5)
# browser.close() 
browser.quit() 

注意:
关闭浏览器close和quit的区别:
以下是两个函数的描述,可见close() 只关闭当前窗口;quit() 退出驱动程序并关闭所有相关窗口。

    def close(self) -> None:
        """
        Closes the current window.

        :Usage:
            ::

                driver.close()
        """
        self.execute(Command.CLOSE)

    def quit(self) -> None:
        """
        Quits the driver and closes every associated window.

        :Usage:
            ::

                driver.quit()
        """
        try:
            self.execute(Command.QUIT)
        finally:
            self.stop_client()
            self.command_executor.close()

2 打开URL链接

browser = webdriver.Chrome()
browser.get('https://www.csdn.net/')
browser.maximize_window()
time.sleep(5)
browser.quit()

3 定位单个页面元素

  使用find_element函数来定位元素。

3.1 通过ID定位

  id值在一个页面中是唯一的。

browser = webdriver.Chrome()
browser.get('https://www.csdn.net/')
browser.maximize_window()
time.sleep(5)
browser.find_element(By.ID, "toolbar-search-input").send_keys("python")
time.sleep(5)
browser.find_element(By.ID, "toolbar-search-button").click()
time.sleep(5)
browser.quit()

3.2 通过name定位

  name属性在同一个表单中唯一,但在页面不唯一。若有两个name属性相同的元素,使用该方法会定位到name属性第一次出现的地方。
在这里插入图片描述

browser.find_element(By.NAME, "username").click()

3.3 通过classname定位

  class属性同样不唯一,页面中可能会出现多个,使用该方法定位到的也是第一个拥有该class属性的元素。
在这里插入图片描述

browser.find_element(By.CLASS_NAME, "blog-nav-box").click()

3.4 通过CSS定位

  传入的参数格式:标签名[属性名=属性值],通过标签与属性的组合来唯一的定位页面元素

browser.find_element(By.CSS_SELECTOR, "input[id='toolbar-search-input']").click()

3.5 通过链接的文本信息定位

  这种方法只适合定位链接元素

browser.find_element(By.By.LINK_TEXT, "Python").click()

3.6 通过XPath定位

browser = webdriver.Chrome()
browser.get('https://www.csdn.net/')
browser.maximize_window()
browser.find_element(By.XPATH, '//*[@id="csdn-toolbar"]/div/div/div[3]/div/div[3]/a').click()
browser.find_element(By.XPATH, '//*[@id="toolbar-search-input"]').send_keys("人工智能")
browser.find_element(By.XPATH, '//*[@id="toolbar-search-button"]').click()
time.sleep(5)
browser.quit()
3.6.1 xpath语法
/表示一个层级,从根节点开始定位(绝对路径)
//表示多个层级,从任意位置开始定位
.选取当前节点
..选取当前节点的父节点
@选取属性
*匹配任何元素节点
//*选取文档中的所有元素
@*匹配任何属性节点
//title[@*]选取所有带有属性的title元素
3.6.2 实例
/div/div[3]选取div下的第三个div的元素
//div选取所有div元素,不管他们在文档中的位置
div//title选取div元素的后代的所有title元素
//@lang选取名为lang的所有属性
//title[@lang='eng]选取所有title元素,并且带有值为eng的lang属性
//div|//title选取文档中的所有div和title元素

4 操作

4.1 基本操作

# 清除文本框内容:使用clear()方法
browser.find_element(By.XPATH, '//*[@id="toolbar-search-input"]').clear() 
# 点击
browser.find_element(By.XPATH, '//*[@id="toolbar-search-button"]').click()  
# 填写文本内容
browser.find_element(By.XPATH, '//*[@id="toolbar-search-input"]').send_keys("人工智能") 
# 获取元素的属性信息:使用get_attribute(“属性名”)
browser.find_element(by, element_value).get_attribute('value') 

4.2 切换窗口、框架

 # 切换fram框架, "frame_value"可以是id、name属性值,也可以是序号index,假如有2个iframe
 # 第一个序号就是0
browser.switch_to.frame(frame_value)

# 切换窗口
handles = browser.window_handles # 获取当前全部窗口句柄集合
now_handle = driver.current_window_handle # 获取当前窗口句柄
browser.switch_to.window(now_handle) # 切换至当前窗口

# 切换alert
# accept - 点击【确认】按钮
# dismiss - 点击【取消】按钮(如有按钮)
# send_keys - 输入内容(如有输入框)
alert = switch_to.alert().accept()    #点击确认

5 封装selenium的基本操作

def open_browser0(public_devices):
    """
    打开浏览器------无头模式
    :param public_devices:
    """
    global browser
    ch_options = Options()
    ch_options.add_argument("--headless")  # 为chrome设置无头模式 options=ch_options
    public_devices.driver = webdriver.Chrome()
    log.info("打开浏览器:%s" % public_devices.driver)
    browser = public_devices.driver
    browser.get("http://%s" % public_devices.path)
    log.info("get_url: %s" % public_devices.path)
    browser.maximize_window()
    time.sleep(2)
    
def close_browser():
    """
    logout,并关闭浏览器
    """
    global browser
    browser.quit()
    log.info("关闭浏览器")

@exist
def logout(element_value, element_type):
    """
    退出登录
    """
    global browser
    alert_prencence()
    res = browser.switch_to.default_content()
    log.info("切换至默认frame")
    click_element_by(element_value, element_type)
    log.info("退出登录")

def execute(cmd):
    """
    执行命令
    :param cmd:
    """
    global browser
    log.info(browser.execute(cmd))

def refresh():
    """
    刷新页面
    """
    global browser
    browser.refresh()
    log.info("刷新页面")
    time.sleep(2)

@exist
def check_element(node_element):
    """
    判断用户是否可见该节点元素
    :param node_element:
    :return:
    """
    if node_element.is_displayed():
        return True
    else:
        return False

def switch_to_frame(frame_value):
    """
    切换fame
    :param frame_value:
    """
    global browser
    browser.switch_to.frame(frame_value)
    log.info("切换frame到:%s" % frame_value)

def switch_to_window(window_value, window_type):
    """
    切换浏览器窗口
    :param window_value:
    :param window_type:
    """
    global browser
    handles = browser.window_handles
    log.info(browser.switch_to.window(handles[window_value]))

@exist
def set_element_text(element_value, set_value, element_type):
    """
    输入框输入
    :param element_value:元素定位
    :param set_value:要设置的值
    :param element_type:元素类型,支持id、xpath、link_text、partial_link_text、name、tag_name、class_name、css_selector
    """
    global browser
    by = whichType(element_type)
    browser.find_element(by, element_value).send_keys(set_value)
    log.info("输入:%s", set_value)
    time.sleep(2)

@exist
def clear_element_text(element_value, element_type='XPATH'):
    """
    清空输入框
    :param element_value:元素定位
    :param element_type:元素类型,支持id、xpath、link_text、partial_link_text、name、tag_name、class_name、css_selector
    """
    global browser
    by = whichType(element_type)
    log.info(browser.find_element(by, element_value).clear())
    time.sleep(2)

@exist
def get_text(element_value, element_type):
    """
    获取元素,并打印
    :param element_value:元素定位
    :param element_type:元素类型,支持id、xpath、link_text、partial_link_text、name、tag_name、class_name、css_selector
    """
    global browser
    by = whichType(element_type)
    element = browser.find_elements(by, element_value)
    res = element.__getattribute__('text')
    log.info("获取元素", res)
    return res

@exist
def get_element_attribute(element_value, element_type):
    """
    获取元素属性并返回
    :param element_value:元素定位
    :param element_type:元素类型,支持id、xpath、link_text、partial_link_text、name、tag_name、class_name、css_selector
    :return:
    """
    global browser
    by = whichType(element_type)
    attribute = browser.find_element(by, element_value).get_attribute('value')
    log.info("获取元素属性:%s", attribute)
    return attribute


@exist
def click_element_by(element_value, element_type):
    """
    点击元素
    :param element_value:元素定位
    :param element_type:元素类型,支持id、xpath、link_text、partial_link_text、name、tag_name、class_name、css_selector
    """
    global browser
    by = whichType(element_type)
    log.info("点击元素 %s", element_value)
    browser.find_element(by, element_value).click()
    time.sleep(2)


def alert_prencence():
    result = EC.alert_is_present()(browser)
    if result:
        log.info(result.text)
        result.accept()
    else:
        log.info("未弹出!")

6 判断元素是否存在

  通过添加装饰器,不改变原函数代码、不改变函数返回值,判断元素是否存在。

def exist(func):
    """
    装饰器,判断元素是否存在
    :param func:需要判断元素的函数
    :return:函数
    """
    global browser
    def wrapper(*args, **kwargs):
        keys = inspect.signature(func).parameters  # 得到的是不可迭代对象
        keys_str = str(keys)
        if keys_str.find('element_type') >= 0 and keys_str.find('element_value') >= 0:
            # 变成list后,可根据索引获取参数名对应的参数值
            keys_lis = list(keys)
            index_type = keys_lis.index("element_type") # 获取元素类型索引
            index_value = keys_lis.index("element_value") # 获取元素值索引
            element_type = whichType(args[index_type]) # 取对应索引参数值
            element_value = args[index_value] 
        try:
            WebDriverWait(browser, 5, 0.5).until(EC.presence_of_element_located((element_type, element_value)))
            return func(*args, **kwargs)
        except TimeoutException as e:
            log.error("timeout")
            raise ElementnotFoundException(element_type, element_value)
    return wrapper

class ElementnotFoundException(Exception):
    """
    自定义异常
    :param
    :return:字符串
    """

    def __init__(self, element_type, element_value):
        self.element_type = element_type
        self.element_value = element_value

    def __str__(self):
        log.error("\n找不到元素: %s" % self.element_value)
        # return "\n找不到元素: %s" % self.element_value

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/166428.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Express做后端服务详细步骤,从零到一

文章目录一、全局安装脚手架二、生成项目1.生成项目2.目录结构介绍3.拓展:配置文件热更新(避免改一次文件重启一次服务)步骤1:安装nodemon步骤2:创建nodemon.json文件步骤3:更改启动命令步骤4:上…

如何准确测试相位噪声

相位噪声是表征CW信号频谱纯度的非常重要的参数,衡量了信号频率的短期稳定度。通常所说的相噪为单边带(SSB) 相位噪声,相噪的好坏对于系统的性能至关重要! 对于终端通信而言,如果接收机LO的相噪较差,且在信道附近存在…

GO语言开篇-Go语言急速入门(基础知识点)| 青训营笔记

文章目录一.GO语言应用场景1.1 前言1.2 什么是GO语言1.3 仅仅10行完成高并发的服务器二.入门2.1 基础语法-HelloWorld2.2 基础语法-变量类型2.2.1 变量2.2.2 if else2.2.3 循环2.2.4 switch2.2.5 数组2.2.6 切片2.2.7 map2.2.8 range2.2.9 函数2.2.10 指针2.2.11 结构体2.2.12 …

Java基础之《netty(24)—netty入站与出站机制》

一、基本说明 1、netty的组件设计:netty的主要组件有Channel、EventLoop、ChannelFuture、ChannelHandler、ChannelPipe等。 2、ChannelHandler充当了处理入站和出站数据的应用程序逻辑的容器。 例如,实现ChannelInboundHandler接口(或Chan…

开关电源详解

目录 电源分类 线性稳压电源(LDO) 适用场景 特点 基本组成 开关电源 适用场景 发展方向 特点 分类 基本组成: 开关电源和线性电源对比: 两款开关电源的性能参数对比: 某款电源适配器: 电源分类…

Python NumPy 拆分数组

前言NumPy(Numerical Python的缩写)是一个开源的Python科学计算库。使用NumPy,就可以很自然地使用数组和矩阵。NumPy包含很多实用的数学函数,涵盖线性代数运算、傅里叶变换和随机数生成等功能。本文主要介绍Python NumPy 拆分数组…

2-求和(蓝桥杯)

问题描述给定 nn 个整数 a_1, a_2, , a_na1,a2,⋅⋅⋅,an ,求它们两两相乘再相加的和,即:Sa_{1} \cdot a_{2}a_{1} \cdot a_{3}\cdotsa_{1} \cdot a_{n}a_{2} \cdot a_{3}\cdotsa_{n-2} \cdot a_{n-1}a_{n-2} \cdot a_{n}a_{n-1} \cdot a_…

2022考研人年度总结,描摹23实习备战进行时

今年,是硝烟弥漫的一年在各个科目上努力也常常焦虑不断怀疑是否真的可以在考研的道路上每一件努力的小事看起来无所谓但却十分有必要2022考研热词是“努力” “披星戴月”“痛苦”你的每一个清晨与深夜都刻满了泪水与汗水春天你最爱期待夏天,夏天你说秋天…

JAVA开发运维(CI/CD)

CI :持续性集成CD:持续性部署SIT:系统集成测试UAT:用户验收测试研发流程的变化,因为用户永远一开始不知道自己想要什么样的东西,导致了软件无法从一而终的进行设计,用户需要能立刻运行的软件和功能。&#…

再学C语言36:指针和数组

指针提供了一种用来使用地址的符号方法,可以很有效地处理数组 数组标记实际上是一种变相使用指针的形式 数组名同时也是该数组首元素的地址,如果arr是一个数组,则: arr &arr[0]; 在C中,对一个指针加1的结果是…

【ROS】使用pluginlib自定义costmap地图层

文章目录 文章目录 前言 一、重写地图层 1.包含头文件 2.onInitialize() 3.updateBounds() 4.updateCosts() 二、向ROS注册 1.插件描述文件 2.向ROS注册插件 3.在costmap配置文件中使用 总结 前言 pluginlib是一个 C 库,用于从 ROS 包中加载和卸载插件。插件是从…

SpringBoot实战(十一)集成RebbitMQ

目录1.工作原理图1.1 配置阶段1.2 生产者1.3 消费者2.Maven依赖3.常用交换机类型3.1 direct 直连交换机3.2 fanout 广播交换机3.3 topic 主题交换机4.Direct 直连交换机4.1 yml配置4.2 配置类4.3 消息推送类4.4 消息监听类4.5 测试5.Fanout 广播交换机5.1 配置类5.2 消息推送类…

javascript画全年日历

前些日子闲聊群里有人提了用js画全年日历的需求,趁闲暇时间画了个小demo,下面还是先上效果图吧。 高亮显示的是今天的日期和标记要高亮显示的日期,也添加了点击事件的钩子,自己可以实现钩子函数,从而操作点击的日期值。…

综述 | 深度强化学习在自动驾驶中的应用

本文是2020年的综述论文《Deep Reinforcement Learning for Autonomous Driving: A Survey》的部分内容节选。翻译稿全文共2万6千字,本文略掉了第3、4节强化学习理论的介绍及扩展部分。摘要随着深度表征学习(deep representation learning)的发展,强化学…

【8】SCI易中期刊推荐——图像处理领域(中科院4区)

🚀🚀🚀NEW!!!SCI易中期刊推荐栏目来啦 ~ 📚🍀 SCI即《科学引文索引》(Science Citation Index, SCI),是1961年由美国科学信息研究所(Institute for Scientific Information, ISI)创办的文献检索工具,创始人是美国著名情报专家尤金加菲尔德(Eugene Garfield…

windows下Docker部署Flask的教程

Docker默认安装路径是在C盘,Windows中修改Docker**默认安装****路径方法: 1.先创建 D:\Program Files\Docker 目录 2.运行命令,创建链接 mklink /J "C:\Program Files\Docker" "D:\codeSoftware\Docker"3.点击exe安装…

logstash 向多目标输出多份日志输出syslog

logstash默认情况下是内置了输入syslog日志的,但是不支持输出syslog,需要输出syslog的情况下,就需要手动安装logstash-output-syslog插件。安装方法如下:下载logstash-output-syslog插件,https://rubygems.org/downloa…

SpringBoot 注册自己的Servlet(三种方式)

SpringBoot 注册自己的Servlet(三种方式) 目录SpringBoot 注册自己的Servlet(三种方式)方法1:使用servlet3.0规范提供的注解方式注册Servlet1,声明servlet及映射2,加上ServletComponentScan 才会扫描加了这个注解运行结…

LeetCode 62. 不同路径

🌈🌈😄😄 欢迎来到茶色岛独家岛屿,本期将为大家揭晓LeetCode 62. 不同路径,做好准备了么,那么开始吧。 🌲🌲🐴🐴 一、题目名称 LeetCode 62. …

蚂蚁智能内容合规产品,提供一站式营销合规管控解决方案

随着互联网服务的不断深化,产品营销的形式从传统文本、长图文,增加到短视频、直播等新媒介形态,展现形式愈加丰富的同时,也为营销宣传内容合规审核带来了诸多难题。如何解决与日俱增的审核量与合规审核人员有限之间的矛盾&#xf…