TA的每日心情 | 无聊 前天 09:05 |
---|
签到天数: 1050 天 连续签到: 1 天 [LV.10]测试总司令
|
select下拉列表
下拉列表的tag name是“select”,而下拉列表的选项的tag name是“option”。
导包,可以用这两种方法任一个。
from [url=]selenium[/url].webdriver.support.ui import Select
from selenium.webdriver.support.select import Select
●实例化Select:Select(driver.find_element_by_id('s1Id'))。
●选择下拉选项:select类提供了3种选择某一选项的方法,分别是通过index选择下拉选项——select_by_index(index);通过value值选择下拉选项——select_by_value(value);通过可见text选择下拉选项——select_by_visible_text(text)。
●取消下拉选项:select类提供了4种方法取消原来的选择,分别是通过index取消下拉选项——deselect_by_index(index);通过value值取消下拉选项——deselect_by_value(value);通过可见text取消下拉选项——deselect_by_visible_text(text);全部取消选择——deselect_all()。
●返回选项:返回所有选项——options;返回第一个选中项——first_selected_option;返回所有选中项——all_selected_options。
●判断select选项是否可多选:is_multiple,返回一个布尔值。
选择下拉值
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>select下拉列表</title>
</head>
<body>
<select id="s1Id">
<option></option>
<option value="o1" id="id1">o1</option>
<option value="o2" id="id2">o2</option>
<option value="o3" id="id3">o3</option>
</select>
</body>
</html>
from selenium import webdriver
from time import sleep
from selenium.webdriver.support.ui import Select
driver = webdriver.Chrome()
driver.get('C:\\Users\\Desktop\\my_html.html')
ele = driver.find_element_by_id('s1Id')
# Select(ele).select_by_index(1)#通过 index定位
Select(ele).select_by_value('o2')#通过value属性定位
# Select(ele).select_by_visible_text('o3')
sleep(3)
driver.quit()
●value是<option>标签的一个属性值,并不是显示在下拉列表中的值。
●visible_text是在<option>和</option>标签对中间的值,是显示在下拉列表中的值。
取消选择
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>可以多选的select下拉列表</title>
</head>
<body>
<select id="s1Id" multiple="multiple">
<option>请选择:</option>
<option value="o1" id="id1">o1</option>
<option value="o2" id="id2">o2</option>
<option value="o3" id="id3">o3</option>
</select>
</body>
</html>
<select>标签多了一个multiple="multiple"的属性,这意味着该下拉列表的选项可以多选。
from selenium import webdriver
from time import sleep
from selenium.webdriver.support.ui import Select
driver = webdriver.Chrome()
driver.get('C:\\Users\\Desktop\\my_html.html')
ele = driver.find_element_by_id('s1Id')
Select(ele).select_by_index(1)#通过 index定位
sleep(2)
Select(ele).deselect_by_index(1)#取消选择
Select(ele).select_by_index(1)
Select(ele).select_by_index(2)
Select(ele).select_by_index(3)
Select(ele).deselect_all()#取消所有选择
sleep(3)
driver.quit()
获取选项
获取所有option,并依次选中。
◆select提供了3个属性用于获取选项
Options——返回包含所有选项的列表,其中选项是WebElement元素。
all_selected_options——返回包含所有被选中的选项的列表。
first_selected_option——提供第一个被选中的选项,也可以用于获取下拉列表的默认值。
from selenium import webdriver
from time import sleep
from selenium.webdriver.support.ui import Select
driver = webdriver.Chrome()
driver.get('C:\\Users\\Desktop\\my_html.html')
ele = driver.find_element_by_id('s1Id')
all_options=Select(ele).options #返回所有option
for i in range(len(all_options)):
Select(ele).select_by_index(i)#循环option依次选中
all=Select(ele).all_selected_options #获取所有被选择的选项
for i in all:
print(i.text)
driver.quit()
判断select下拉列表中的选项是否可多选
◆Select提供了一个属性,用来判断是否可多选is_multiple——返回一个布尔值,判断select选项是否可多选。
from selenium import webdriver
from time import sleep
from selenium.webdriver.support.ui import Select
driver = webdriver.Chrome()
driver.get('C:\\Users\\Desktop\\my_html.html')
ele = driver.find_element_by_id('s1Id')
print(Select(ele).is_multiple)
表格
一个table标签对应一个表格;“table”里面包含若干“tr”,每个“tr”对应一行;每个“tr”下面包含若干“td”,每个“td”对应一个单元格。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>学习操作表格-1</title>
</head>
<body>
<table border="1">
<tr>
<td>0-0</td>
<td>0-1</td>
<td id="CellWithId">Cell with id</td>
<td>0-3</td>
</tr>
<tr>
<td>1-0</td>
<td>1-1</td>
<td>1-2</td>
<td>1-3</td>
</tr>
<tr>
<td>2-0</td>
<td>2-1</td>
<td>2-2</td>
<td>2-3</td>
</tr>
</table>
<br>
</body>
</html>
如果只是想获取某个单元格中的值,那么像定位普通元素一样定位单元格即可
from selenium import webdriver
from time import sleep
driver = webdriver.Chrome()
driver.get('C:\\Users\\yangyl13\\Desktop\\my_html.html')
ele=driver.find_element_by_id('CellWithId')
print(ele.text)
场景二:假如想输出表格中所有单元格的值呢?
思路:先定位页面中的表格对象元素;然后在该表格中,通过tag name = 'tr'找所有行;最后在每行中,通过tag name = 'td'找所有单元格。
from selenium import webdriver
from time import sleep
driver = webdriver.Chrome()
driver.get('C:\\Users\\Desktop\\my_html.html')
table = driver.find_element_by_xpath('/html/body/table[1]')
rows = table.find_elements_by_tag_name('tr')
cols = rows[0].find_elements_by_tag_name('td')
for i in range(len(rows)):
for j in range(len(cols)):
cell = rows.find_elements_by_tag_name('td')[j]
print(cell.text)
driver.quit()
框架
●frame一般用来设置页面布局,将整个页面分成规则的几块,每一块里面包含一个新页面;iframe用来在页面的任何地方插入一个新的页面。
from selenium import webdriver
from time import sleep
import os
driver = webdriver.Chrome()
html_file = 'File:///' + os.getcwd() + os.sep + 'myhtml6_8.html'
driver.get(html_file)
driver.switch_to.frame('iframe1') # 通过id切换
# driver.switch_to.frame('name1') # 通过name切换
# driver.switch_to.frame(0) # 通过index切换
driver.find_element_by_id('kw').send_keys('storm') # 尝试定位搜索框,输入文字
sleep(2)
driver.quit()
先定位iframe这个元素,然后切换到目标元素。
from selenium import webdriver
from time import sleep
import os
driver = webdriver.Chrome()
html_file = 'File:///' + os.getcwd() + os.sep + 'myhtml6_8.html'
driver.get(html_file)
ele = driver.find_element_by_xpath('//*[@id="another"]/iframe') # 定位iframe元素
driver.switch_to.frame(ele) # 直接传递元素
driver.find_element_by_id('kw').send_keys('storm')
sleep(2)
driver.quit()
4种从[url=]Web[/url]页面切换到iframe的方法。
●通过id切换(iframe有id属性):driver.switch_to.frame('iframe1')。
●通过name切换(iframe有name属性,且唯一):driver.switch_to.frame('name1')。
●通过index切换(index从0开始,即0代表页面中第一个iframe):driver.switch_to.frame(0)。
●通过定位元素切换:driver.switch_to.frame(iframe_element)。
●总原则:想操作iframe里面的元素,就要先切换到这个iframe上,然后进行操作;想操作iframe外面的元素,就必须跳出这个iframe。对于嵌套的iframe,进去的时候一层层进,出来的时候可以一层层出,也可以直接跳到最外层。
●切换到父级iframe的方法:switch_to. parent_frame。
●切换到主窗口的方法:switch_to.default_content。
JavaScript弹窗
JavaScript弹窗有3种:Alert、Confirm、Prompt。
这3种JavaScript弹窗其实都是input标签,type为按钮(button),都调用了onclick事件,只不过该事件实现的功能有简单和复杂之分,因此其操作类似。
●Alert弹窗:文字信息+确定按钮。
●Confirm弹窗:文字信息+确定按钮+取消按钮。
●Prompt弹窗:文字信息+文本框+确定按钮+取消按钮。
Alert弹窗
下方代码用来准备一个包含Alert弹窗的页面。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Alert学习</title>
</head>
<body>
<h2>Alert Test</h2>
<script type="text/javascript">
function showAlert(){
alert(document.f1.t1.value);
}
</script>
<form name="f1">
<input type="text" name="t1" value="Alert Message"><br><br>
<input type="button" name="b1" value="Click For Alert"><br>
</form>
</body>
</html>
from selenium import webdriver
from time import sleep
driver = webdriver.Chrome()
driver.get('C:\\Users\\yangyl13\\Desktop\\my_html.html')
driver.find_element_by_name('b1').click()#点击按钮
sleep(1)
print(driver.switch_to.alert.text)#打印alert的text
driver.switch_to.alert.accept()#点击alert弹窗的确定按钮
sleep(2)
driver.quit()
confirm弹窗
html示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Confirm学习</title>
</head>
<body>
<h4>Confirm Test</h4>
<script type="text/javascript">
function showConfirm(){
var t1 = document.f1.t1;
if (confirm("Some question?")){
t1.value = "oked";
}else{
t1.value = "canceled";
}
}
</script>
<form name="f1">
<input type="button" name="b1" value="Click For Confirm"><br><br>
<input type="text" name="t1">
</form>
<br>
</body>
</html>
from selenium import webdriver
from time import sleep
driver = webdriver.Chrome()
driver.get('C:\\Users\\yangyl13\\Desktop\\my_html.html')
driver.find_element_by_name('b1').click()#点击按钮
sleep(1)
print(driver.switch_to.alert.text)#打印confirm的text
# driver.switch_to.alert.accept()#点击confirm弹窗的确定按钮
driver.switch_to.alert.dismiss()#点击confirm的取消按钮
sleep(2)
driver.quit()
prompt弹窗
from selenium import webdriver
from time import sleep
driver = webdriver.Chrome()
driver.get('C:\\Users\\yangyl13\\Desktop\\my_html.html')
driver.find_element_by_name('b1').click() # 单击按钮打开Prompt弹窗
sleep(1)
print(driver.switch_to.alert.text) # 输出Prompt弹窗文字
driver.switch_to.alert.send_keys('storm')
sleep(3)
driver.switch_to.alert.accept() # 单击Prompt弹窗中的"确定"按钮
sleep(2)
driver.find_element_by_name('b1').click() # 单击按钮打开Prompt弹窗
sleep(1)
driver.switch_to.alert.send_keys('shadow')
sleep(1)
driver.switch_to.alert.dismiss()
sleep(2)
driver.quit()
这里有个问题,就是send_keys没有输入到prompt的文本框里。
●使用开发者工具无法查看到JavaScript弹窗中的元素,也就是说Alert弹窗是不属于网页DOM树的,在弹窗中单击是没有反应的。
●在使用switch_to.alert.×××之前,首先要确认弹窗确实是JavaScript弹窗。由于Alert 弹窗不美观(样式不好修改),在项目中经常会使用其他类型的弹窗。
非JavaScript弹窗
JavaScript弹窗虽然使用起来很方便,但支持的功能过于简单,某些情况下很难满足项目中的需求,因此还可能会使用其他类型的弹窗。
(1)[url=]Windows[/url][url=]浏览器[/url]弹窗单击某个链接之后可能会打开一个新的浏览器弹窗,注意该弹窗跟之前的弹窗是平行关系,有自己的地址栏、最大化按钮、最小化按钮等,这个很容易分辨。而Alert弹窗更类似父子关系,或者叫从属关系,Alert必须依托于某一个弹窗。对于Windows浏览器弹窗,我们只需要通过窗口句柄切换到目标窗口,然后操作即可。
(2)div弹窗div弹窗是通过网页元素构造成的弹窗。这种弹窗一般比较花哨且内容比较多,可以使用开发者工具查看元素内容。
对于这类弹窗,将其视为普通元素去定位就好了。
◆注意事项在处理弹窗类元素的时候,需要做好元素是否已经加载的判断,避免由于网络等原因造成弹窗加载慢、元素定位不到等问题。
日期时间控件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>日期时间控件</title>
</head>
<body>
<input type="date" name="name1" id="id1">
</body>
</html>
日期时间控件的外观虽然多种多样,但使用浏览器开发者工具查看,可以发现它就是一个input框。对于input框,我们是不是可以像普通文本框一样直接输入日期。
from selenium import webdriver
from time import sleep
driver = webdriver.Chrome()
driver.get('C:\\Users\\yangyl13\\Desktop\\my_html.html')
sleep(2)
driver.find_element_by_tag_name('input').send_keys('002020/06/06')
sleep(5)
driver.quit()
◆注意事项
●日期时间控件本身功能是否健全,需要人工去验证,自动化模拟单击实现成本太高(实际上,如果用的是标准化的日期时间控件,已经有大把的团队验证过其功能的健全性了)。
●自动化一般不验证日期时间控件的功能,只需要模拟输入,然后验证其他功能即可(自动化不是万能的,又或者说“物尽其用”即可)。
●有些日期时间控件有readonly属性,在使用send_keys方法之前,我们就需要做点“准备工作”了
文件下载
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>文件下载</title>
</head>
<body>
<a href="storm.rar" download="storm.rar">下载</a>
</body>
</html>
下载的本质就是一个<a>标签,有点类似链接,点击即可。
如何下载到指定路径?
from selenium import webdriver
from time import sleep
import os
chromeOptions = webdriver.ChromeOptions() # 定义变量,存储Chrome浏览器的设置项
prefs = {"download.default_directory": "D:\\A\\"} # 指定默认下载路径
chromeOptions.add_experimental_option("prefs", prefs) # 将prefs定义的下载路径应用于浏览器设置
driver = webdriver.Chrome(chrome_options=chromeOptions) # 以自定义的设置项启动浏览器
html_file = 'File:///' + os.getcwd() + os.sep + 'myhtml6_13.html'
driver.get(html_file)
sleep(2)
driver.find_element_by_tag_name('a').click()
sleep(5)
driver.quit()
如何验证确实下载了文件呢?
from selenium import webdriver
from time import sleep
import os
if os.path.exists("D:\\A\\storm.rar"): # 先判断文件是否存在
os.remove("D:\\A\\storm.rar") # 如果存在则删除
chromeOptions = webdriver.ChromeOptions() # 定义变量,存储Chrome浏览器的设置项
prefs = {"download.default_directory": "D:\\A\\"} # 指定默认下载路径
chromeOptions.add_experimental_option("prefs", prefs) # 将prefs定义的下载路径应用于浏览器设置
driver = webdriver.Chrome(chrome_options=chromeOptions) # 以自定义的设置项启动浏览器
html_file = 'File:///' + os.getcwd() + os.sep + 'myhtml6_13.html'
driver.get(html_file)
sleep(2)
driver.find_element_by_tag_name('a').click()
sleep(5) # 等待下载完成,然后再去判断文件是否存在
if os.path.exists("D:\\A\\storm.rar"): # 判断文件是否存在
print("文件下载成功")
driver.quit()
如何比对下载的文件?MD5值。
文件上传
在实际项目中,我们遇到的上传按钮大体上可以分为两种:一种是input控件,另外一种是通过js、flash等实现的且较复杂的非input控件。
input控件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>文件上传学习</title>
</head>
<body>
<form name="form1" action="fileUpload.php" method="post" enctype="multipart/form-data">
<label for="file">File:</label>
<input type="file" name="file" id="file" />
</form>
</body>
</html>
对于“input类型文件上传”功能,我们可以通过“send_keys”+“文件”的方式跳过对文件选择弹窗的操作。要知道这个文件选择弹窗是Windows弹窗,而WebDriver的操作范围是浏览器,我们是无法让其控制Windows弹窗的。
from selenium import webdriver
from time import sleep
driver = webdriver.Chrome()
driver.get('C:\\Users\\yangyl13\\Desktop\\my_html.html')
sleep(2)
driver.find_element_by_id('file').send_keys("C:\\Users\\yangyl13\\Desktop\\test.txt")
sleep(2)
driver.quit()
selenium不支持上传多个文件。
非input 型上传控件
对于非input型上传控件,就不能使用send_keys取巧了。这类上传控件种类众多,有用a标签的、有用div的、有用button的、有用object的,我们没有办法直接在网页上处理这些上传操作。唯一的办法就是打开操作系统弹窗,再想办法去处理弹窗。而对于操作系统的弹窗,其涉及的层面已经不是Selenium能解决的了,怎么办?
很简单,用操作系统层面的操作去处理,到这里我们基本找到了处理问题的思路。大致有以下几种方案。
●AutoIt,借助外力,我们去调用其生成的“.au3”或“.exe”文件。
●Python pywin32库,识别弹窗句柄,进而处理弹窗。
●SendKeys库。
注意:当单击type=file的input类型的元素时会报错。
遇到上传文件控件时,看看其是否是input型。如果是,那么恭喜你,可以用send_keys解决。如果碰到了div型的控件,用AutoIt处理也不难。如果还想验证能否同时上传多个文件,那么只能使用pywin32库来处理。
|
|