目录

基于Python的selenium入门超详细教程第1章-WebDriver-API篇

基于Python的selenium入门超详细教程(第1章)–WebDriver API篇

学习路线 参照博文:[selenium入门超详细教程——网页自动化操作- CSDN博客]( task-blog-2allfirst_rank_ecpm_v1~hot_rank-3-128796839-null- null.142^v102^pc_search_result_base6&utm_term=Web%E6%B5%8B%E8%AF%95selenium&spm=1018.2226.3001.4187 “selenium入门超详细教程——网页自动化操作-CSDN博客”)


前言

前面已经对selenium有了简单的了解,Selenium 是一个用于 Web 应用程序测试的工具集,它能够模拟用户在浏览器中的操作,比如点击按钮、输入文本、切换页面等。通过 Selenium,我们可以轻松地与各种主流浏览器(如 Chrome、Firefox、Edge 等)进行交互,驱动浏览器,模拟浏览器的操作,为自动化测试提供了坚实的基础 并且已经在Python环境下搭建好了selenium环境,从这篇开始,将正式学习selenium的webdriver框架。我们平常说的selenium自动化,其实它并不是类似于QTP之类的有GUI界面的可视化工具,我们要学的是webdriver框架的API。 本篇主要讲如何用Python调用webdriver框架的API,对浏览器元素做一些常规的操作,如定位元素、基本元素的操作,下拉框选择,滚动条,不同层切换,模拟鼠标,模拟键盘,进阶的上传文件,弹出框操作,窗体切换操作。

一、WebDriver API介绍

1.1 什么是WebDriver?

WebDriver API 是 Selenium 自动化测试框架中的核心部分,它提供了一组用于自动化浏览器操作的编程接口,通过这些接口,测试人员或者开发者能够模拟用户在浏览器中的各种行为,实现对 Web 应用程序的自动化测试。

1.2 工作原理

WebDriver 通过与浏览器的驱动程序进行通信来实现对浏览器的控制。不同的浏览器需要使用相应的驱动程序,如 Chrome 浏览器需要使用 ChromeDriver,Firefox 浏览器需要使用 GeckoDriver。当你调用 WebDriver API 中的方法时,这些指令会被发送到对应的浏览器驱动程序,驱动程序再将指令转化为浏览器可以理解的操作,从而实现对浏览器的自动化控制。即:

  • 客户端编写脚本—>运行浏览器驱动—>打开浏览器—>执行脚本

二、基础用法

首先,确保你已经安装了Python和Selenium库以及相应的浏览器驱动 注:本文采用的是selenium4.0版本,部分语句同其他文章可能存在不一致现象 #导入webdriver模块 from selenium import webdriver #最新的 Selenium 4 版本中,引入了 Service 类来更好地管理浏览器驱动服务 from selenium.webdriver.chrome.service import Service #selenium4.0版本语法 #写入之前解压保存的路径,获取浏览器驱动 e=Service(executable_path=r’D:\WebDriver\MicrosoftWebDriver.exe’) #使用浏览器驱动,打开浏览器 driver=webdriver.Edge(service=e)

针对浏览器本身

  • 打开网页

打开百度网址

driver.get(“ ) #访问百度

  • 设置窗口大小和位置

有时需要测试网站在不同屏幕尺寸下的显示效果,确保页面元素在各种分辨率和显示设备上均能正确显示和操作。

driver.set_window_size(1024, 768) #设置窗口尺寸(width,height) driver.maximize_window() #最大化窗口 driver.set_window_position(100,200) #设置窗口位置(x,y)

  • 设置休眠

selenium4.0版本存在程序执行完成后自动关闭窗口的现象,此外有时页面加载过久,而又需要等待某些操作完成,此时可以通过设置休眠时间强制让程序暂停执行一段时间

from time import sleep sleep(2) #停止2s,可以是小数,以秒为单位

  • 退出

退出有两种方式,一种是close;另外一种是quit

close方法用于关闭当前窗口或标签,但不会退出浏览器会话,如果只有一个标签页,close 会关闭浏览器

quit方法用于退出浏览器会话,关闭所有窗口和标签,结束webdriver进程,可以回收c盘的临时文件

driver.close() driver.quit()

以上是本文将会使用到的基本方法语句,想要再深入了解其他用法可查询:[python+selenium自动化软件测试(第2章):WebDriver API

  • Web自动化测试 - 博客园]( “python+selenium自动化软件测试(第2章):WebDriver API - Web自动化测试 - 博客园”)

★定位标签元素

from selenium.webdriver.common.by import By(导入类By) driver.find_element(By.元素属性,值).操作名() #根据元素属性和值找到唯一对应元素并执行相关操作 元素定位和操作是使用selenium进行自动化测试非常核心和关键的步骤,通过元素定位可以找到Web页面上的各种元素,如文本框、按钮、链接等,从而进行后续的操作

补充:

可以前往该网页了解各HTML前端网页标签的含义,帮助更好的定位元素

或查看博文:【等我写一篇啊】

元素属性常用操作
ID:id值输入:send_keys(‘要输入的内容’)
NAME:name值点击:click()
CLASS_NAME:class值选择:select 下拉列表操作
LINK_TEXT:超链接的内容 它通过匹配超链接的完整文本来找到对应的元素获取元素的文本值:元素.text
PARTIAL_LINK_TEXT:部分超链接的内容获取元素的属性:el1.get_attribute(“name”)
TAG_NAME:标签名 【不常用】 Tag Name是HTML标签的名称,例如 < input>< button>、 _< a>_等
XPATH:路径 在 XML 文档中对元素和属性进行遍历, 使用路径表达式来选取 XML 文档中的节点或者节点集,例如//div[@class=“file”]/button
CSS_SELECTOR:css
以百度为例,我们进入首页,按 【F12】
进入开发者工具。红框中显示的就是页面的代码,我们要做的就是从代码中定位获取我们需要的元素。使用途中框选出的选择工具可以快速查询某一特点标签元素的详情,例如查找这里百度一下的输入框
https://i-blog.csdnimg.cn/direct/188494ce8dfe4b928f127fad444146b2.png
可以看到这个y有对应的class,name以及id

定位标签元素最基础的方法和操作

driver.find_element(By.ID, ‘id_value’).click() driver.find_element(By.NAME, ’name_value’).send_keys(‘要输入的内容’) driver.find_element(By.CLASS_NAME, ‘class_name’) driver.find_element(By.LINK_TEXT, ‘all_link_text’) driver.find_element(By.PARTIAL_LINK_TEXT, ‘partial_link_text’) driver.find_element(By.TAG_NAME, ’tag_name’)

针对select下拉框标签元素的select操作

https://i-blog.csdnimg.cn/direct/4738a04d7b804f40ba7c38e30847c21f.png 针对该下拉框标签的相关操作,可以通过先定位select框,再定位select里的选项的二次定位方法,或通过XPATH遍历路径直接定位;但selenium还提供了更高级的玩法,通过导入Select模块。直接根据属性或索引定位 #下拉框的选择 标签名: ##导入select模块,选择Select类 from selenium.webdriver.support.select import Select select_elem=driver.find_element(By.ID,‘role’) #获取下拉框元素

Select(select_elem).select_by_index(2) #根据select的option索引

Select(select_elem).select_by_value(‘pm’) #根据option的value

Select(select_elem).select_by_visible_text(‘项目经理’) #根据显示的值

切换iframe层

有时我们会发现就算显示在了当前界面中没被遮挡,定位的方式也换了很多种但就是不能定位到想要的标签元素。这可能是由于元素处在标签元素下 在Web页面中,有时候会存在iframe(内联框架)元素,也就是嵌套在页面中的另一个页面,通过iframe可以将多个不同的页面内容组合在一起。在自动化测试中,当页面中存在iframe时,Selenium需要切换到对应的iframe中才能操作其中的元素。 因此,Selenium提供了switch_to_frame方法来实现在不同的iframe之间进行切换,使得测试脚本可以准确地定位到需要操作的元素 不在同一层:切换层,切换到不同的iframe里面; 若存在iframe嵌套关系,需要多次切换 https://i-blog.csdnimg.cn/direct/c8613e85c1c846ddaa0cd9a4e3960b20.png #切换层,切换到不同的iframe,switch_to.frame(id/name/index) driver.switch_to.frame(‘appIframe-admin’) #切换到对应层 driver.find_element(By.LINK_TEXT, ‘人员’).click() switch_to.default_content() #切回默认层

延时等待

有时我们会发现,明明定位方式无误,元素也确实存在于页面中,但在执行定位元素的操作时却抛出找不到元素的异常。这可能是由于页面元素的加载需要一定时间,而代码执行速度过快,在元素还未完全加载到页面上时就尝试进行定位操作。 在 Web 页面中,元素的加载速度受到多种因素的影响,比如网络状况、服务器响应时间、页面的复杂度等。一些动态加载的元素,如通过 AJAX 技术加载的内容,可能需要在页面加载完成后额外的时间才能显示出来。在自动化测试中,如果不考虑这些因素,直接进行元素定位和操作,很容易导致测试失败。 因此,Selenium 提供了延时等待机制,让脚本在执行过程中暂停一段时间,等待元素加载完成后再进行后续操作,从而确保测试脚本能够准确地定位和操作元素

等待方式用法
强制等待time模块的sleep()方法,让进程强制停止运行
显示等待直到指定元素出现为止,结束等待;若超出指定时间则返回异常
隐式等待浏览器在设定的时间内不断刷新页面来寻找元素,加隐式等待可显著提升测试脚本运行速度

显示等待

原理:显示等待,就是明确的要等到某个元素的出现或者是某个元素的可点击等条件,等不到,就一直等,除非在规定的时间之内都没找到,那么久跳出Exception。(简而言之,就是直到元素出现才去操作 ,如果超时则报异常) 语法:WebDriverWait(driver,timeout,poll_frequency=0.5,ignored_exceptions=None)

  1. driver:WebDriver对象,即浏览器驱动对象,用于执行浏览器操作。
  2. timeout:最长等待时间,即等待条件成立的最大时长。如果超过这个时间条件仍未成立,则抛出TimeoutException异常。
  3. poll_frequency:检测条件变化的时间间隔,默认为0.5秒。即每隔poll_frequency秒检查一次条件是否成立。
  4. ignored_exceptions:在等待过程中忽略的异常类型。如果设置了该参数,当被忽略的异常发生时,不会导致等待失败。 from selenium.webdriver.support.ui import WebDriverWait #等待方法 from selenium.webdriver.support import expected_conditions as EC #结束等待情况

退出禅道

if WebDriverWait(driver,10).until(EC.presence_of_element_located((By.ID,‘appIframe-my’))): #等待By.ID,‘appIframe-my’元素出现,等待结束

until(method,message=‘’)

method: 在等待期间,每隔一段时间调用这个传入的方法,直到返回值不是False

message: 如果超时,抛出TimeoutException,将message传入异常

until_not(method,message=‘’): 与until相反,until是当某元素出现或什么条件成立则继续执行,until_not是当某元素消失或什么条件不成立则继续执行,参数也相同。 其中until(EC.presence_of_element_located())指的是当指定元素出现是结束等待,还有如下其他几种情况: from selenium.webdriver.support import expected_conditions as EC

判断标题是否和预期的一致

title_is

判断标题中是否包含预期的字符串

title_contains

判断指定元素是否加载出来

presence_of_element_located

判断所有元素是否加载完成

presence_of_all_elements_located

判断某个元素是否可见. 可见代表元素非隐藏,并且元素的宽和高都不等于0,传入参数是元组类型的locator

visibility_of_element_located

判断元素是否可见,传入参数是定位后的元素WebElement

visibility_of

判断某个元素是否不可见,或是否不存在于DOM树

invisibility_of_element_located

判断元素的 text 是否包含预期字符串

text_to_be_present_in_element

判断元素的 value 是否包含预期字符串

text_to_be_present_in_element_value #判断frame是否可切入,可传入locator元组或者直接传入定位方式:id、name、index或WebElement frame_to_be_available_and_switch_to_it #判断是否有alert出现 alert_is_present #判断元素是否可点击 element_to_be_clickable

判断元素是否被选中,一般用在下拉列表,传入WebElement对象

element_to_be_selected

判断元素是否被选中

element_located_to_be_selected

判断元素的选中状态是否和预期一致,传入参数:定位后的元素,相等返回True,否则返回False

element_selection_state_to_be

判断元素的选中状态是否和预期一致,传入参数:元素的定位,相等返回True,否则返回False

element_located_selection_state_to_be #判断一个元素是否仍在DOM中,传入WebElement对象,可以判断页面是否刷新了 staleness_of

隐式等待

原理:隐式等待,就是在创建driver时,为浏览器对象创建一个等待时间,这个方法是得不到某个元素就等待一段时间,直到拿到某个元素位置。 注意:在使用隐式等待的时候,实际上浏览器会在你自己设定的时间内不断的刷新页面去寻找我们需要的元素 需要特别说明的是: 隐性等待对整个 driver 的周期都起作用,所以只要设置一次即可(在最开始设置一次就可以了),切不要当作固定等待使用。 ###隐式等待:浏览器在设定的时间内不断刷新页面来寻找元素

加隐式等待可显著提升测试脚本运行速度

implicitly_wait()设置等待时间,如果到时间有元素节点没有加载出来,就会抛出异常

from selenium import webdriver from selenium.webdriver.chrome.service import Service e=Service(executable_path=r’D:\WebDriver\MicrosoftWebDriver.exe’) #写入之前解压保存的路径 driver=webdriver.Edge(service=e) #获取浏览器驱动 driver.implicitly_wait(10)

模拟鼠标操作ActionChains

既然是模拟浏览器操作,自然也就需要能模拟鼠标的一些操作了,这里需要导入ActionChains 类。 from selenium.webdriver.common.action_chains import ActionChains

常用操作

操作函数
右击context_click()
双击double_click()
拖拽double_and_drop()
悬停move_to_element()
执行perform()
#鼠标事件
from selenium.webdriver.common.action_chains import ActionChains
driver.maximize_window() #窗口最大化
driver.get(r"https://www.baidu.com/”) #访问baidu
target_elem=driver.find_element(By.ID,’s-usersetting-top’)
ActionChains(driver).move_to_element(target_elem).perform()
time.sleep(10)

模拟键盘操作Keys

既然是模拟浏览器操作,自然也就需要能模拟键盘的一些操作了,这里需要导入Keys类。 from selenium.webdriver.common.keys import Keys

常用操作

操作函数
删除键 backspacesend_keys(Keys.BACK_SPACE)
空格键 spacesend_keys(Keys.SPACE)
制表键 tabsend_keys(Keys.TAB)
回退键 escsend_keys(Keys.ESCAPE)
回车 entersend_keys(Keys.ENTER)
全选 ctrl+asend_keys(Keys.CONTRL,‘a’)
复制 ctrl+csend_keys(Keys.CONTRL,‘c’)
剪切 ctrl+xsend_keys(Keys.CONTRL,‘x’)
粘贴 ctrl+vsend_keys(Keys.CONTRL,‘v’)
键盘F1键send_keys(Keys.F1)
#键盘事件
from selenium.webdriver.common.keys import Keys
driver.maximize_window() #窗口最大化
driver.get(r"https://www.baidu.com/") #访问baidu
driver.find_element(By.ID,‘kw’).send_keys(“python学习路线”)
driver.find_element(By.ID,‘kw’).send_keys(Keys.BACK_SPACE)
time.sleep(10)

三、进阶用法

XPATH和CSS_SELECTOR方法定位元素,搭配使用Chropath与Xpath helper插件

XPATH:

  • 绝对路径查找元素 从根节点位置到目标位置 /html/body/div[2]/table/tbody/tr[1]/td[1]
  • 相对路径查找元素 从指定节点位置到目标位置 //table[@class=‘tb’]/tbody/tr[1]/td[1] CSS_SELECTOR: By.CSS_SELECTOR, ‘div p’| 获取

标签内部所有的

标签元素
By.CSS_SELECTOR, ’div>p‘获取所有父亲标签为

标签元素 By.CSS_SELECTOR, ’div+p‘ | 获取所有紧接在

标签之后的

标签元素 By.CSS_SELECTOR, ‘#d2’| 获取所有id属性值为d2的标签元素 By.CSS_SELECTOR, ‘.td’ | 获取所有class属性值为td的标签元素 By.CSS_SELECTOR, ’[text-align=“center”]‘| 获取其他属性,例如text-align属性值为center的所有标签元素 By.CSS_SELECTOR, ‘[type]’| 获取带有type属性的所有标签元素 By.CSS_SELECTOR, ‘[type~=“text”]’| 获取带有type属性且属性值包含text的所有标签元素,模糊查询 By.CSS_SELECTOR, ‘a[href^=“https”]’ | 获取所有标签的href属性值以https开头的所有标签元素 By.CSS_SELECTOR, ‘a[src$=".jpg"]’| 获取所有标签的src属性值以.jpg结尾的所有标签元素 By.CSS_SELECTOR, ‘a[src*=“xxx”]’| 获取所有标签的src属性值包含xxx的所有标签元素 By.CSS_SELECTOR, ‘’.tb2 td:nth-child(n)’ | 获取class属性值为tb2父标签的第n个子元素的所有 标签元素 注:多个列表值用find_elements()方法,以列表形式返回 一般来说xpath和css_selector方式定位元素较为复杂,首先考虑基础定位元素方法能否简便的定位元素然后再考虑使用该两种方法,同时可以借助Xpath_helper和Chropath插件帮助我们编写XPATH和CSS_SELETOR的定位语句 这里介绍Edge如何下载: https://i-blog.csdnimg.cn/direct/1a7692b212904f0eb476a95e32bef7fd.png https://i-blog.csdnimg.cn/direct/8e6536ab6e50468dae8b338b32d6989f.png https://i-blog.csdnimg.cn/direct/969e47740f514c2ab3dd656b1dc79943.png 重启浏览器后,打开此扩展 即可使用 https://i-blog.csdnimg.cn/direct/79fb0786c7d14064b1f2e264c8fe1942.png chropath安装地址: 使用方法参照博文:[xpath-helper、chropath下载使用方式 及 selenium中如何配置浏览器插件- CSDN博客]( task- blog-2defaultbaidujs_baidulandingworddefault-0-121788824-blog-143385273.235^v43^pc_blog_bottom_relevance_base4&spm=1001.2101.3001.4242.1&utm_relevant_index=3 “xpath-helper、chropath下载使用方式 及 selenium中如何配置浏览器插件-CSDN博客”) ### 上传文件与Spy++ 搭配Spy++工具实现上传文件 下载路径: 使用参照:[Microsoft SPY++ 使用教程及实操- CSDN博客]( task-blog-2alltop_clickdefault-1-138137983-null- null.142^v102^pc_search_result_base6&utm_term=spy%20%20%20&spm=1018.2226.3001.4187 “Microsoft SPY++ 使用教程及实操-CSDN博客”) 步骤 1. 使用Spy++来识别上传文件对话框窗口的窗口控件信息,包括窗口句柄、控件类名、控件ID等。 2. 导入pywin32库,在Selenium中使用相关的命令和方法,通过窗口句柄或其他标识找到对应的控件,并进行操作。 3. 通过Selenium的方法模拟点击上传文件按钮、输入文件路径等操作,实现文件上传功能。 https://i-blog.csdnimg.cn/direct/c3353a674c5943659bbb73bb96fdb13d.png https://i-blog.csdnimg.cn/direct/4a110e65328d435287c817a7b4bc2fac.png 上传文件 import win32gui import win32con win1=win32gui.FindWindow(’#32770’,‘打开’) #查找第一层窗体 win2=win32gui.FindWindowEx(win1,None,‘ComboBoxEx32’,None) #查找第二层窗体 win3=win32gui.FindWindowEx(win2,None,‘ComboBox’,None) #查找第三层窗体 # edit=win32gui.FindWindowEx(win3,None,‘Edit’,None) #查找第三层窗体下的填写文件路径文本框 button=win32gui.FindWindowEx(win1,None,‘Button’,‘打开(&O)’) #查找第一层窗体下的打开按 if win3: #检查是否正常获取到窗体 # 查找编辑框控件 edit = win32gui.FindWindowEx(win3, None, ‘Edit’, None) # 查找第三层窗体下的填写文件路径文本框 if edit: text = r’C:\Users\92870\Desktop\Rose introduction.txt’ win32gui.SendMessage(edit, win32con.WM_SETTEXT,None, text) else: print(“未找到编辑框控件”) else: print(“未找到主窗口”) # win32gui.SendMessage(edit,win32con.WM_SETTEXT,0,r’C:\Users\92870\Desktop\Rose introduction.txt’) #填写文件路径 win32gui.SendMessage(win1,win32con.WM_COMMAND,1,button) 参照博文: ### 两大切换 #### 切换到弹出框 https://i-blog.csdnimg.cn/direct/deca321c40a74598926657afb1fd09af.png #弹出框 ##法一: alert_dialog=driver.switch_to.alert #切换到弹出框 content1=alert_dialog.text #获取弹出框内容 alert_dialog.accept() #确认 alert_dialog.dismiss() #取消 print(content1) ##法二 from selenium.webdriver.common.alert import Alert content2=Alert(driver).text Alert(driver).accept() print(content2) #### 切换窗体 在 selenium 操作页面的时候,可能会因为点击某个链接而跳转到一个新的页面(打开了一个新标签页),这时候 selenium 实际还是处于上一个页面的,需要我们进行切换才能够定位最新页面上的元素。 窗口切换需要使用 switch_to.windows() 方法。 https://i-blog.csdnimg.cn/direct/d8520d45958c4128b4a3121adde8a61c.png #窗体切换 current_hanler = driver.current_window_handle #保存当前窗口编号 js=‘window.open(“ ”);’ driver.execute_script(js) #新打开窗口 time.sleep(2) driver.switch_to.window(current_hanler) #切换回保存的窗口 handles = driver.window_handles #系统以列表形式存储窗体编号 driver.switch_to.window(handles[0]) #根据索引切换窗体 ## 四、JS操作 ### 滚动条 在进行Web页面自动化测试时,因为只能获取当前页面所显示的标签元素,有时候页面内容会很长,存在元素被挡住的问题。因此,学习滚动条操作有助于更加全面的定位标签元素 # 滚动条 ## 直接设置滚动条位置 js=‘var q=document.body.ScrollTop=10000’ driver.execute_script(js) ## 拖动到可见的元素位置 target = driver.find_element(By.XPATH,’//div[@class=“file-input-empty”]/button’) #被挡住的元素 time.sleep(1) #等待拖动完成 driver.execute_script(“arguments[0].scrollIntoView();”, target) 可以提前判断需要定位的元素是否被遮挡了 def is_element_exist(browser,xpath): try: element=browser.find_element(by=By.XPATH,value=xpath) flag=True #未被遮挡,返回true except: flag=False #被遮挡,返回false return flag 若还想深入了解可查看: ## 常见问题: ### 找不到对象 原因| 解决方法 —|— 反应时间太短,元素未生成| sleep()、显示等待、隐式等待 不在同一iframe层| 切换层,切换到不同的iframe里面;若存在iframe嵌套关系,需要多次切换 元素定位方式设置地不正确| 检查元素定位方式是否正确,尝试使用不同的定位方式进行定位 元素被挡住,不在当前的显示页面上| 添加滚动条,滚动到对应元素位置 ### 学习过程中的问题记录 https://i-blog.csdnimg.cn/direct/d6f4b65050bd460e83c07c442e4e5e92.png 在 HTML 代码中,虽然看起来标签内的文本是 `" 添加用户"`,开头有一个空格和双引号,但实际上在使用`By.LINK_TEXT`定位时,不应该包含这个空格和双引号 空格原因如下: * **渲染后的实际文本** :在浏览器渲染页面时,对于标签内的文本,通常会自动忽略开头和结尾的空白字符,包括空格、换行符等。所以用户实际看到的可见文本是 “添加用户”,而不是 “ 添加用户”。`By.LINK_TEXT`是根据用户在页面上实际看到的可见文本进行定位的,所以不需要包含开头的空格。 * **Selenium 定位机制** :Selenium 的`By.LINK_TEXT`定位策略是基于页面渲染后的文本内容来查找元素的。它会按照浏览器呈现给用户的文本进行匹配,而不是严格按照 HTML 源代码中的文本格式。如果按照 HTML 源代码中的格式,包含了不必要的空格等空白字符,反而可能导致定位失败。 双引号原因如下: * **渲染后的实际文本** :虽然 HTML 代码中写成 `... ”添加用户“ ...`,但在浏览器渲染页面后,引号(`”`)通常不会作为可见文本的一部分显示给用户。浏览器会将其视为普通的 HTML 文本格式标记,而不是要显示的内容。用户在页面上看到的就是 “添加用户” 这四个字,没有引号。 * **Selenium 定位机制** :Selenium 的`By.LINK_TEXT` 定位策略是根据页面上实际可见的文本内容来匹配元素的。它会去查找页面中显示的文本与传入的 `value` 完全一致的 标签元素。所以,为了能准确匹配到目标元素,value 应该是页面上实际显示的 “添加用户”,而不是包含引号的 ““添加用户””。 * 特殊情况处理: 如果引号确实是作为可见文本的一部分显示在页面上,那么在使用 By.LINK_TEXT 时,value 就需要包含引号,即 '“添加用户”'。但从常见的网页设计来看,引号一般不会作为链接文本的一部分显示,所以大多数情况下使用 '添加用户' 即可。 https://i-blog.csdnimg.cn/direct/eca3ab70de0048158ae89c43c3f4349a.png 在 HTML 代码中,虽然看起来 标签内的文本 “测试” 是写在 标签里,但实际上在使用 By.LINK_TEXT 定位时,依然可以用 “测试” 来定位 标签,原因如下: * **渲染后的实际文本** :在浏览器渲染页面时, 标签作为一个整体的链接元素,其内部包含的所有子元素(如 标签)的文本内容会被整合并显示为该链接的可见文本。 标签通常用于对文本进行样式或语义上的修饰,浏览器会将 内的文本与 标签其他部分的内容(如果有的话)组合成一个完整的可见文本呈现给用户。所以用户实际看到的 标签的可见文本就是 “测试”,`By.LINK_TEXT` 是根据用户在页面上实际看到的可见文本进行定位的,因此可以直接使用 “测试” 来定位。 * **Selenium 定位机制** :Selenium 的 `By.LINK_TEXT` 定位策略是基于页面渲染后的文本内容来查找元素的。它关注的是用户在浏览器中实际能看到的文本信息,而不是 HTML 代码的具体结构。无论文本是直接写在 标签内,还是包含在 标签的子元素(如)中,只要最终呈现给用户的文本是 “测试”,就可以使用该文本进行定位。如果过于关注 HTML 结构,而不考虑渲染后的实际文本,反而可能导致定位失败。 附录代码(登录禅道–添加用户–删除用户–退出禅道) import time from selenium import webdriver from selenium.webdriver.edge.service import Service #使用浏览器驱动的方法 from selenium.webdriver.common.by import By from selenium.webdriver.support.select import Select import unittest class TestCases(unittest.TestCase): def init(self): # selenium4.0 e = Service(executable_path=r’D:\WebDriver\MicrosoftWebDriver.exe’) # 写入之前解压保存的路径 self.driver = webdriver.Edge(service=e) self.driver.maximize_window() # 窗口最大化 self.driver.get(“http://127.0.0.1:81/zentao/user-login.html”) # 访问禅道登录界面 def login_case(self): #登录禅道 self.driver.find_element(By.ID,‘account’).send_keys(‘admin’) #输入用户名 self.driver.find_element(By.NAME,‘password’).send_keys(‘password123456’)#输入密码 self.driver.find_element(By.ID,‘submit’).click() time.sleep(0.5) #有时界面刷新的慢,元素还未生成,可能导致找不到对应的元素 def adduse_users(self): #添加用户 self.driver.find_element(By.LINK_TEXT, ‘后台’).click() time.sleep(0.5) #切换层,切换到不同的iframe,switch_to.frame(id/name/index) self.driver.switch_to.frame(‘appIframe-admin’) #切换到对应层 self.driver.find_element(By.LINK_TEXT, ‘人员’).click() self.driver.find_element(By.LINK_TEXT,‘添加用户’).click() time.sleep(0.5) self.driver.find_element(By.NAME,‘account’).send_keys(’tester0011’) self.driver.find_element(By.ID,‘password1’).send_keys(‘password001’) self.driver.find_element(By.ID,‘password2’).send_keys(‘password001’) self.driver.find_element(By.ID,‘realname’).send_keys(’tester0011’) #下拉框的选择 标签名: ##导入select模块,选择Select类 from selenium.webdriver.support.select import Select select_elem=self.driver.find_element(By.ID,‘role’) #获取下拉框元素 Select(select_elem).select_by_visible_text(‘项目经理’) #根据显示的值 time.sleep(0.5) #添加滚动条 js=‘var q=document.documentElement.scrollTop=200’ self.driver.execute_script(js) self.driver.find_element(By.ID,‘verifyPassword’).send_keys(‘password123456’) self.driver.find_element(By.ID,‘submit’).click() time.sleep(0.5) def deluser_case(self): # 搜索并删除用户 ##搜索 self.driver.find_element(By.ID, ‘bysearchTab’).click() self.driver.find_element(By.ID, ‘value1’).send_keys(’tester0011’) self.driver.find_element(By.ID, ‘submit’).click() time.sleep(0.5) ##删除 self.driver.find_element(By.CLASS_NAME, ‘icon-trash’).click() self.driver.switch_to.frame(‘iframe-triggerModal’) self.driver.find_element(By.ID, ‘verifyPassword’).send_keys(‘password123456’) self.driver.find_element(By.ID, ‘submit’).click() # def logout_case(self): # 退出禅道 self.driver.switch_to.frame(‘appIframe-my’) self.driver.find_element(By.LINK_TEXT, ‘A’).click() self.driver.find_element(By.LINK_TEXT, ‘退出’).click() time.sleep(10) |