赞
踩
以下是selenium3的定位写法方式:
去年selenium4更新后,做了修改,新的定位写法与3有些不同,不过定位方法一样。大同小异。
旧版本的写法(selenium3):
from selenium import webdriver
driver= webdriver.Chrome()
driver.get('https:/www.baidu.com')
#获取网页元素
byid =driver.find_element_by_id('kw')
byname = driver.find_element_by_name('paord')
bytname = driver.find_element_by_tag_name("elementTagName")
byltext = driver.find_element_by_link_text("linkText")
bycls =driver.find_elemet_by_class('su')
byclsnm = driver.find_element_by_class_name('main-container')
bycss = driver.find_element_by_css_selector('li.el-menu-item')
byxpath = driver.find_element_by_xpath('//*[@href="https://consumer.huawei.com/cn/"][1]')
---------------------------以上在4中是无法使用的
。---------------------------
新版本的写法(selenium4):
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.get('https:/www.baidu.com')
byid = driver.find_element(By.ID,'kw')
bytname = driver.find_element(By.NAME,"xx")
bytname = driver.find_element(By.TAG_NAME,"xx")
bycls = driver.find_element(By.CLASS'main-container')
byclsnm = driver.find_element(By.CLASS_NAME,"xx")
byltext = driver.find_element(By.LINK_TEXT,"xx")
bycss = driver.find_element(By.CSS_SELECTOR,"xx")
byxpath = driver.find_elements(By.XPATH, '//*[@id="bottom_layer"]/div/p')
web元素:示例:成对儿出现的元素,标签之间的是内容
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"> <!-- 设置字符集 -->
<title>计算器-基于Table实现</title>
</head>
<body>
<h1>First heading</h1>
<p>first paragraph.</p>
</body>
</html>
1.HTML:Hyper Text Market Language 超文本标记语言,由一系列事先约定好的标记(标签)来描述一个页面的构成。HTML不是编程语言,只是标记语言。
HTML主要由三个部分构成:标记、属性、内容。
(1)文本:设置字体、颜色、大小
(2)图片:设置边框、大小、位置
(3)超链接:图片文本均可以添加超链接
(4)表格:行列构成的结构化数据、可以用表格展示,可以为表格设置大小、背景等,表格里面可以放所有元素
(5)表单:文本框、下拉框、单选框、复选框、按钮、文本域等。
(6)多媒体:音频、视频、H5游戏等。
2.CSS:Cascade Style Sheet : 层叠样式表,用于对页面元素进行布局和美化。
3.JavaScript:在浏览器中运行的解释性编程语言,用于进行页面交互(前后端交互、用户之间交互)
weUI自动化
操控
的基本是<body>内容</body>
内的元素,是能直观在页面看到的东西。
更多html元素可以查阅:https://www.runoob.com/html/html-elements.html
.find_element_by_id(' ')
基于元素属性中的id
的值来进行定位,类似人们的身份证上的号码,不出意外不会重复
from selenium import webdriver
#实例化浏览器
driver= webdriver.Chrome()
#登录网站网址
driver.get('https://www.baidu.com')#打开网址
#定位元素方法1
ele = driver.find_element_by_id('kw')
#输入搜索内容
ele.send_keys('xxxxxx')
获取百度网页:
注意
:
有些id是会随着网页刷新的,并不是固定不变的,不能用来作为元素定位使用
刷新后:
还有带有auto标签的id:
以上都是不可以作为元素定位使用的。确保是否可以用来元素定位,可以刷新页面验证。
基于元素属性中name
的值进行定位,类似身份证上的名字,会重复
#定位元素方法1
ele = driver.find_element_by_name('wd')
#输入搜索内容
ele.send_keys('xxxxxx')
用于超链接文本属性
进行定位,例如点击登录跳转等操作
#获取元素-定位
ele=driver.find_element_by_link_text('关于百度')
ele.click()
link text的超链接模糊查询
版本,类似于数据库中like %,当模糊查询匹配多个符合条件的元素,选取第一个
driver.get('https://www.baidu.com')
ele = driver.find_element_by_partial_link_text('使用百度').click()
基于元素样式来进行定位,非常容易遇到重复的,而且遇到多样式的时候,之间会有空格可能会导致定位不到情况
ele = driver.find_element_by_class_name('mnav.s-top-more-btn').click()
标签名来进行定位,重复度最高,只有需要定位后进行二次筛选时候使用
例:
el = driver.find_elements_by_tag_name(‘a’)
for i in el:
if d.text == ‘登录’
d.click()
ele = driver.find_element_by_class_name('mnav.s-top-more-btn')
ele1 = ele.find_element_by_tag_name('a').click()
一般tag_name
需要有上一级的父元素被查询出来再调用父元素的定位继续往下一级查询会用tag_name
查询多个或者一个子元素`
——————————————————————————————————————————
应用相对较多的一种行为,采用绝对路径定位,最初IE浏览器不支持xpath,完全依赖此方法
CSS选择器:作用:
通过描述元素特征和元素直接关系来定位元素
被浏览原生支持
优点:效率高
⑴标签选择器(元素选择器)
⑵ID选择器(唯一性,一次引用)
⑶类选择器(单类选择器,多类选择器)
⑷属性选择器(简单属性选择,具体属性选择,部分属性选择, 特定属性选择)
⑸派生选择器(后代选择器(descendant selector),子元素选择器(child selector),相邻兄弟选择器(Adjacent sibling selector))
一个完整的HTML页面是由很多不同的标签组成。标签选择器可以直接设置HTML元素的样式,比如h1、td、p、a,甚至可以是html本身。
语法:标签名 { 属性:值 }
h1 { color : blue ;} <!--所有h1标签变蓝色-->
a { text-decoration : none ; } <!--所有链接没有下划线-->
特殊的两个元素id
和class
使用css定位对于有id的属性:就是在id的属性前面加#:元素名称#id属性值
例如:
songele = browser.find_element_by_css_selector('div#song-list-pre-cache')
对于class元素定位对其属性前加‘.
’:元素名称.class属性值
onbtn = browser.find_element_by_css_selector('a.u-btn2.u-btn2-2.u-btni-addply.f-fl')
空格
)#属性值 空格 下一级元素
,这里的下一级可以是明确的子元素,也可以是下下一级的子元素并不一定是往下一级的可以往下跨几级只要能够定位的到都可以
。#song-list-pre-cahce span
)多级后代
元素定位,中间可以跳级往下查找
,并不一定要严格按照往下一级一级的查找
。#song-list-pre-cache div table tr span
).
**#hd div span
)>
)选择同一父元素下的子元素,相较于后代选择器
有一定区别:子元素选择器是用“>
”承接表示,是明确的下一级子元素
,不能往下跳级,只能严格的按照一级一级的往下查找
。一般用做最后面的一两级
,多级实在是比较麻烦
例子:
一级子元素
#choose_car > option
.
footer>p
.
p元素一定是明确的footer的子元素。p子元素可以是一个也可以是多个
可以是多级的
footer>table>p>a……
,
)组选择 同时选择多个元素,使用‘’,
‘’隔开
语法:,
例子:
p,button
.
#food, .choose
.
#food>span,p
.#food>span,#food>p
#food>*
. .+
)表示相邻的元素使用‘+
’号连接上一个元素
#food+p
.p元素是food的下面的相邻元素,只能选择下面的相邻元素,不能选择上面的
可以多级表示:
#food+p+a
.a是p下面的相邻元素,p是food的`下面的相邻元素
1、CSS [attribute] 选择器
[attribute]
选择器用于选取带有指定属性的元素。
下例选择所有带有 target
属性的 <a>
元素;
实例
a[target]
{ background-color: yellow;}
2、CSS [attribute=“value”] 选择器
[attribute="
value"]
选择器用于选取带有指定属性和值的元素。
下例选取所有带有 target="_blank"
属性的 <a>
元素:
实例
3、CSS [attribute=“value”] 选择器
[attribute*
=“value”] 选择器选取属性值包含指定词的元素。
提示:值不必写完整!
实例
4、CSS [attribute^=“value”] 选择器
[attribute^
=“value”] 选择器用于选取指定属性以指定值开头的元素。
下例选取 class 属性值
以 xxx" 开头的所有元素:
提示:值不必是完整单词!
实例
5、CSS [attribute$=“value”] 选择器
[attribute$
=“value”] 选择器用于选取指定属性以指定值结尾的元素。
下例选取 class 属性以 “test” 结尾的所有元素:
提示:值不必是完整单词!
实例
[class$=“test”] { background: yellow;}
CSS [attribute~=“value”] 选择器
[attribute~=“value”] 选择器选取属性值包含指定词的元素。
下例选取 title 属性包含 “flower” 单词的所有元素:
实例
等同于*
模糊匹配
6、CSS [attribute|=“value”] 选择器
[attribute|=“value”] 选择器用于选取指定属性以指定值开头的元素。
下例选取 class 属性以 “xxx” 开头的所有元素:
注释:值必须是完整或单独的单词,比如 class=“xxx” 或者后跟连字符的,比如 class=“xxx-text”。
实例
7、CSS多个属性选择器
div[attribute="value"][attribute="value"]
多个属性就用[]
联接多个定位查询,一个定位上两个属性
:nth-child(n)
p:nth-child(2) 选择其父元素的第二个子元素的所有p元素
:last-child
p:last-child 选择其父元素的最后一个子元素的所有p元素
—————————————————————————————
应用最多的一种行为,基于页面结构来进行定位
绝对路径:从html根目录一层一层查找
相对路径:基于匹配制度来查找
例如://*[@id=“kw”]
//
:表示从根路径开始查找
*
:任意元素
[]
:表示筛选条件
@
:表示基于属性来筛选:例如@id=“kw”表示基于id属性值为kw来进行筛选
如果要基于text来定位元素
在[]中添加text()=“文本内容” 例如//a[text()=“登录”]
子元素如果定位不到,可以定位它的父元素
contain:进一步查找匹配项模糊查找
缺点:消耗系统性能
xpath=//div//div//a
,使用两个‘//
’表示,可以向下跳级
查找定位
xpath = /html/body/div[1]/div/div/div/div[1]/div[2]/div
,使用“/”基本不用,太繁琐,必须从html开始,不过可以和相对路径搭配使用
相当于css的属性定位
的方法**:
//*[@id=‘kw’
] #标红的部分就是直接通过html元素页粘贴贴过来即可。等同与css[id=‘kw’]
标准写法//div[@id=‘kw’
],可以不写元素div
属性定位也是比较常用的方法,如果元素中没有常见的id,name,class等直接有方法可调用的属性,也可以查找元素中是否有其他能唯一标识元素的属性,如果有,就可以用此方法定位
contains
//*[contain(@class,"xxx")]
. #属性class包含xxx的定位
例子:
//*[starts-with(@id,"xxx")]
.#属性id以xxx开头的元素定位,
同理以什么结尾//*[ends-with(@id,"xxx")]
.#属性id以xxx结尾的元素定位但是好多浏览器原生不支持这种方法,方法是对的。
例子
//*[@id="xx"]/option[2]
通过下标的方法,标记子元素的第几个 .
索引变形:
//*[@class="s-top-more"]/div[1]/a[1]
当子元素div
还有多个子元素a
时,需要索引下标锁定子元素,子元素的子元素索引才有效锁定一个元素,同样的三级四级多个子元素也要从父元素开始锁定
//*[@id="song-list-pre-cache"]//tr[last()]
多个同级子元素的最后一个定位
//*[@id="song-list-pre-cache"]//tr[last()-1]
子元素的倒数第二个定位
position()=?
父元素有多个同级子元素时,可以通过位置索引锁定,效果大多数等同于/div[position()=1]==/div[1]
同理当多个子元素还有多个子元素的同级子元素时,子元素需要锁定后才可以对子元素的子元素锁定//*[@class="s-top-more"]/div[2]/a[position()=3]
position()
运算符的使用"=
" 和不等于"!=
"子元素的排除子元素的定位position()>1
可以使用">
" “=
” “<
” “>=
” “<=
”
//*[@id=“song-list-pre-cache”]//tr[position()=9]`位置第几个元素的定位
“=
”的用法最后一个,与"!=
"相反,等于
是选择法
和不等于
是排除法
position()
运算符的使用">
" 和不等于"<
"“>
”用法,大于第几个,从第几个开始定位。“<
”用法相反,小于第几个。是个范围选择法
position()
运算符的使用">=
" 和不等于"<=
"“>=
”用法,,“<=
”用法相反,小于等于包含着当前元素位置的范围选择法
css使用“,
”隔开,xpath用管道符“|
”等同于"and
"
//p | //button
同时选择多个使用“|”联接
and
和or
当一个位置的元素无法通过一个属性锁定位置时,同时该位置包含多个属性时,可以使用and连接符用多个属性锁定位置
and
用法
而or的使用是定位时满足任意一个属性条件就锁定位置
选择下面
的兄弟节点:/following-sibling::div[2]
//*[@class="s-top-more"]/div[2]/following-sibling::div[1]
.
选择上面
的同级相邻兄弟元素:/preceding-sibling::div
.
//*[@class="s-top-more"]/div[3]/preceding-sibling::div[1]
.
../
"或者上一级元素使用../
表示
如果定位到了父节点:元素ele,下一级子元素查找ele2定位置调用ele时需要区分是当前节点元素的子元素还是所有的查找子元素 ".//
"表示当前节点的范围内查找。尽管在ele.find……基础上调用,不用.//是全局查找
ele = browser.find_element_by_xpath('//*[@id="song-list-pre-cache"]')
ele2 = ele.find_elements_by_xpath('.//a')
或者使用://*[@id=“s-top-left”]/a[contains(text(),“贴吧”)]/parent::*
表示定位当前节点的父元素
模糊查找定位://[contains(text(),"百度产品")]
注意:多级定位时模糊匹配文本,text()属性前必须加上该位置的元素://[@id=“s-top-left”]/a
[contains(text(),“贴吧”)]
精确查找定位://*[@class=“img-spacing”]/div[(text()="知道")]
1)selenium能够处理js,这使selenium拥有更为强大的能力,既然能够执行js,那么js能做的事情,selenium大部分也能做
2)直接使用js操作页面,能解决很多click()不生效的问题
3)页面滚动到底部,顶部
4)处理富文本,时间控件的输入
execute_script
(同步执行)
execute_async_script
(异步执行)
execute_script(script, *args): 执行js
return:可以返回js的返回结果
execute_script:arguments传参
以百度首页为例:
from selenium import webdriver
driver = webdriver.Chrome()
driver.maximize_window()# 最大化窗口
driver.implicitly_wait(10)# 隐式等待
#打开百度首页
driver.get('https://www.baidu.com')
ele2 = driver.execute_script("return document.title;") # 返回网页标题
print(ele2)
在Selenium中可以使用drvier.execute_script()来执行Javascript脚本,支持多行语句。
使用Javascript可以实现以下功能:
移除元素隐藏、禁用、只读等限制属性
为元素添加id或高亮样式
页面滚动
富文本框输入(HTML注入)
获取页面信息
使用Javascript参数
在使用Javascript语句时,还可以动态传入参数或元素对象,Javascript语句中使用占位符“argument[n]”来表示取第几个参数,如:
js = "arguments[0].setAttribute('style', arguments[1]);"
这里埋设了两个参数,一个是元素对象,另一个是样式字符串。
element = driver.find_element_by_id("kw")
.
style = "background: red; border: 2px solid yellow;"
.
执行脚本时,按顺序携带参数即可:
driver.execute_script(js, element, style)
.
获取Javascript返回值
在Javascript语句中加上return字样,如获取页面高度:
js = 'return document.documentElement.scrollHeight;'
.
执行该后便可以拿到其返回值:
page_height = driver.execute_script(js)
.
文档级别操作
document.getElementById
.
document.getElementsByClassName
.
document.getElementsByName
.
document.getElementsByTagName
.
document.getElementsByTagNameNS
.
#获取标签的text文本值,,测试没有该效果,可能使用方法不对 js1="return document.getElementById('key1').innerText" dr.execute_script(js1) #获取标签的html文本,测试没有该效果,可能使用方法不对 js2="return document.getElementById('key2').innerHTML" dr.execute_script(js2) #单文本框中输入值 content_text="测试" js3="document.getElementById('key3').value = '%s'" % (content_text) dr.execute_script(js3) #多文本框(富文本框)中输入text文本 js4="document.getElementById('key4').contentWindow.document.body.innerText = '%s'" % (content_text) dr.execute_script(js4) #多文本框(富文本框)中输入html文本 js5="document.getElementById('key5').contentWindow.document.body.innerHTML = '%s'" % (content_html) dr.execute_script(js5) #点击按钮 js6="document.getElementById('key6').click()" dr.execute_script(js6)
---------------------------------注
----------------------------------------------
firefox浏览器不支持innerText
元素级别操作
可以先使用WebDriver获取想要操作的元素,然后使用JavaScript执行操作。
input_ele = driver.find_element(By.ID, "su")
driver.execute_script("arguments[0].click();", input_ele)
操作百度首页搜索天气预报的例子:
from time import sleep from selenium import webdriver from selenium.webdriver.common.by import By driver = webdriver.Chrome() driver.maximize_window() driver.implicitly_wait(10) driver.get('https://www.baidu.com') input_text = driver.find_element(By.ID, 'kw') # 获取输入框定位 driver.execute_script("arguments[0].value = '天气预报';", input_text) click_ele = driver.find_element(By.ID, 'su') # 获取百度搜索按钮定位 driver.execute_script("arguments[0].click();", click_ele) # 返回网页标题 sleep(10)
可以在语句中使用多个 JavaScript动作
username = driver.find_element_by_xpath("//*[@id='username']")
password = driver.find_element_by_xpath("//*[@id='pwd']")
driver.execute_script("arguments[0].value = 'admin';arguments[1].value = '12345678';", username, password)
1、上下滑动:
滑动百度搜索页 到最底部或者 最顶部
driver.execute_script('document.documentElement.scrollTop=5000') # 将页面滑动至底部,给一个非常大的值就可以
sleep(2)
driver.execute_script("document.documentElement.scrollTop=0") # 给一个非常小的值就可以滑动到顶部
#滑动底部还有另一种写法:
driver.execute_script("window.scrollTo(0, document.body.scrollHeight)")
#滑到顶部另种写法:
driver.execute_script("window.scrollTo(0, 0)")
2、左右滑动:
对于页面有嵌入插件,可以滑动的模块时:
selenium:滑动到target 为可见状态:
target =self.driver.find_element_by_id("help") 或 target =driver.execute_script("return document.getElementById('help')")
driver.execute_script("arguments[0].scrollIntoView();", target)
return document.title
driver.execute_script("return document.title"))
可以在当前窗口弹窗alert提示窗:自定义文字
#js: window.alert("hello selenium”)
driver.execute_script("window.alert('hello selenium')")
#js:JSON.stringify(performance.timing)
driver.execute_script("return JSON.stringify(performance.timing)")
driver.execute_script("arguments[0].click();", element),点击操作
driver.execute_script("arguments[0].scrollIntoView();", element),移动到目标元素,类似于滑动查找
HTML代码如下:
<textarea value="" name="ta1"></textarea>
虽然可以通过name定位到元素,但是不能通过send_keys()输入内容,这种情况下就可以借助javascript代码输入内容
代码如下:
#定义输入的内容
input_text = "selenium"
#将输入的内容与js拼接
js = "document.querySelector('textarea').value='"+ input_text + "';"
print(js)
driver.execute_script(js)
实操:通过JavaScript实现页面滚动,JavaScript操作滚动条:
class casetest(object): def __init__(self): self.driver = webdriver.Chrome() self.driver.get('http://wwww.baidu.com') self.driver.maximize_window() self.driver.implicitly_wait(5) def test_execute1(self): self.driver.execute_script("alert('test')") # 同步执行,弹出提示窗口 sleep(2) self.driver.switch_to.alert.accept() def test_execute2(self): js = 'return document.title' title = self.driver.execute_script(js) # 取到百度的title print(title) def test_execute3(self): js = "var q=document.getElementById(\'kw\');q.style.border=\'4px solid red\';" # js = "var q=document.getElementById(\"su\");q.style.background=\'green\';" self.driver.execute_script(js) # 把百度搜索边框变为红色 sleep(7) def test_execute4(self): # 滚动条滚动 self.driver.find_element(By.ID, 'kw').send_keys('留白') self.driver.find_element(By.ID, 'su').click() sleep(2) # 滚动到底部 js = 'window.scrollTo(0,document.body.scrollHeight)' self.driver.execute_script(js) sleep(2) if __name__ == '__main__': casetest().test_execute1() # casetest().test_execute2() # casetest().test_execute3() # casetest().test_execute4()
总结:
从效率的角度来说 id,name,cssselector效率更高,xpath效率最低,但是这种效率来说几乎微乎其微,xpath属于万金流,没有定位不了的元素,配合绝对筛选查找,可读性高,维护性会更好。
—————————————————————————————————————————
ele = browser.find_element_by_id('')
.
当使用element
时是定位的一个元素对象,如果有多个,默认查找的是第一个
。可以通过
print(ele.get_attribute('outerHTML'))
打印出查询结果的html原始文本信息
例子:
定位播放按钮的对象,当前网页是有多个相同元素的播放按钮的,通过element定位:打印出来时第一个
播放按钮的元素对象:
ele = browser.find_elements_by_id('')
.
当使用elements时是定位的多个元素对象,并且放置在列表中。无法准确定位需要的元素对象。
只能通过print(ele)
所有的查询元素对象,需要定位某一个可以通过索引[0]……[xx]
第几个确定的定位
例子:
song= browser.find_elements_by_id('album-desc-dot')
print(song.text)
b:属性带有内容
通过css方法定位元素,然后通过.get_attribute('属性')
获取属性值
,就可以打印属性值
,即标题内容
song = browser.find_element_by_id('song-list-pre-cache')
songtitle = song.find_element_by_css_selector('.txt a b').get_attribute('title')
print(songtitle)
显示结果:
错误方法:
通过定位元素打印title标题方式会出现其他不必要的内容:直接在定位元素后打印.text
song = browser.find_element_by_id('song-list-pre-cache')
songtitle = song.find_element_by_css_selector('.txt a b').text
print(songtitle)
打印结果:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。