Xpath 表达式选择元素及JS执行

Xpath 表达式选择元素及JS执行

目的:了解XPath表达式的含义,掌握XPath绝对路径和相对路径的表达方法,能够熟练使用XPath表达式进行元素选择;了解Selenium应用execute_script()函数执行JS的原理,能够在自动化测试过程中完成JS常用操作的执行。

要求:在pycharm 环境下完成实验目的中所述各项任务

条件:win7/10、pycharm、selenium4.4.0

内容及步骤:

XPath (XML Path Language) 是由国际标准化组织W3C指定的,用来在 XML 和 HTML 文档中选择节点的语言。目前主流浏览器 (chrome、firefox,edge,safari) 都支持XPath语法。因此,在做Web自动化测试时,可以使用XPath表达式进行元素选择。

https://cdn2.byhy.net/files/selenium/test1.html 网页中验证下列内容。

一、 XPath中绝对路径的表达:

从HTML文档根节点开始,到某个节点,每层都依次写下来,每层之间用 / 分隔的表达式,就是某元素的绝对路径。可见, / 有点像 CSS中的 > , 表示直接子节点关系。

使用Xpath来选择web元素,应该调用 WebDriver对象的 find_element() 或者 find_elements()方法,其中参数要使用 By.XPATH。

例如:elements = driver.find_elements(By.XPATH, "/html/body/div")

二、 XPath中相对路径的表达:

在xpath语法中, // 表示从当前节点往下寻找所有的后代元素,不管这个元素在什么位置。这种表示方法就是相对路径。

比如想要选择网页中某一类元素,如:选择所有标签名为 div 的元素,语法为: //div

'//' 符号也可以继续加在后面。比如,要选择所有的 div 元素里面的所有的 p 元素 ,不管div在什么位置,也不管p元素在div下面的什么位置,则可以这样写 //div//p

具体代码为:elements = driver.find_elements(By.XPATH, "//div//p")

相当于CSS选择器的:elements = driver.find_elements(By.CSS_SELECTOR, "div p")

注意,如果要选择 所有的 div 元素里面的 直接子节点 p:

Xpath表示为:elements = driver.find_elements(By.XPATH, "//div/p")

CSS表示为:elements = driver.find_elements(By.CSS_SELECTOR, "div > p")

三、 XPath中通配符的使用:

* 是一个通配符,对应任意节点名的元素。

如果要选择所有div节点的所有直接子节点,可以使用表达式 //div/*

四、 XPath根据属性选择元素:

语法为: [@属性名='属性值']

  1. 根据id属性选择:

例如:选择 id 为 west 的元素,写成: //*[@id='west']

  1. 根据class属性选择:

例如:选择所有 select 元素中 class为 single_choice 的元素,写成://select[@class='single_choice']

注意:对于一个元素class 有多个值时要写完整,如://p[@class='capital huge-city']

  1. 根据其它属性选择:

例如:选择具有 multiple 属性的所有页面元素,写成://*[@multiple]

  1. 根据属性值包含的字符串选择:

a. 要选择 style属性值 包含 color 字符串的页面元素,写成://*[contains(@style,'color')]

b. 要选择 style属性值 以 color 字符串 开头的页面元素,写成://*[starts-with(@style,'color')]

c. 要选择 style属性值 以 color 字符串 结尾的页面元素,应写成: //*[ends-with(@style,'color')],但这是xpath 2.0 的语法,目前浏览器都不支持。

五、 XPath根据元素在父节点中的次序进行选择:

其语法为:直接在方括号中使用数字表示次序。

  1. 根据某类型第几个子元素选择:

例如:要选择 p类型第2个的子元素,写成: //p[2]

注意,这里表示的是p类型的第2个子元素,不是指“第2个子元素,并且是p类型”。

又如: //div/p[2] 表示要选取父元素为div 中的 p类型下第2个子元素

  1. 根据某类型倒数第几个子元素选择:倒数使用last()

例如://p[last()] 表示选取p类型中倒数第1个子元素;

//p[last()-1] 则表示选取p类型中倒数第2个子元素

又如://div/p[last()-2] 表示选择父元素为div中p类型倒数第3个子元素

  1. 根据次序范围选择:

例如:要选取option类型第1到2个子元素,写成: //option[position()<=2]//option[position()<3]

又如:要选择class属性为multi_choice的前3个子元素,写成: //*[@class='multi_choice']/*[position()<=3]

而选择class属性为multi_choice的后3个子元素,要写成://*[@class='multi_choice']/*[position()>=last()-2]

注意:在选择元素过程中,如果分两步完成:先定位到一个元素,再要在此元素内部使用XPath选择元素, 必须在XPath表达式最前面加个点,否则表示的范围是整个页面。\

# 先寻找id是china的元素
china = wd.find_element(By.ID, 'china')

# 再选择该元素内部的p元素
elements = china.find_elements(By.XPATH, './/p')

# 打印结果
for element in elements:
	print('---------------')
	print(element.get_attribute('outerHTML'))

六、 XPath中的组选择:

在选择满足多个表达式要求的所有元素时,XPath的表达式多个表达式间是用 竖线 隔开。

例如:要选所有的option元素和所有的 h4 元素,写成://option | //h4

等同于CSS选择器的:option , h4

又如:要选所有的 class 为 single_choice 和 class 为 multi_choice 的元素,写成: //*[@class='single_choice'] | //*[@class='multi_choice']

等同于CSS选择器的: .single_choice , .multi_choice

七、 XPath中向上选择父节点:

XPath中不仅可以根据元素在父节点中的次序进行选择,还可以选择某个元素的父节点,我们用 /… 表示。当某个元素没有特征可以直接选择,但是它的某个子节点有特征, 就可以采用这种方法,先选择子节点,再指定父节点。

例如:要选择 id 为 china 的节点的父节点,写成: //*[@id='china']/..

还可以继续找上层父节点,比如: //*[@id='china']/../../..

八、 XPath中兄弟节点的选择:

  1. 选择后续兄弟节点:

这与 CSS选择器要选择某个节点的后续兄弟节点时,用波浪线是不同的。其语法为: following-sibling::

例如,要选择 class 为 single_choice 的元素的所有后续兄弟节点,写成: //*[@class='single_choice']/following-sibling::* ,等同于CSS选择器 .single_choice ~ *

不选择所有后续兄弟节点,而要选择后续节点中的div节点,就要写成 //*[@class='single_choice']/following-sibling::div

  1. 选择前面的兄弟节点:

CSS选择器目前没有方法选择前面的兄弟节点,而XPath表达式可以,其语法为: preceding-sibling::

例如,要选择 class 为 single_choice 的元素的所有前面的兄弟节点,写成: //*[@class='single_choice']/preceding-sibling::*

Selenium能够处理JS ,这使selenium拥有更为强大的能力。既然能够执行JS ,那么JS能做的事情,selenium大部分也能做。

Selenium可以在当前窗口/框架中同步执行JavaScript。应用的函数是:execute_script(script, *args),其中:script是被执行的js代码(代码中加入 return可以直接返回我们需要的数据),*args是被执行的JS脚本中使用的参数。

实际执行JS时有两种场景:一种是在页面上直接执行JS,另一种是在某个已经定位的元素上执行JS(也就是可以先使用WebDriver获取想要操作的元素,然后使用JavaScript执行操作)。

九、 调用JS时常用的操作:

  1. 获取页面标题:

JS代码很简单,就是:document.title

调用代码:text = driver.execute_script("return document.title")

由于使用了return,则 text中写入了具体的页面标题。

  1. 弹出alert弹窗:

JS代码为:window.alert("hello selenium")

调用代码:driver.execute_script("window.alert('hello selenium')")

  1. 获取元素:

a. 根据元素的id获取元素:

​ JS代码为: js_code = document.getElementById(元素id值)

b. 根据元素的class属性获取元素:

​ JS代码为: js_code = document.getElementsByClassName (元素class值)

c. 根据元素的TagName属性获取元素:

​ JS代码为: js_code = document.getElementsByTagName (标签名)

d. 根据元素的css属性获取元素:

​ JS代码为:

	js_code = document. querySelector(css表达式)   (选择一个元素)

	js_code = document. querySelectorAll(css表达式)   (选择多个元素)

​ 调用代码: driver.execute_script(js_code)

  1. 拉动滚动条方法:

JS代码:

js_code = "document.documentElement.scrollTop=10000"(给一个非常大的值就可以将页面滑动至底部)

js_code = "document.documentElement.scrollTop=0" (给一个非常小的值就可以滑动到页面顶部)

js_code = window.scrollTo(0,document.body.clientHeight)  模拟鼠标滚轮向右向下滑动(负值反向),到可视窗口的最底部

调用代码:driver.execute_script(js_code)

  1. 对某个已选择元素element执行基本操作:(使用带参数的调用)

调用代码: driver.execute_script("arguments[0].click();", element)

又如: driver.execute_script("arguments[0].scrollIntoView();", element)

  1. 修改元素属性:

使用JS可以对已获取到的元素的属性进行修改。

例如:要修改“百度一下”按钮的value属性为“你猜一下”;修改“换一换”的样式为“18px的字号,红色,加粗”;修改搜索框的可见属性为“隐藏”。

JS代码:

js_code = "document.getElementById('su').value='你猜一下'"

js_code = " document.querySelector('#hotsearch-refresh-btn>span').style='color: red; font-size:18px; font-Weight:bolder;'"

js_code = "document.getElementById('kw').style. visibility='hidden'"

依次调用三次,调用代码为:driver.execute_script(js_code)

为了减少多次调用代码造成的冗余,可将JS语句通过英文分号连接,作为execute_script()的script参数进行传参。

driver.get("https://www.baidu.com")
driver.maximize_window()
sleep(2)
driver.execute_script(
	'''
	document.getElementById('su').value='你猜一下';
	document.querySelector('#hostsearch-refresh-btn > span').style='color: red; font-size:18px; font-Weight:bolder;';
	document.getElementById('kw').style. visibilty='hidden';
	'''
)
sleep(2)
driver.quit()

练习1:修改UI_7程序,要求在执行所有操作前,先确定系统中没有订单、客户和药品,如果有,点击删除按钮删除掉。注意:订单数据依赖于客户和药品,必须先删除订单,然后方可删除客户和药品。修改部分的元素选择过程用XPath方法实现。预期结果仍为:成功登录后,添加订单成功。

提交代码
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import Select


driver = webdriver.Chrome()
driver.get("http://127.0.0.1:8047/mgr/sign.html")

driver.find_element(By.CSS_SELECTOR, '#username').send_keys("byhy")
driver.find_element(By.CSS_SELECTOR, '#password').send_keys("88888888")
driver.find_element(By.CSS_SELECTOR, '.col-xs-12').click()
time.sleep(1)

# 判断是否存在客户,药品,订单;若长度大于0则存在
js_code = "return document.getElementsByClassName('search-result-item').length"
# 先删订单
driver.find_element(By.XPATH, '//*[@id="root"]/aside/section/ul/li[4]/a').click()
time.sleep(1)
while 1:
    if driver.execute_script(js_code) > 0:
        ele1 = driver.find_element(By.XPATH, '//*[@id="root"]/div/section[2]/div[3]/div[5]/div/label')
        if ele1:
            ele1.click()
            driver.switch_to.alert.accept()
            time.sleep(1)
    else:
        break


driver.find_element(By.XPATH, '//*[@id="root"]/aside/section/ul/li[3]/a').click()
time.sleep(1)
while 1:
    if driver.execute_script(js_code) > 0:
        ele1 = driver.find_element(By.XPATH, '//*[@id="root"]/div/section[2]/div[3]/div[4]/div/label[2]')
        if ele1:
            ele1.click()
            driver.switch_to.alert.accept()
            time.sleep(1)
    else:
        break


driver.find_element(By.XPATH, '//*[@id="root"]/aside/section/ul/li[2]/a').click()
time.sleep(1)
while 1:
    if driver.execute_script(js_code) > 0:
        ele1 = driver.find_element(By.XPATH, '//*[@id="root"]/div/section[2]/div[3]/div[4]/div/label[2]')
        if ele1:
            ele1.click()
            driver.switch_to.alert.accept()
            time.sleep(1)
    else:
        break


time.sleep(1)

driver.find_element(By.XPATH, '//*[@id="root"]/aside/section/ul/li[3]/a').click()
driver.find_element(By.XPATH, '//*[@id="root"]/div/section[2]/div[1]/button').click()

name1 = ["头孢盒装1", "头孢盒装2", "头孢盒装3"]
model1 = ["YP-20023524", "YP-20023525", "YP-20023526"]
text1 = ["头孢他啶注射液,每支15ml,10支装", "头孢他啶注射液,每支15ml,20支装’; ‘头孢盒装3", "头孢他啶注射液,每支15ml,30支装"]
for i in range(0, 3):
    driver.find_element(By.XPATH, '//*[@id="root"]/div/section[2]/div[1]/div[1]/div[1]/input').send_keys(name1[i])
    driver.find_element(By.XPATH, '//*[@id="root"]/div/section[2]/div[1]/div[1]/div[2]/input').send_keys(model1[i])
    driver.find_element(By.XPATH, '//*[@id="root"]/div/section[2]/div[1]/div[1]/div[3]/textarea').send_keys(text1[i])
    driver.find_element(By.XPATH, '//*[@id="root"]/div/section[2]/div[1]/div[2]/button[1]').click()
    time.sleep(1)

driver.find_element(By.XPATH, '//*[@id="root"]/aside/section/ul/li[2]/a').click()
driver.find_element(By.XPATH, '//*[@id="root"]/div/section[2]/div[1]/button').click()
time.sleep(1)

name2 = ["南京鼓楼区中医院1", "南京鼓楼区中医院2", "南京鼓楼区中医院3"]
tele1 = ["2583426507", "2583426508", "2583426509"]
addr1 = ["江苏省-南京市-鼓楼区-中山北路-253", "江苏省-南京市-鼓楼区-中山北路-254", "江苏省-南京市-鼓楼区-中山北路-255"]
for i in range(0, 3):
    driver.find_element(By.XPATH, '//*[@id="root"]/div/section[2]/div[1]/div[1]/div[1]/input').send_keys(name2[i])
    driver.find_element(By.XPATH, '//*[@id="root"]/div/section[2]/div[1]/div[1]/div[2]/input').send_keys(tele1[i])
    driver.find_element(By.XPATH, '//*[@id="root"]/div/section[2]/div[1]/div[1]/div[3]/textarea').send_keys(addr1[i])
    driver.find_element(By.XPATH, '//*[@id="root"]/div/section[2]/div[1]/div[2]/button[1]').click()
    time.sleep(1)

driver.find_element(By.XPATH, '//*[@id="root"]/aside/section/ul/li[4]/a/span').click()
driver.find_element(By.XPATH, '//*[@id="root"]/div/section[2]/div[1]/button').click()
driver.find_element(By.XPATH, '//*[@id="root"]/div/section[2]/div[1]/div[1]/div[1]/input').send_keys("南京鼓楼中院头孢")

select1 = Select(driver.find_element(By.XPATH, '//*[@id="root"]/div/section[2]/div[1]/div[1]/div[2]/select'))
select1.select_by_visible_text("南京鼓楼区中医院2")
select2 = Select(driver.find_element(By.XPATH, '//*[@id="root"]/div/section[2]/div[1]/div[1]/div[3]/select'))
select2.select_by_visible_text("头孢盒装1")
select2.select_by_visible_text("头孢盒装2")
driver.find_element(By.XPATH, '//*[@id="root"]/div/section[2]/div[1]/div[1]/div[3]/div[1]/input').send_keys("100")
driver.find_element(By.XPATH, '//*[@id="root"]/div/section[2]/div[1]/div[1]/div[3]/div[2]/input').send_keys("100")
driver.find_element(By.XPATH, '//*[@id="root"]/div/section[2]/div[1]/div[2]/button[1]').click()

driver.find_element(By.XPATH, '//*[@id="root"]/aside/section/ul/li[4]/a').click()
if '南京鼓楼中院头孢' == driver.find_element(By.XPATH, '//*[@id="root"]/div/section[2]/div[3]/div[1]/span[2]').text:
    print("添加订单成功")
driver.quit()

练习2:在https://www.byhy.net/_files/stock1.html 网页中修改“股票名称”输入框的边框为“3px solid red”,删除输入框的提示输入内容placeholder属性;“一句话建议”输入框的提示输入内容placeholder属性改为“说说哪个股票最优”,输入文本颜色为“绿色”、14px、加粗且居中;查询结果第一条的背景色为黄色。在“一句话建议”输入框中输入“不好说”。

提交代码
from time import sleep
from selenium import webdriver

wd = webdriver.Chrome()
wd.get("https://www.byhy.net/_files/stock1.html")

js_code01 = "document.querySelector('#kw').style='border-color: 3px solid red;'"
js_code02 = "document.querySelector('#kw').removeAttribute('placeholder')"
js_code03 = "document.querySelector('#suggestion').placeholder='说说哪个股票最优'"
js_code04 = "document.querySelector('#suggestion').style='color: green;font-size: 14px;font-weight: bold;text-align: center;'"
js_code05 = "document.querySelector('.search-result').children[0].style='background-color: yellow;'"
js_code06 = "document.querySelector('#suggestion').value='不好说'"
wd.execute_script(js_code01)
wd.execute_script(js_code02)
wd.execute_script(js_code03)
wd.execute_script(js_code04)
wd.execute_script(js_code05)
wd.execute_script(js_code06)
sleep(3)

wd.quit()

练习3:调用JS完成以下操作:在浏览器中访问百度网站,获取并输出当前网页的标题和地址;弹出alert弹窗显示“你好!”再点击确定关闭;设置搜索框输入字体颜色为蓝色加粗,value值为“selenium”,边框为绿色,删除搜索框元素的autocomplete属性;执行搜索查询;在网页中拉动滚动条至右下角,再滑动到顶部。关闭浏览器。整个过程适当添加等待时间,使相关步骤的操作可见。

提交代码
from time import sleep
from selenium import webdriver
from selenium.webdriver.common.by import By

wd = webdriver.Chrome()
wd.get("https://www.baidu.com")

js_code01 = "return document.title"
js_code02 = "return window.location.href"
js_code03 = "window.alert('你好!')"
js_code04 = "document.querySelector('#kw').style='color: blue;font-weight: bold;border-color: green;'"
js_code05 = "document.querySelector('#kw').value='selenium'"
js_code06 = "document.querySelector('#kw').removeAttribute('autocomplete')"
js_code07 = "document.documentElement.scrollTop=10000"
js_code08 = "document.documentElement.scrollTop=0"

print(wd.execute_script(js_code01))
sleep(1)
print(wd.execute_script(js_code02))
sleep(1)
wd.execute_script(js_code03)
sleep(1)
wd.switch_to.alert.accept()
sleep(1)
wd.execute_script(js_code04)
sleep(1)
wd.execute_script(js_code05)
sleep(1)
wd.execute_script(js_code06)
sleep(1)
wd.find_element(By.CSS_SELECTOR, '#su').click()
sleep(1)
wd.execute_script(js_code07)
sleep(1)
wd.execute_script(js_code08)
sleep(1)

wd.quit()

  • 30
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 可以使用 JavaScript 的 addEventListener 方法来监听元素的点击事件。例如: ``` document.querySelector('xpath').addEventListener('click', function() { // 处理点击事件 }); ``` 也可以使用 jQuery 的 click 方法来监听元素的点击事件,例如: ``` $('xpath').click(function() { // 处理点击事件 }); ``` 注意,xpath 要替换为你要监听的元素xpath。 ### 回答2: XPath是一种用于定位和选择XML文档中特定元素语言。虽然XPath不直接支持监听元素的点击事件,但可以结合其他编程语言和框架来实现此功能。 首先,我们可以使用XPath选择要监听的元素。例如,使用xpath="//button[@id='myButton']"可以选择具有id为"myButton"的按钮元素。 然后,我们可以使用编程语言和框架来监听元素的点击事件。例如,可以使用Python的Selenium库来实现。以下是一个示例代码: ``` from selenium import webdriver # 初始化WebDriver driver = webdriver.Chrome() # 导航到网页 driver.get("http://example.com") # 使用XPath选择要监听点击事件的元素 button = driver.find_element_by_xpath("//button[@id='myButton']") # 监听按钮的点击事件 def button_click(event): print("按钮被点击了") # 绑定点击事件处理程序 button.click(button_click) # 执行其他操作 # ... # 关闭WebDriver driver.quit() ``` 在上面的代码中,我们使用XPath选择具有id为"myButton"的按钮元素,并将其保存在`button`变量中。然后,我们定义了一个名为`button_click`的函数作为点击事件的处理程序,并使用`button.click`方法将其绑定到按钮上。当按钮被点击时,`button_click`函数将被调用,可以在函数中执行特定的操作。 这只是一个示例,具体的实现可能因编程语言和框架的不同而有所差异。希望这个回答对您有帮助! ### 回答3: XPath是一种用于在HTML或XML文档中定位元素语言。它通过使用元素的层级关系和属性来匹配元素,可以用于监听元素的点击事件。 要监听元素的点击事件,我们可以使用XPath表达式来定位该元素,并通过编程的方式绑定点击事件的监听器。 首先,我们可以使用XPath来定位元素XPath表达式可以根据元素的标签名、属性、父子关系等进行匹配。例如,通过使用元素的class属性或id属性,我们可以精确地定位元素的位置。 然后,我们可以使用编程语言,例如JavaScript,在页面中使用XPath来选取元素,并为其绑定点击事件的监听器。当该元素被点击时,绑定的监听器会执行相关的操作。 举个例子,假设我们要监听一个id为"myButton"的按钮元素的点击事件。首先,我们可以使用XPath表达式"//*[@id='myButton']"来选取这个按钮元素。然后,我们可以在JavaScript中获取该元素,并为其绑定一个点击事件的监听器。 具体的监听器代码可以根据需求来编写。例如,可以在监听器中执行一些操作,比如发送请求、更新页面内容或做其他逻辑处理。 总之,使用XPath监听元素的点击事件需要先通过XPath表达式定位元素,然后使用编程语言来为该元素绑定点击事件的监听器,从而实现对元素点击事件的监听。这样就可以根据元素的点击来执行一些相关操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值