css selector 的高级用法
CSS(Casading Style Sheets)层叠样式表。一种用来表现HTML或者XML等文件样式的语言。css选择器是浏览器用来选择元素,selenium 也要选择元素,可以使用css选择器来选择Web元素。
定位元素的注意事项:
1、找到等待定位的元素的唯一属性
2、如果该元素没有唯一属性,则先找到能够给被唯一定位的父元素/子元素/相邻元素,再使用 “>” 、“ ”、“+” 等辅助定位要定位的元素。
3、不要使用随机唯一属性,属性是会发生改变。 ID = “Dev45” Dev46
1、ID选择器 通过 # 来定义,通过元素的ID属性来定位。 格式: #id属性值
id选择器来定位元素 格式: #id属性值 通过 # 来定义的
print (driver.find_element_by_css_selector("#pLabel").get_attribute("id"))
2、class选择器(类选择器) 使用 . (点)来定义 格式: .class属性的值
class 选择器 使用 . (点)来定义 格式: .class属性的值
driver.find_element_by_css_selector(".RedChamber").send_keys("class 选择器 使用 . (点)来定义 格式: .class属性的值")
如果class属性值有空格,则可以使用如下方法来定位:
方法一:
可以使用 点 替换掉所有的空格(例如: .Dream.of.the.Red.Chamber)
方法二:
可以截取一部分值,然后在截取的部分值之前加上 . (点) (例如: .Dream) class属性值有空格
driver.find_element_by_css_selector(".Dream.of.the.Red.Chamber").send_keys("class属性值有空格")
driver.find_element_by_css_selector(".Dream").send_keys("截取部分值在前面加上点来定位")
3、标签选择器 通过 标签的标签名 来定位元素
标签选择器 通过标签的标签名来定位元素
print (driver.find_element_by_css_selector("span").text)
4、属性选择器 根据标签中的属性来定位元素, 格式: [属性名=”属性值”]
属性选择器 使用方括号把属性扩起来 ,格式: [属性名=“属性值”] 例如: [id=“form”]
print (driver.find_element_by_css_selector('[id="form"]').get_attribute('id'))
没有指定属性值,则返回所有具有某个属性的元素。
没有指定属性值
print (driver.find_element_by_css_selector("[id]").get_attribute("id"))
5、id选择器和class选择器的组合使用 即要定位的元素既要满足id属性值为指定的值,又要满足class属性的值为指定的值。
id选择器和class选择器组合使用 #ID .Dream 两个条件是 且 的关系
driver.find_element_by_css_selector("#ID.Dream").send_keys("id选择器和class选择器组合使用")
6、id选择器和标签选择器的组合使用 标签选择器只能放在id选择器的前面
id选择器和标签选择器的组合使用
print (driver.find_element_by_css_selector("a#tianshang").text)
7、标签选择器和class选择器组合使用
标签选择器和class选择器的组合使用 标签选择器只能放在class选择器的前面
点击展开下拉框
driver.find_element_by_css_selector("select").click()
选择下拉框中的内容
driver.find_element_by_css_selector("option.poem").click()
8、使用多个属性来定位元素
使用多个属性来定位元素
driver.find_element_by_css_selector('[id="IamID"][name="first"]').send_keys("使用多个属性来定位元素")
选中某一行,如果鼠标在最前面,则使用 shift + end,如果鼠标在最后面,则使用shift + home键。
9、标签选择器、id选择器、class选择器、属性选择器组合使用
标签选择器、id选择器、class选择器、属性选择器组合使用
driver.find_element_by_css_selector('input[id="IamID"].poem[name="first"]').send_keys("标签选择器、id选择器、class选择器、属性选择器组合使用")
10、分组选择器
使用的场景:id的属性值 在 ID1 和 ID2 之间变化,只能使用id属性来定位元素,此时可以使用分组选择器来定位元素。
分组选择器 使用 , (逗号)来定义
driver.find_element_by_css_selector("#IamID1,#IamID2").send_keys("使用 , (逗号)来定义")
11、后代选择器
使用 空格 来定义,父元素 加上 空格 后代元素
只能够选择到直系 后代,而不能选择 旁系后代,不论是儿子还是孙子都可以。
后代选择器 使用 父元素 加上 空格 后面元素
print (driver.find_element_by_css_selector("#form span").tag_name)
12、子元素选择器 只能选择自己的儿子,不能隔代, 使用 > 来定位
子元素选择器 使用 > (大于号)来定位 只能选择自己的儿子,不能隔代
print (driver.find_element_by_css_selector('[id="form"] > span').text)
13、相邻兄弟选择器
相邻的(两个元素之间不能有间隔) 兄弟关系(有相同的父元素),只能向后 选择,不能向前选择。 使用 + 号来定位
相邻兄弟选择器 使用 + 来定位
print (driver.find_element_by_css_selector(".Dream + br").tag_name)
14、后续兄弟选择器
使用 ~ 来定位,后续兄弟选择器选取所有指定元素之后的兄弟元素,中间可以有间隔。
后续兄弟选择器 使用 ~ 来定位,后续兄弟选择器选取所有指定元素之后的兄弟元素,中间可以有间隔
print (driver.find_element_by_css_selector("#pLabel ~ br").tag_name)
15、伪类
Pseudo-classes [‘su:dƏu]
伪类选择元素基于的是当前元素处于的状态,或者元素当前所有的特性,而不是元素的id、class等静态属性标志。由于状态是动态变换的,所有一个元素达到一个状态以后,就可能获取到一个伪类的样式,当状态改变时,就有可能失去了这个样式。它的功能与class(类)类似,所以称之为伪类。
1):nth-child(n)
匹配属于其父元素下的第n个子元素
option:nth-child(3) 表示匹配到 option元素的父元素下的第3个子元素。
:nth-child(n) 匹配属于其父元素下的第n个子元素
print (driver.find_element_by_css_selector("option:nth-child(3)").get_attribute("value"))
2):nth-last-child(n)
匹配属于其父元素下的倒数第n个子元素
:nth-last-child(n) 匹配属于其父元素下的倒数第n个子元素
print (driver.find_element_by_css_selector("option:nth-last-child(4)").get_attribute("value"))
3):first-child
匹配属于其父元素下的第1个子元素
:first-child 匹配属于其父元素下的第1个子元素
print (driver.find_element_by_css_selector("option:first-child").text)
4):last-child
匹配属于其父元素下的最后1个子元素
:last-child 匹配属于其父元素下的最后1个子元素
print (driver.find_element_by_css_selector('option:last-child').text)
Python + selenium 元素定位系列
Python + selenium 元素定位(六)----Xpath的高级用法
window.location.href 跳转页面,隐藏携带的参数
window.location.href 跳转页面,隐藏携带的参数 前言
问题:
在使用 ajax返回结果后,我们有一种需求:根据返回结果跳转到相应的页面,并且跳转过程中会携带一个或多个参数,传递至某个页面或者后台的某个方法,这个时候跳转页面后携带的参数就会直接暴露给用户,带来极大的安全隐患。
举例说明
如下一段方法,在执行完 /order/getOrder 该操作后,如果操作成功,跳转到/pay/checkout 后台封装的controller中,controller重新转发至指定的某个页面,此时跳转成功后,页面路径中直接将 orderId 、totalPrice直接暴露出来了,因为此时为get跳转。
function queryOrder(){
$.ajax({
type : "post",
url : '/order/getOrder',
data : {
orderId: orderId,
},
dataType : "json",
success : function(data) {
if (data.data == 1) {
window.location.href = "/pay/checkout?orderId="
+ orderId + '&payPrice=' + totalPrice;
} else {
return false;
}
}
});
}
那该如何成功跳转又能将参数隐藏呢,当然是想办法将方法以post方式提交,下面就是把路径和参数重新封装到一个form 表单里,
function queryOrder(){
$.ajax({
type : "post",
url : '/order/getOrder',
data : {
orderId: orderId,
},
dataType : "json",
success : function(data) {
/**if (data.data == 1) {
window.location.href = "/pay/checkout?orderId="
+ orderId + '&payPrice=' + totalPrice;**/
//封装form表单
var form = $(");
form.attr("style","display:none");
form.attr("target","");
form.attr("method","post");
//请求地址
form.attr("action","/pay/checkout");
//第一个参数 orderId
var input1 = $("");
input1.attr("type","hidden");
input1.attr("name","orderId");
input1.attr("value",orderId);
//第二个参数 totalPrice
var input2 = $("");
input2.attr("type","hidden");
input2.attr("name","payPrice");
input2.attr("value",totalPrice);
//...多个参数以此类推
$("body").append(form);
form.append(input1);
form.append(input2);
form.submit();
form.remove();
} else {
return false;
}
}
});
}
致此,参数完美的隐藏了,但是项目运行过程中,我们的写的js还是会暴露出去,通过分析js还是可以查看分析我们的路径和参数,因为js设计的时候就是明文执行。所以对于重要的js还是要通过特殊手段加密。
例如:
1、将重要的逻辑处理在后端进行,这个过程就比较繁琐
2、通过软件将js直接加密处理,比较常用的是 jshaman ,整个将js代码复制过去,加密后复制回来直接可以使用。
3、自己写个小脚本禁止 F12等按键查看源码等 页面禁用F12或禁用右键查看源码,其他方式还是有挺多的,可以根据实际情况使用,就不多做介绍了