元素定位

获取页面元素属性

元素判断

元素操作

操作输入框/单击

双击

下拉框操作

键盘操作

鼠标操作

单选框操作

多选框操作

拖动窗口

操作 JS 框

切换 frame

使用 JS 操作页面对象

操作滚动条

浮动(联想)选项选择

更改页面对象的属性值

文件下载

文件上传

操作日期控件

操作富文本框

高亮显示操作元素

切换浏览器标签页

操作表格

测试 HTML5 的视频播放器

断言

截屏

隐式等待

显式等待

操作 cookies

页面加载超时

结束 Windows 的浏览器进程

浏览器相关配置

元素定位

 1 ''' 使用id定位 '''
2 driver.find_element_by_id("id值")
3 driver.find_element("id", "id值") # 该方式可分离定位方式,更适合封装
4
5
6 ''' 使用xpath定位 '''
7 # 定位单个元素
8 driver.find_element_by_xpath("xpath定位表达式")
9 driver.find_element("xpath", "xpath定位表达式")
10 # 定位多个元素,返回列表
11 driver.find_elements_by_xpath("xpath定位表达式")
12 driver.find_elements("xpath", "xpath定位表达式")
13
14
15 ''' 使用name定位 '''
16 # 定位单个元素
17 driver.find_element_by_name("name值")
18 driver.find_element("name", "name值")
19 # 定位多个元素
20 driver.find_elements_by_name("name值")
21 driver.find_elements("name", "name值")
22
23
24 ''' 使用classname定位 '''
25 # 定位单个元素
26 driver.find_element_by_class_name("class属性值")
27 driver.find_element("classname", "class属性值")
28 # 定位多个元素
29 driver.find_elements_by_class_name("class属性值")
30 driver.find_elements("classname", "class属性值")
31
32
33 ''' 使用标签名称定位 '''
34 # 定位单个元素
35 driver.find_element_by_tag_name("标签名称")
36 driver.find_element("tagname", "标签名称")
37 # 定位多个元素
38 driver.find_elements_by_tag_name("标签名称")
39 driver.find_elements("tagname", "标签名称")
40
41
42 ''' 使用链接的全部文字定位 '''
43 # 定位单个元素
44 driver.find_element_by_link_text("链接全部本文内容")
45 driver.find_element("linktext", "链接全部本文内容")
46 # 定位多个元素
47 driver.find_elements_by_link_text("链接全部本文内容")
48 driver.find_elements("linktext", "链接全部本文内容")
49
50
51 ''' 使用部分链接文字定位 '''
52 # 定位单个元素
53 driver.find_element_by_partial_link_text("链接的部分本文内容")
54 driver.find_element("partial link text", "链接的部分本文内容")
55 # 定位多个元素
56 driver.find_elements_by_partial_link_text("链接的部分本文内容")
57 driver.find_elements("partial link text", "链接的部分本文内容")
58
59
60 ''' 使用CSS方式定位 '''
61 # 定位单个元素
62 driver.find_element_by_css_selector("CSS定位表达式")
63 driver.find_element("css selector", "CSS定位表达式")
64 # 定位多个元素
65 driver.find_elements_by_css_selector("CSS定位表达式")
66 driver.find_elements("css selector", "CSS定位表达式")

获取页面元素的属性信息

 1 from selenium import webdriver
2 import time
3
4
5 driver = webdriver.Chrome()
6 driver.get("https://baidu.com")
7
8 searchBox = driver.find_element_by_id('kw')
9 element = driver.find_element_by_xpath("//a[text()='使用百度前必读']")
10
11 # 元素的标签名
12 print(element.tag_name)
13 # 元素的大小
14 print(element.size)
15 # 元素的本文内容
16 print(element.text)
17 # 获取元素指定属性的值,等价于get_property())
18 print(element.get_attribute("name")) # 如"name"、"value"等属性
19
20 element = driver.find_element_by_id("kw")
21 element.send_keys("hippop")
22 print(element.get_attribute("value")) # 获取输入框的值
23
24
25 # 获取页面元素的CSS属性值
26 searchBox = driver.find_element_by_id('kw')
27 print(searchBox.value_of_css_property("height"))
28 print(searchBox.value_of_css_property("width"))
29
30 button = driver.find_element_by_id('su')
31 print(button.value_of_css_property("font-size"))
32 print(button.value_of_css_property("font-family"))
33
34
35 time.sleep(3)
36 # driver.close() # 关闭浏览器的当前tab窗口
37 driver.quit() # 关闭浏览器

元素判断

判断元素是否存在

 1 from selenium import webdriver
2 from selenium.webdriver import ActionChains
3 import time
4
5
6 driver = webdriver.Chrome()
7 driver.get("http://www.baidu.com")
8
9
10 # 函数封装:判断元素是否存在
11 def isElementPresent(driver, by, value):
12 try:
13 element = driver.find_element(by=by, value=value)
14 except NoSuchElementException as e:
15 # 打印异常信息
16 print(e)
17 # 发生了NoSuchElementException异常,说明页面中未找到该元素,返回False
18 return False
19 else:
20 # 没有发生异常,表示在页面中找到了该元素,返回True
21 return True
22
23 if isElementPresent(driver, "id", "kw"):
24 driver.find_element_by_id("kw").send_keys("hiphop")
25
26
27 time.sleep(3)
28 driver.quit()

element.is_displayed():判断元素是否可显示(未被隐藏)

 1 from selenium import webdriver
2 import time
3
4
5 driver = webdriver.Chrome()
6 driver.get("http://39.100.104.214/test_visible.html")
7
8 element = driver.find_element_by_id("div1")
9 print(element.is_displayed()) # True
10 element = driver.find_element_by_id("div2")
11 print(element.is_displayed()) # False
12
13 time.sleep(3) # 休眠3秒后点击按钮,让元素隐藏
14 button = driver.find_element_by_id("button1")
15 button.click()
16
17 element = driver.find_element_by_id("div1")
18 print(element.is_displayed()) # False
19 element = driver.find_element_by_id("div2")
20 print(element.is_displayed()) # True
21
22
23 time.sleep(2)
24 driver.quit()

element.is_enabled():判断元素是否可用

 1 from selenium import webdriver
2 import time
3
4
5 driver = webdriver.Chrome()
6 driver.get("http://39.100.104.214/test_enable.html")
7
8 button = driver.find_element_by_id("input1") # 可操作
9 print(button.is_enabled()) # True
10
11 button = driver.find_element_by_id("input2") # 不可用(标签中加了"disabled"属性)
12 print(button.is_enabled()) # False
13
14 button = driver.find_element_by_id("input3") # 只读(标签中加了"readonly"属性)
15 print(button.is_enabled()) # True
16
17
18 time.sleep(2)
19 driver.quit()

element_located_selection_state_to_be():判断一个元素的状态是否是给定的选择状态

方式1:element_selection_state_to_be(driverObject, state)

  • driverObject:定位器
  • state:期望的元素状态,True表示选中状态,False反之。相等返回True,否则返回False
 1 from selenium.webdriver.common.by import By
2 from selenium.webdriver.support.ui import WebDriverWait
3 from selenium.webdriver.support import expected_conditions as EC
4
5 # 设置显式等待时间为10秒
6 wait = WebDriverWait(driver, 10)
7
8 # 判断给定的元素是否被选中
9 # EC.element_selection_state_to_be(driverObject, state)
10
11 # 设定元素当前选中状态为True
12 EC.element_selection_state_to_be(driver.find_element_by_id("peach"), True).is_selected # 此句会先校验元素是否存在,不存在则抛异常
13
14 # 显式等待元素是否为选中状态,若是选中状态则返回True,若超过10秒仍不为选中状态,则跑出异常(异常提示信息为:超时10秒)
15 wait.until(EC.element_selection_state_to_be(driver.find_element_by_id("peach"), True))
16 # 显式等待元素是否不为选中状态,若不为选中状态则返回False
17 wait.until_not(EC.element_selection_state_to_be(driver.find_element_by_id("peach"), True))

方式2:element_selection_state_to_be(locator, state)

  • locator:定位器,是一个元组 (by, path)
  • state:期望的元素状态,True表示选中状态,False反之。相等返回True,否则返回False
1 # 原型
2 EC.element_located_selection_state_to_be((By.ID, "peach"), True).is_selected # 不会校验元素是否存在,返回True
3 # True
4 wait.until(EC.element_located_selection_state_to_be((By.ID, "peach"), True))
5 # Flase
6 wait.until_not(EC.element_located_selection_state_to_be((By.ID, "waterlemon"), True))

其他

element_to_be_clickable(locator):判断某元素是否可见且能被单击,满足则返回元素对象,否则返回False

1 # 存在并可见
2 wait.until(EC.element_to_be_clickable((By.ID, "")))
3 # 不存在
4 wait.until_not(EC.element_to_be_clickable((By.ID, "")))

frame_to_be_available_and_switch_to_it(parm):判断frame是否可用,如果可用返回True并切入到该frame

参数 parm 可以是:

  • 定位器 locator
  • 定位方式(id、name等)
  • 元素对象
  • frame 在页面中的索引值

invisibility_of_element_located(locator):希望某元素不出现在页面的DOM中

visibility_of_element_located(locator):希望某元素出现在页面的DOM中

1 element = wait.until(EC.visibility_of_element_located((By.ID, ""), True))
2
3 element = EC.visibility_of(driver.find_element_by_id(""))
4
5 # 判断页面上至少一个元素可见,返回满足条件的所有页面对象。
6 inputs = wait.until(EC.visibility_of_any_elements_located((By.TAG_NAME, "input")))

presence_of_all_elements_located(locator):判断页面上至少一个元素出现(不一定可见),返回满足条件的所有页面对象

1 elements = wait.until(EC.presence_of_all_elements_located((By.TAG_NAME, "input")))
2 # 判断单个元素出现(不一定可见)
3 element = wait.until(EC.presence_of_element_located((By.TAG_NAME, "input")))

staleness_of(driver.find_element_by_id(""):判断元素是否仍在DOM中,如果在规定时间内已经移除,返回True,反之False

text_to_be_present_in_element((By.ID, ""):判断文本内容text是否出现在某个元素中,判断的是元素的text

text_to_be_present_in_element_value(locator, text):判断文本内容text是否出现在某个元素的value属性值中

元素操作

操作输入框

  • 输入内容:element.send_keys()

  • 清空内容:element.clear()

单击:element.click()

 1 from selenium import webdriver
2 import time
3
4 driver = webdriver.Chrome()
5 driver.get("https://baidu.com")
6 time.sleep(2)
7
8 searchBox = driver.find_element_by_id('kw')
9 searchBox.send_keys("before")
10
11 time.sleep(2)
12
13 # 为了防止缓存的文字内容干扰测试结果,把输入框的内容先清空
14 searchBox.clear()
15 searchBox.send_keys("after")
16
17 # 定位"百度一下"按钮
18 button = driver.find_element_by_id("su")
19 # 单击按钮
20 button.click()
21
22 time.sleep(2)
23 driver.quit()

双击:action_chains.double_click(element).perform()

 1 from selenium import webdriver
2 from selenium.webdriver import ActionChains
3 import time
4
5
6 driver = webdriver.Chrome()
7 driver.get("http://39.100.104.214/test_doubleclick.html")
8 time.sleep(2)
9
10 element = driver.find_element_by_id("inputBox")
11
12 action_chains = ActionChains(driver)
13 # 双击元素
14 action_chains.double_click(element).perform()
15
16 time.sleep(2)
17 driver.quit()

下拉框操作

单选

 1 from selenium import webdriver
2 from selenium.webdriver.support.ui import Select
3 import time
4
5
6 driver = webdriver.Chrome()
7 driver.get("http://39.100.104.214/test_select.html")
8
9
10 # 获取下拉框对象
11 select_element = Select(driver.find_element_by_xpath("//select"))
12 print(select_element)
13
14 # 打印默认选中的选项的文本
15 print(select_element.first_selected_option.text)
16
17 # 获取所有的选项对象
18 all_options = select_element.options
19 print(all_options)
20
21 # 判断若第二个选项对象可用,并且没有被选中,就选中它
22 if all_options[1].is_enabled() and not all_options[1].is_selected():
23 # 方式1:通过索引来选择选项
24 select_element.select_by_index(1)
25 print (select_element.all_selected_options[0].text)
26 assert "西瓜" in select_element.all_selected_options[0].text
27
28 time.sleep(1)
29 # 方式2:通过文本来选择选项
30 select_element.select_by_visible_text("猕猴桃")
31 assert "猕猴桃" in select_element.all_selected_options[0].text
32
33 time.sleep(1)
34 # 方式3:通过value属性值来选择选项
35 select_element.select_by_value("shanzha")
36 assert "山楂" in select_element.all_selected_options[0].text
37
38 time.sleep(2)
39 driver.quit()

封装下拉框操作

 1 from selenium import webdriver
2 from selenium.webdriver.support.ui import Select
3 import time
4
5
6 # 根据xpath定位到下拉框对象,再根据选项的文本值选中指定选项
7 def choose_option(driver, select_xpath, option_text):
8 select = driver.find_element_by_xpath(select_xpath)
9 all_options = select.find_elements_by_tag_name("option")
10 # 遍历所有选项对象
11 for option in all_options:
12 # print ("选项显示的文本:", option.text)
13 # print ("选项值为:", option.get_attribute("value"))
14 # 如果选项的文本值为入参,则选中
15 if option.text == option_text:
16 option.click()
17 return
18
19
20 driver = webdriver.Chrome()
21 driver.get("http://39.100.104.214/test_select.html")
22
23 # 找到页面上name属性为“fruit”的下拉框对象,并选中"猕猴桃"选项
24 choose_option(driver, "//select[@name='fruit']", "猕猴桃")
25
26 time.sleep(2)
27 driver.quit()

校验下拉框中的全部选项内容

 1 from selenium import webdriver
2 from selenium.webdriver.support.ui import Select
3 import time
4
5
6 driver = webdriver.Chrome()
7 driver.get("http://39.100.104.214/test_select.html")
8
9 # 定位下拉框对象
10 select_element = Select(driver.find_element_by_xpath("//select"))
11 # 获取所有选项对象
12 actual_options = select_element.options
13 # 以列表形式获取所有选项的文本值
14 actual_options_text = [option.text for option in actual_options]
15 print(actual_options_text)
16
17 expected_values = ['桃子', '西瓜', '橘子', '猕猴桃', '山楂', '荔枝']
18 # 断言下拉框的选项内容是否全部相等
19 assert actual_options_text == expected_values
20
21
22 time.sleep(2)
23 driver.quit()

多选

 1 from selenium import webdriver
2 from selenium.webdriver.support.ui import Select
3 import time
4
5
6 driver = webdriver.Chrome()
7 driver.get("http://39.100.104.214/test_multiple_select.html")
8
9 select_element = Select(driver.find_element_by_xpath("//select"))
10 actual_options = select_element.options
11
12 # 和单选的下拉框一样,遍历所有的选项文字和value
13 for option in actual_options:
14 print(option.text)
15 print(option.get_attribute("value"))
16 if option.text == "桃子": # 基于选项文本选择
17 option.click()
18 if option.get_attribute("value") == "lizhi": # 基于value选择
19 option.click()
20
21 # 打印所有被选中option的值
22 print("First choices:")
23 for option in select_element.all_selected_options:
24 print (option.text)
25
26 time.sleep(2)
27 select_element.select_by_index(1) # 基于坐标选择
28 select_element.select_by_visible_text("荔枝") # 基于选项文本选择
29 select_element.select_by_value("juzi") # 基于value选择
30 select_element.deselect_all() # 取消所有的选项
31
32 # 打印所有被选中option的值
33 print("Second choices:")
34 for option in select_element.all_selected_options: # 空
35 print (option.text)
36
37 time.sleep(2)
38 select_element.select_by_index(1)
39 select_element.select_by_visible_text("荔枝")
40 select_element.select_by_value("juzi")
41
42 time.sleep(2)
43 select_element.deselect_by_visible_text("荔枝") # 基于选项文本取消选择
44 select_element.deselect_by_index(1) # 基于坐标取消选择
45 select_element.deselect_by_value("juzi") # 基于value取消选择
46
47 # 打印所有被选中option的值
48 print("Third choices:")
49 for option in select_element.all_selected_options: # 空
50 print (option.text)
51
52
53 time.sleep(2)
54 driver.quit()

键盘操作

selenium 键盘操作

 1 from selenium import webdriver
2 from selenium.webdriver.common.keys import Keys
3 import time
4
5
6 driver = webdriver.Chrome()
7 driver.get("http://www.baidu.com")
8
9 driver.find_element_by_id("kw").clear() # 清空输入框
10
11 driver.find_element_by_id("kw").send_keys("hiphop") # 输入框内写入文本
12 driver.find_element_by_id("kw").send_keys(Keys.ENTER) # 模拟键盘回车操作
13
14
15 time.sleep(5)
16 driver.quit()

系统键盘事件封装

  1 from selenium import webdriver
2 from selenium.webdriver import ActionChains
3 from selenium.webdriver.common.keys import Keys
4 import win32clipboard as w
5 import win32con
6 import time
7 import win32api
8
9
10 # 读取剪切板
11 def getText():
12 w.OpenClipboard()
13 d = w.GetClipboardData(win32con.CF_TEXT)
14 w.CloseClipboard()
15 return d
16
17
18 # 设置剪切板内容
19 def setText(aString):
20 w.OpenClipboard()
21 w.EmptyClipboard()
22 w.SetClipboardData(win32con.CF_UNICODETEXT, aString)
23 w.CloseClipboard()
24
25
26 VK_CODE ={
27 'enter':0x0D,
28 'ctrl':0x11,
29 'a':0x41,
30 'v':0x56,
31 'x':0x58
32 }
33
34
35 # 键盘键按下
36 def keyDown(keyName):
37 win32api.keybd_event(VK_CODE[keyName], 0, 0, 0)
38
39
40 # 键盘键抬起
41 def keyUp(keyName):
42 win32api.keybd_event(VK_CODE[keyName], 0, win32con.KEYEVENTF_KEYUP, 0)
43
44
45 driver = webdriver.Chrome()
46 url = "https://www.baidu.com"
47 driver.get(url)
48 content = '软件测试'
49
50 setText(content) # 设置剪切板中文字内容为:'软件测试'
51 getContent = getText() # 获取剪切板中的内容
52 print ("剪切板中的内容:", getContent.decode("gbk"))
53 driver.find_element_by_id("kw").click() # 点击输入框,使焦点保持在输入框中
54
55 time.sleep(1)
56 keyDown('ctrl')
57 keyDown('v')
58 # 释放 ctrl + v 组合键软件测试
59 keyUp('v')
60 keyUp('ctrl')
61
62 driver.find_element_by_id('su').click() # 点击搜索按钮
63
64 time.sleep(3)
65 driver.quit()
66
67 #所有的键盘按钮定义
68 '''
69 VK_CODE = {
70 'backspace': 0x08,
71 'tab': 0x09,
72 'clear': 0x0C,
73 'enter': 0x0D,
74 'shift': 0x10,
75 'ctrl': 0x11,
76 'alt': 0x12,
77 'pause': 0x13,
78 'caps_lock': 0x14,
79 'esc': 0x1B,
80 'spacebar': 0x20,
81 'page_up': 0x21,
82 'page_down': 0x22,
83 'end': 0x23,
84 'home': 0x24,
85 'left_arrow': 0x25,
86 'up_arrow': 0x26,
87 'right_arrow': 0x27,
88 'down_arrow': 0x28,
89 'select': 0x29,
90 'print': 0x2A,
91 'execute': 0x2B,
92 'print_screen': 0x2C,
93 'ins': 0x2D,
94 'del': 0x2E,
95 'help': 0x2F,
96 '0': 0x30,
97 '1': 0x31,
98 '2': 0x32,
99 '3': 0x33,
100 '4': 0x34,
101 '5': 0x35,
102 '6': 0x36,
103 '7': 0x37,
104 '8': 0x38,
105 '9': 0x39,
106 'a': 0x41,
107 'b': 0x42,
108 'c': 0x43,
109 'd': 0x44,
110 'e': 0x45,
111 'f': 0x46,
112 'g': 0x47,
113 'h': 0x48,
114 'i': 0x49,
115 'j': 0x4A,
116 'k': 0x4B,
117 'l': 0x4C,
118 'm': 0x4D,
119 'n': 0x4E,
120 'o': 0x4F,
121 'p': 0x50,
122 'q': 0x51,
123 'r': 0x52,
124 's': 0x53,
125 't': 0x54,
126 'u': 0x55,
127 'v': 0x56,
128 'w': 0x57,
129 'x': 0x58,
130 'y': 0x59,
131 'z': 0x5A,
132 'numpad_0': 0x60,
133 'numpad_1': 0x61,
134 'numpad_2': 0x62,
135 'numpad_3': 0x63,
136 'numpad_4': 0x64,
137 'numpad_5': 0x65,
138 'numpad_6': 0x66,
139 'numpad_7': 0x67,
140 'numpad_8': 0x68,
141 'numpad_9': 0x69,
142 'multiply_key': 0x6A,
143 'add_key': 0x6B,
144 'separator_key': 0x6C,
145 'subtract_key': 0x6D,
146 'decimal_key': 0x6E,
147 'divide_key': 0x6F,
148 'F1': 0x70,
149 'F2': 0x71,
150 'F3': 0x72,
151 'F4': 0x73,
152 'F5': 0x74,
153 'F6': 0x75,
154 'F7': 0x76,
155 'F8': 0x77,
156 'F9': 0x78,
157 'F10': 0x79,
158 'F11': 0x7A,
159 'F12': 0x7B,
160 'F13': 0x7C,
161 'F14': 0x7D,
162 'F15': 0x7E,
163 'F16': 0x7F,
164 'F17': 0x80,
165 'F18': 0x81,
166 'F19': 0x82,
167 'F20': 0x83,
168 'F21': 0x84,
169 'F22': 0x85,
170 'F23': 0x86,
171 'F24': 0x87,
172 'num_lock': 0x90,
173 'scroll_lock': 0x91,
174 'left_shift': 0xA0,
175 'right_shift ': 0xA1,
176 'left_control': 0xA2,
177 'right_control': 0xA3,
178 'left_menu': 0xA4,
179 'right_menu': 0xA5,
180 'browser_back': 0xA6,
181 'browser_forward': 0xA7,
182 'browser_refresh': 0xA8,
183 'browser_stop': 0xA9,
184 'browser_search': 0xAA,
185 'browser_favorites': 0xAB,
186 'browser_start_and_home': 0xAC,
187 'volume_mute': 0xAD,
188 'volume_Down': 0xAE,
189 'volume_up': 0xAF,
190 'next_track': 0xB0,
191 'previous_track': 0xB1,
192 'stop_media': 0xB2,
193 'play/pause_media': 0xB3,
194 'start_mail': 0xB4,
195 'select_media': 0xB5,
196 'start_application_1': 0xB6,
197 'start_application_2': 0xB7,
198 'attn_key': 0xF6,
199 'crsel_key': 0xF7,
200 'exsel_key': 0xF8,
201 'play_key': 0xFA,
202 'zoom_key': 0xFB,
203 'clear_key': 0xFE,
204 '+': 0xBB,
205 ',': 0xBC,
206 '-': 0xBD,
207 '.': 0xBE,
208 '/': 0xBF,
209 '`': 0xC0,
210 ';': 0xBA,
211 '[': 0xDB,
212 '\\': 0xDC,
213 ']': 0xDD,
214 "'": 0xDE,
215 '`': 0xC0
216 }
217 '''

系统键盘事件(组合键)的综合应用(输入框内容,全选、剪切、粘贴)

 1 from selenium import webdriver
2 from selenium.webdriver import ActionChains
3 from selenium.webdriver.common.keys import Keys
4 import win32clipboard as w
5 import win32con
6 import time
7 import win32api
8
9
10 VK_CODE ={
11 'enter':0x0D,
12 'ctrl':0x11,
13 'a':0x41,
14 'v':0x56,
15 'x':0x58
16 }
17
18
19 #键盘键按下
20 def keyDown(keyName):
21 win32api.keybd_event(VK_CODE[keyName], 0, 0, 0)
22
23
24 #键盘键抬起
25 def keyUp(keyName):
26 win32api.keybd_event(VK_CODE[keyName], 0, win32con.KEYEVENTF_KEYUP, 0)
27
28
29 driver = webdriver.Chrome()
30 url = "https://www.baidu.com"
31 driver.get(url)
32
33 driver.find_element_by_id("kw").click()
34 driver.find_element_by_id("kw").send_keys("野生动物")
35 time.sleep(1)
36 keyDown('ctrl')
37 keyDown('a')
38 # 释放ctrl + a组合键
39 keyUp('a')
40 keyUp('ctrl')
41
42 keyDown('ctrl')
43 keyDown('x')
44 # 释放ctrl + x组合键
45 keyUp('x')
46 keyUp('ctrl')
47 time.sleep(2)
48
49 keyDown('ctrl')
50 keyDown('v')
51 # 释放ctrl + v组合键
52 keyUp('v')
53 keyUp('ctrl')
54
55 driver.find_element_by_id("kw").send_keys("保护")
56
57 driver.find_element_by_id('su').click()
58
59
60 time.sleep(3)
61 driver.quit()

ActionChains 键盘组合事件

 1 from selenium import webdriver
2 from selenium.webdriver import ActionChains
3 from selenium.webdriver.common.keys import Keys
4 import time
5
6
7 driver = webdriver.Chrome()
8 url = "https://www.baidu.com"
9 driver.get(url)
10
11
12 search_box = driver.find_element_by_id('kw') # 定位到输入框
13 search_box.send_keys("hiphop")
14 driver.find_element_by_id("kw").click() # 点击输入框,保证焦点在输入框
15
16 ActionChains(driver).key_down(Keys.CONTROL).send_keys('a').key_up(Keys.CONTROL).perform() # Ctrl + a 组合键
17 time.sleep(2)
18 ActionChains(driver).key_down(Keys.CONTROL).send_keys('x').key_up(Keys.CONTROL).perform() # Ctrl + x 组合键
19 time.sleep(2)
20 ActionChains(driver).key_down(Keys.CONTROL).send_keys('v').key_up(Keys.CONTROL).perform() # Ctrl + v 组合键
21 time.sleep(2)
22
23 driver.find_element_by_id('su').click() # 点击搜索按钮
24
25 time.sleep(3)
26 driver.quit()

鼠标操作

 1 from selenium import webdriver
2 from selenium.webdriver import ActionChains
3
4
5 # 鼠标右键
6 ActionChains(driver).context_click().perform()
7
8 # 鼠标左键与释放
9 ActionChains(driver).click_and_hold("div").perform()
10 ActionChains(driver).release("div").perform()
11
12 # 鼠标悬浮
13 ActionChains(driver).move_to_element("元素").perform()
14
15 # 拖拽
16 ActionChains(driver).drag_and_drop("被拖拽的元素", "目标位置").perform()
17 ActionChains(driver).drag_and_drop_by_offset("被拖拽的元素", 10, 10).perform() # 向右下拖动10个像素

单选框操作

 1 from selenium import webdriver
2 from selenium.webdriver.common.keys import Keys
3 import time
4
5
6 driver = webdriver.Chrome()
7 driver.get("http://39.100.104.214/test_radio.html")
8
9 # 定位到“草莓”单选框
10 radio = driver.find_element_by_xpath("//input[@value='berry']")
11 if not radio.is_selected():
12 radio.click()
13 time.sleep(2)
14
15 #定位到“西瓜”单选框
16 radio = driver.find_element_by_xpath("//input[@value='watermelon']")
17 if not radio.is_selected():
18 radio.click()
19 # 断言单选框是否被选中
20 assert radio.is_selected() == True
21
22 # 遍历所有单选框,依次选择
23 for radio in driver.find_elements_by_xpath("//input[@name='fruit']"):
24 time.sleep(1)
25 radio.click()
26
27 #遍历所有单选框
28 for radio in driver.find_elements_by_xpath("//input[@name='fruit']"):
29 # 当单选框value为“berry”时,进行选择
30 if radio.get_attribute("value") == "berry":
31 time.sleep(1)
32 radio.click()
33
34
35 time.sleep(2)
36 driver.quit()

多选框操作

 1 from selenium import webdriver
2 from selenium.webdriver.common.keys import Keys
3 import time
4
5
6 driver = webdriver.Chrome()
7 driver.get("http://39.100.104.214/test_checkbox.html")
8
9 # 定位到“草莓”复选框
10 check_box = driver.find_element_by_xpath("//input[@value='berry']")
11 if not check_box.is_selected():
12 # 选择“草莓”复选框(第一次选择)
13 check_box.click()
14 time.sleep(2)
15 # 取消选择“草莓”复选框(第二次重复选择)
16 check_box.click()
17
18 time.sleep(2)
19 # 遍历所有复选框
20 for check_box in driver.find_elements_by_xpath("//input[@name='fruit']"):
21 check_box.click() # 依次选择复选框
22
23
24 time.sleep(2)
25 driver.quit()

操作 JS 框

 1 # 操作JS的Alert弹窗
2 alert = driver.switch_to.alert()
3 alert.accept()
4
5 # 操作JS的confirm弹窗
6 alert = driver.switch_to.alert()
7 alert.accept() # "确定"按钮
8 alert.dismiss() # "取消"按钮
9
10 # 操作JS的Prompt弹窗
11 alert = driver.switch_to.alert()
12 alert.send_keys("弹窗中输入自定义文本")
13 alert.accept() # "确定"按钮
14 alert.dismiss() # "取消"按钮

切换frame

iframe 同理。

 1 # 使用索引值切换frame
2 driver.switch_to.frame(0)
3
4 # 回到主frame页面(才能继续切换到其他frame)
5 driver.switch_to.default_content()
6 # 通过其他frame元素对象切换
7 driver.switch_to.frame(self.driver.find_element_by_tag_name("frame")[0])
8
9 driver.switch_to.default_content()
10 driver.switch_to.frame(self.driver.find_element_by_id("rightframe"))

使用 JS 操作页面对象

 1 from selenium import webdriver
2 import time
3
4 driver = webdriver.Chrome()
5 url = "http://www.sogou.com"
6 # 访问baidu首页
7 driver.get(url)
8
9 # 当selenium的click不好用时
10 # JS执行输入和点击
11 searchInputBoxJS = "document.getElementById('query').value='hiphop';"
12 searchButtonJS = "document.getElementById('stb').click()"
13
14 driver.execute_script(searchInputBoxJS)
15 driver.execute_script(searchButtonJS)
16
17 time.sleep(3)
18 assert '嘻哈' in driver.page_source
19
20 driver.quit()

操作滚动条

 1 from selenium import webdriver
2
3
4 driver = webdriver.Chrome()
5 url = "http://www.sohu.com"
6 driver.get(url)
7
8 # 移动到末尾
9 driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
10 # 移动到中间
11 driver.execute_script("window.scrollTo(0, document.body.scrollHeight/2);")
12
13 # 基于第多少个标签的元素来移动(若使用相同的个数则不会移动)
14 driver.execute_script("document.getElementsByTagName('a')[100].scrollIntoView(true);")
15 # 基于像素移动
16 driver.execute_script("window.scrollBy (0,400);")

浮动(联想)选项选择

 1 # 方法一:模拟按键
2 searchBox = self.driver.find_element_by_id("").send_keys("嘻哈")
3 searchBox.send_keys(Keys.DOWN)
4 searchBox.send_keys(Keys.ENTER)
5
6 # 方法二:匹配模糊内容
7 suggestion_option = self.driver.find_element_by_xpath("//ul/li[contains(., '篮球公园')]")
8 suggestion_option.click()
9
10 # 方法三:通过索引(索引从1开始)
11 suggestion_option = self.driver.find_element_by_xpath("//ul/li[3]")

 

更改页面对象的属性值

注意:只针对当前会话有效,页面源码并没有真正改变。

使用场景:当原本的元素难以定位或操作时,可临时使用该方法为元素添加属性以方便后续继续操作。

 1 from selenium import webdriver
2 import time
3
4
5 def addAttribute(driver, elementObj, attributeName, value):
6 # 封装向页面标签中添加新属性方法
7 # 调用JavaScript代码给页面标签添新属性,arguments [0] - [2] 分别会用后面的
8 # element、attributeName和value参数值进行替换,并执行该JavaScript代码
9 # 添加新属性的JavaScript代码语法为:element.attributeName = value
10 # 比如input.name="test"
11 driver.execute_script("arguments[0].%s=arguments[1]" %attributeName, elementObj, value)
12
13 def setAttribute(driver, elementObj, attributeName, value):
14 # 封装设置页面对象的属性值的方法
15 # 调用JavaScript代码修改页面元素的属性值,arguments [0] - [2] 分别会用后面的
16 # element、attributeName和value参数值进行替换,并执行该JavaScript代码
17 driver.execute_script("arguments[0].setAttribute(arguments[1],arguments[2])", elementObj, attributeName, value)
18
19 def getAttribute(elementObj, attributeName):
20 # 封装获取页面对象的属性值的方法
21 return elementObj.get_attribute(attributeName)
22
23 def removeAttribute(driver, elementObj, attributeName):
24 # 封装删除页面元素属性的方法
25 # 调用JavaScript代码删除页面元素的指定的属性,arguments [0] - [1] 分别会用后面的
26 # element、attributeName参数值进行替换,并执行该JavaScript代码
27 driver.execute_script("arguments[0].removeAttribute(arguments[1])", elementObj, attributeName)
28
29
30 driver = webdriver.Chrome()
31 url = "http://39.100.104.214/test_change_attr.html"
32 driver.get(url)
33
34 element = driver.find_element_by_xpath("//input")
35
36 # 给输入框对象新增属性name
37 addAttribute(driver, element, 'name', "search")
38 print ('添加的新属性值%s="%s"' %("name", getAttribute(element, "name")))
39
40 time.sleep(3)
41 print ("更改文本框中的内容前的内容:", getAttribute(element, "value"))
42 # 更改input页面元素的value属性值为:这是更改后的文字内容:xxxxx
43 setAttribute(driver, element, "value", "xxxxxxx")
44
45 time.sleep(3)
46 print ("更改文本框中内容后的内容:", getAttribute(element, "value"))
47
48 # 修改输入框的长度
49 setAttribute(driver, element, "size", 20)
50 print ("更改后文本框标签中的size属性值:", getAttribute(element, "size"))
51
52 time.sleep(3)
53 # 删除输入框里面的值
54 removeAttribute(driver, element, "value")
55 print ("删除value属性值后value属性值:", getAttribute(element, "value"))
56
57 driver.quit()

文件下载

示例1:Chrome版

 1 from selenium import webdriver
2 import time
3 from selenium.webdriver.chrome.options import Options
4
5
6 options = Options()
7 options.add_experimental_option("prefs", {
8 "download.default_directory": "e:\\", # 指定下载目录
9 "download.prompt_for_download": False,
10 "download.directory_upgrade": True,
11 "safebrowsing.enabled": True
12 })
13
14 # 初始化配置
15 driver = webdriver.Chrome(chrome_options=options)
16
17 url = "http://mirrors.hust.edu.cn/apache/zzz/mirror-tests/"
18 driver.get(url)
19
20 # 点击下载文件
21 driver.find_element_by_partial_link_text("tar.gz").click()
22
23 # 等待文件下载(等待时间根据实际情况而定)
24 time.sleep(10)
25 driver.quit()

示例2:Firefox版

 1 from selenium import webdriver
2
3
4 # 无人工干预地自动下载文件的相关配置
5 def setProfile():
6     # 创建一个FirefoxProfile实例,用于存放自定义配置
7     profile = webdriver.FirefoxProfile()
8     # 指定下载路径,默认只会创建一级目录,如果指定了多级不存在的目录,将会
9     # 下载到默认路径
10     profile.set_preference("browser.download.dir", "d:\\iDownload")
11     # browser.download.folderList:2表示下载到指定路径;0表示下载到桌面;
12     # 1表示下载到默认路径
13     profile.set_preference("browser.download.folderList", 2)
14     # browser.helperApps.alwaysAsk.force:对于未知的MIME类型文件会弹出
15     # 窗口让用户处理,默认值为True,设定为False表示不会记录打开未知MIME类型
16     # 文件的方式。
17     profile.set_preference("browser.helperApps.alwaysAsk.force", False)
18     # 在开始下载是是否显示下载管理器
19     profile.set_preference("browser.download.manager.showWhenStarting", False)
20     # False隐藏下载框
21     profile.set_preference("browser.download.manager.useWindow", False)
22     # 默认值为True,False表示不获取焦点
23     profile.set_preference("browser.download.manager.focusWhenStarting", False)
24     # 下载EXE文件弹出警告;False表示不弹出警告框
25     profile.set_preference("browser.download.manager.alertOnEXEOpen", False)
26     # browser.helperApps.neverAsk.openFile表示直接打开下载文件,不显示确认框
27     # 默认值为空字符串,文件类型可用逗号隔开,如"application/exe","application/excel"
28     profile.set_preference("browser.helperApps.neverAsk.openFile", "application/pdf")
29     # 对所给出文件类型不再弹出提示框进行询问,直接保存到本地磁盘
30     profile.set_preference("browser.helperApps.neverAsk.saveToDisk",
31                            "application/zip, application/octet - stream")
32     # 下载完成后是否显示完成提示框
33     profile.set_preference("browser.download.manager.showAlertOnComplete", False)
34     # 下载结束后是否自动关闭下载框;False表示不关闭
35     profile.set_preference("browser.download.manager.closeWhenDone", False)
36
37     return profile
38
39
40 # 启动浏览器时,添加设定好的自定义配置
41 driver = webdriver.Firefox(firefox_profile=setProfile())
42
43 url = "https://www.python.org/downloads/release/python-2712/"
44 driver.get(url)
45 # 找到Python2.7.12下载页面中链接文字为“Windows x86-64 MSI installer”
46 # 的链接页面元素,点击进行无人工干预的下载Python2.7.12解释器文件
47 driver.find_element_by_link_text\
48 ("Windows x86-64 MSI installer").click()
49 # 等待文件下载完成,根据各自的网络带宽情况设定等待相应的时间
50 time.sleep(100)

文件上传

方式1:使用 send_keys 上传文件

 1 from selenium import webdriver
2 from selenium.webdriver.support.ui import WebDriverWait
3 from selenium.webdriver.common.by import By
4 from selenium.webdriver.support import expected_conditions as EC
5 import time
6
7
8 driver = webdriver.Chrome()
9 url= 'http://39.100.104.214/test_upload_file.html'
10 driver.get(url)
11
12 wait = WebDriverWait(driver, 10, 0.2)
13 # 显示等待判断被测试页面上的上传文件按钮是否处于可被点击状态
14 wait.until(EC.element_to_be_clickable((By.ID, 'file')))
15 # 选择文件按钮直接输入文件名
16 driver.find_element_by_id("file").send_keys("e:\\file.txt")
17
18 time.sleep(3)
19 # 提交文件
20 fileSubmitButton = driver.find_element_by_id("filesubmit")
21 fileSubmitButton.click()
22
23 time.sleep(2)
24 driver.close()

方式2:使用键盘事件

注意:键盘事件无法使用并发,仅适用单个用例执行的情况

 1 from selenium import webdriver
2 import unittest
3 import time
4 import traceback
5 import win32clipboard as w
6 import win32api
7 import win32con
8 from selenium.webdriver.support.ui import WebDriverWait
9 from selenium.webdriver.common.by import By
10 from selenium.webdriver.support import expected_conditions as EC
11 from selenium.common.exceptions import TimeoutException, NoSuchElementException
12
13
14 # 用于设置剪切板内容
15 def setText(aString):
16 w.OpenClipboard()
17 w.EmptyClipboard()
18 w.SetClipboardData(win32con.CF_UNICODETEXT, aString)
19 w.CloseClipboard()
20
21 # 键盘按键映射字典
22 VK_CODE = {
23 'enter':0x0D,
24 'ctrl':0x11,
25 'v':0x56}
26
27 # 键盘键按下
28 def keyDown(keyName):
29 win32api.keybd_event(VK_CODE[keyName], 0, 0, 0)
30 # 键盘键抬起
31 def keyUp(keyName):
32 win32api.keybd_event(VK_CODE[keyName], 0, win32con.KEYEVENTF_KEYUP, 0)
33
34 driver = webdriver.Chrome()
35 url= 'http://39.100.104.214/test_upload_file.html'
36 driver.get(url)
37 wait = WebDriverWait(driver, 10, 0.2)
38 # 显示等待判断被测试页面上的上传文件按钮是否处于可被点击状态
39 wait.until(EC.element_to_be_clickable((By.ID, 'file')))
40
41 setText(u"c:\\test.txt")
42 driver.find_element_by_id("file").click()
43
44 time.sleep(2)
45 # 模拟键盘按下ctrl + v组合键
46 keyDown("ctrl")
47 keyDown("v")
48 # 模拟键盘释放Ctrl + v组合键
49 keyUp("v")
50 keyUp("ctrl")
51 time.sleep(1)
52 # 模拟键盘按下回车键
53 keyDown("enter")
54 # 模拟键盘释放回车键
55 keyUp("enter")
56 # 暂停查看上传的文件
57
58 time.sleep(3)
59 fileSubmitButton = driver.find_element_by_id("filesubmit")
60 fileSubmitButton.click()

操作日期控件

 1 from selenium import webdriver
2 import time
3
4
5 driver = webdriver.Chrome()
6 url= 'http://jqueryui.com/resources/demos/datepicker/other-months.html'
7 driver.get(url)
8 # 操作日期控件
9 wait = WebDriverWait(driver, 10, 0.2)
10 # 显式等待日期控件对象
11 wait.until(EC.element_to_be_clickable((By.ID, "datepicker")))
12
13
14 # 方式1:直接输入值
15 input_box.send_keys("11/24/2016")
16 # 注意:若遇到日期控件不允许用户输入,则可通过JS改变页面元素属性值来将日期控件修改成可编辑状态。
17
18
19 time.sleep(3)
20 input_box.clear()
21 # 方式2:定位日期控件中的日期值对象
22 input_box.click()
23 date = driver.find_element_by_xpath("//a[.='19']")
24 date.click()

操作富文本框

示例:操作邮件正文的富文本框

  • 方式1:通过执行JS

  • 方式2:找到富文本框对象直接输入

 1 from selenium import webdriver
2 import time
3
4
5 driver = webdriver.Firefox()
6 url = "http://mail.sohu.com"
7 driver.get(url)
8
9 # 进行登录
10 time.sleep(3)
11 userName = driver.find_element_by_xpath('//input[@placeholder="请输入您的邮箱"]')
12 userName.clear()
13 userName.send_keys("xxx")
14 passWord = driver.find_element_by_xpath('//input[@placeholder="请输入您的密码"]')
15 passWord.clear()
16 passWord.send_keys("xxx")
17 login = driver.find_element_by_xpath(u'//input[@value="登 录"]')
18 login.click()
19
20 # 进入“写邮件”页面
21 time.sleep(3)
22 driver.find_element_by_xpath(u'//li[text()="写邮件"]').click()
23 time.sleep(1)
24 # 收件人
25 receiver = driver.find_element_by_xpath('//div[@arr="mail.to_render"]//input')
26 time.sleep(1)
27 receiver.send_keys("fosterwu@sohu.com")
28 time.sleep(1)
29 # 标题
30 subject = driver.find_element_by_xpath('//input[@ng-model="mail.subject"]')
31 subject.send_keys("一封测试邮件!")
32 time.sleep(1)
33 iframe = driver.find_element_by_xpath('//iframe[contains(@id, "ueditor")]')
34
35 # 切入到富文本区域的iframe中
36 driver.switch_to.frame(iframe)
37 time.sleep(1)
38 # 定位富文本框
39 editBox = driver.find_element_by_xpath("/html/body")
40
41 # 方式1:通过执行JS方式输入富文本内容
42 driver.execute_script("document.getElementsByTagName('body')[0].innerHTML='<b>邮件的正文内容<b>;'")
43
44 # 方式2:给富文本框元素直接输入内容
45 editBox.send_keys("邮件的正文内容")
46
47 # 从iframe里面切换出来
48 driver.switch_to.default_content()
49 time.sleep(1)
50 # 点击“发送”
51 driver.find_element_by_xpath('//span[.="发送"]').click()
52
53 time.sleep(1)
54 driver.quit()
  • 方式3:使用键盘事件

 1 from selenium import webdriver
2 from selenium.webdriver.common.keys import Keys
3 import win32clipboard as w
4 import win32api, win32con
5 import time
6
7
8 # 用于设置剪切板内容
9 def setText(aString):
10 w.OpenClipboard()
11 w.EmptyClipboard()
12 w.SetClipboardData(win32con.CF_UNICODETEXT, aString)
13 w.CloseClipboard()
14
15 # 键盘按键映射字典
16 VK_CODE = {'ctrl':0x11, 'v':0x56}
17
18 # 键盘键按下
19 def keyDown(keyName):
20 win32api.keybd_event(VK_CODE[keyName], 0, 0, 0)
21
22 # 键盘键抬起
23 def keyUp(keyName):
24 win32api.keybd_event(VK_CODE[keyName], 0, win32con.KEYEVENTF_KEYUP, 0)
25
26
27 driver = webdriver.Firefox()
28 url = "http://mail.sohu.com"
29 driver.get(url)
30
31 time.sleep(2)
32 userName = driver.find_element_by_xpath('//input[@placeholder="请输入您的邮箱"]')
33 userName.clear()
34 userName.send_keys("xxx")
35 passWord = driver.find_element_by_xpath('//input[@placeholder="请输入您的密码"]')
36 passWord.clear()
37 passWord.send_keys("xxx")
38 login = driver.find_element_by_xpath(u'//input[@value="登 录"]')
39 login.click()
40
41 time.sleep(2)
42 driver.find_element_by_xpath(u'//li[text()="写邮件"]').click()
43
44 time.sleep(1)
45 receiver = driver.find_element_by_xpath('//div[@arr="mail.to_render"]//input')
46
47 receiver.send_keys("fosterwu@sohu.com")
48
49 time.sleep(1)
50 subject = driver.find_element_by_xpath('//input[@ng-model="mail.subject"]')
51
52 subject.send_keys("一封测试邮件!")
53
54 # 将焦点移动到正文
55 subject.send_keys(Keys.TAB)
56 subject.send_keys(Keys.TAB)
57
58 setText(u"邮件正文内容")
59 # 将剪贴板的内容粘贴到当前焦点即邮件正文中
60 keyDown("ctrl")
61 keyDown("v")
62 keyUp("v")
63 keyUp("ctrl")
64
65 time.sleep(1)
66 driver.find_element_by_xpath('//span[.="发送"]').click()
67
68 driver.quit()

高亮显示操作元素

 1 from selenium import webdriver
2 import time
3
4
5 def highLightElement(driver,element):
6 # 封装好的高亮显示页面元素的方法
7 # 使用JavaScript代码将传入的页面元素对象的背景颜色和边框颜色分别设置为绿色和红色
8 driver.execute_script("arguments[0].setAttribute('style',\
9 arguments[1]);", element,"background:green; border:2px solid red;")
10
11 driver = webdriver.Chrome()
12
13 url = "http://sogou.com"
14 driver.get(url)
15 searchBox = driver.find_element_by_id("query")
16
17 highLightElement(driver, searchBox)
18 time.sleep(3)
19 searchBox.send_keys("hiphop")
20
21 submitButton = driver.find_element_by_id("stb")
22 highLightElement(driver, submitButton)
23 time.sleep(3)
24 submitButton.click()
25
26 time.sleep(3)
27 driver.quit()

切换浏览器标签页

方式1:遍历标签页对象

 1 from selenium import webdriver
2 import time
3 import win32api, win32con
4
5
6 VK_CODE ={'ctrl':0x11, 't':0x54, 'tab':0x09}
7
8 # 键盘键按下
9 def keyDown(keyName):
10 win32api.keybd_event(VK_CODE[keyName], 0, 0, 0)
11 # 键盘键抬起
12 def keyUp(keyName):
13 win32api.keybd_event(VK_CODE[keyName], 0, win32con.KEYEVENTF_KEYUP, 0)
14
15 # 封装的按键方法
16 def simulateKey(firstKey, secondKey):
17 keyDown(firstKey)
18 keyDown(secondKey)
19 keyUp(secondKey)
20 keyUp(firstKey)
21
22 # 使用快捷键 ctrl+t 新增两个标签页
23 driver = webdriver.Chrome()
24 time.sleep(1)
25 for i in range(2):
26 simulateKey("ctrl", "t")
27
28 # 将焦点切回第一个标签页
29 simulateKey("ctrl", "tab")
30 driver.get("http://sogou.com")
31 driver.find_element_by_id("query").send_keys("hiphop")
32 driver.find_element_by_id("stb").click()
33 time.sleep(3)
34
35 flag = True
36
37 all_handles = driver.window_handles
38 for handle in all_handles:
39 driver.switch_to.window(handle)
40 if "知乎" not in driver.page_source and flag:
41 driver.get("http://www.baidu.com")
42 driver.find_element_by_id("kw").send_keys("hiphop")
43 driver.find_element_by_id("su").click()
44 flag = False
45 time.sleep(2)
46 assert "嘻哈" in driver.page_source
47 elif ("知乎" not in driver.page_source) and ("hiphop" not in driver.page_source):
48 driver.get("http://www.iciba.com")
49 assert "查词" in driver.page_source
50
51 driver.quit()

方式2:使用标签页对象索引

from selenium import webdriver
import time
import win32api, win32con VK_CODE ={'ctrl':0x11, 't':0x54, 'tab':0x09} # 键盘键按下
def keyDown(keyName):
win32api.keybd_event(VK_CODE[keyName], 0, 0, 0)
# 键盘键抬起
def keyUp(keyName):
win32api.keybd_event(VK_CODE[keyName], 0, win32con.KEYEVENTF_KEYUP, 0) # 封装的按键方法
def simulateKey(firstKey, secondKey):
keyDown(firstKey)
keyDown(secondKey)
keyUp(secondKey)
keyUp(firstKey) driver = webdriver.Chrome()
time.sleep(1) # 新增两个标签页
for i in range(2):
simulateKey("ctrl", "t")
time.sleep(1) # 把焦点切换回第一个标签页
simulateKey("ctrl", "tab")
driver.get("http://sogou.com")
driver.find_element_by_id("query").send_keys("hiphop")
driver.find_element_by_id("stb").click()
time.sleep(2) all_handles = driver.window_handles
# 切换到第二个窗口句柄
driver.switch_to.window(all_handles[1])
driver.get("http://www.baidu.com")
driver.find_element_by_id("kw").send_keys("hiphop")
driver.find_element_by_id("su").click()
time.sleep(2) #切换到第三个窗口句柄
driver.switch_to.window(all_handles[2])
driver.get("http://www.baidu.com")
driver.find_element_by_id("kw").send_keys("街舞")
driver.find_element_by_id("su").click()
time.sleep(2) driver.quit()

操作表格

 1 # 操作表格的工具类
2 class Table:
3
4     # 定义一个私有属性__table,用于存放table对象
5     __table = ""
6
7     def __init__(self, table):
8         self.setTable(table)
9
10
11     def setTable(self, table):
12         self.__table = table
13
14
15     def getTable(self):
16         return self.__table
17
18
19     def getRowCount(self):
20         # 返回行数
21         return len(self.__table.find_element_by_tag_name("tr"))
22
23
24     def getColumnCount(self):
25         # 返回列数
26         return len(self.__table.find_element_by_tag_name("td"))
27
28
29     def getCell(self, rowNo, colNo):
30         # 获取表格中某行某列的单元格对象
31         try:
32             currentRow = self.__table.find_element_by_tag_name("tr")[rowNo - 1]
33             currentCell = currentRow.find_element_by_tag_name("td")[colNo - 1]
34             return currentCell
35         except Exception as e:
36             raise e
37
38
39     def getElementInCell(self, rowNo, colNo, by, value):
40         # 获取表格中某行某列的单元格对象
41         try:
42             currentRow = self.__table.find_element_by_tag_name("tr")[rowNo - 1]
43             currentCell = currentRow.find_element_by_tag_name("td")[colNo - 1]
44             element = currentCell.find_element(by=by, value=value)
45             return element
46         except Exception as e:
47             raise e
48
49
50 # 测试示例
51 webTable = driver.find_element_by_tag_name("table")
52 table = Table(webTable)
53 # 获取表格中第二行第三列单元格对象
54 cell = table.getCell(2, 3)
55 self.assertAlmostEqual("第二行第三列", cell.text)
56 cellInput = table.getElementInCell(3, 2, "tag name", "input")
57 cellInput.send_keys("……")

测试HTML5的视频播放器

 1 from selenium import webdriver
2 import time
3
4
5 driver = webdriver.Chrome()
6 url = "https://www.w3school.com.cn/tiy/t.asp?f=html5_av_met_addtexttrack"
7 driver.get(url)
8
9 # 切换到视频播放器所在的frame
10 driver.switch_to.frame(driver.find_element_by_xpath("//iframe[@id='iframeResult']"))
11
12 # 定位视频播放器对象
13 videoPlayer = driver.find_element_by_tag_name("video")
14
15 # 通过播放器内部的currentSrc属性获取视频文件的网络存储地址
16 videoSrc = driver.execute_script("return arguments[0].currentSrc;", videoPlayer)
17 print(videoSrc)
18 assert videoSrc == "https://www.w3school.com.cn/example/html5/mov_bbb.mp4"
19
20 # 通过播放器内部的currentSrc属性获取视频文件的播放时长
21 videoDuration = driver.execute_script("return arguments[0].duration;", videoPlayer)
22 print (videoDuration)
23
24 #点击视频元素,让视频开始播放
25 videoPlayer.click()
26 time.sleep(2)
27
28 #点击视频元素,让视频停止播放,并截屏
29 videoPlayer.click()
30 driver.save_screenshot("e:\\videoPlay_pause.png")
31
32 #点击视频元素,让视频再次播放
33 videoPlayer.click()
34 time.sleep(2)
35
36 driver.quit()

断言

如果断言失败,程序会抛异常,(未捕捉异常的话)程序就不再继续往下执行。

示例:断言网页源码中是否出现某关键字

 1 from selenium import webdriver
2 from selenium.webdriver.common.keys import Keys
3 import time
4
5
6 driver = webdriver.Chrome()
7 driver.get("http://39.100.104.214/test_checkbox.html")
8
9 try:
10 # 断言草莓是否存在于网页源码中
11 assert "草莓" in driver.page_source
12 except AssertionError:
13 print("断言失败!")
14
15
16 time.sleep(2)
17 driver.quit()

截屏

浏览器截屏

  • 只能截当前浏览器屏幕,不能截滚动屏
  • 一般情况下,是断言失败,或者错误时才会使用截屏
  • 提示:IE浏览器截屏图片会出现大黑边
 1 from selenium import webdriver
2 import time
3
4
5 driver = webdriver.Chrome()
6 driver.get("http://www.baidu.com")
7
8 # 截屏,并保存到本地
9 driver.get_screenshot_as_file("e:\\test.png")
10
11
12 time.sleep(2)
13 driver.quit()

操作系统截屏

  • 需要先安装 pillow 包:pip install pillow
  • 只能截当前屏幕,不能截滚动屏
 1 from selenium import webdriver
2 from PIL import ImageGrab # 需要先安装 pillow 包
3 import time
4
5
6 driver = webdriver.Chrome()
7 driver.get("http://www.baidu.com")
8
9 # 最大化浏览器窗口
10 driver.maximize_window()
11 time.sleep(1)
12 im = ImageGrab.grab() # 操作系统截屏
13 im.save("e:\\test2.jpg")
14
15 time.sleep(2)
16 driver.quit()

隐式等待

  • 只需要设置一次,将在整个driver生命周期起作用。
  • 弊端:等页面全部元素加载后才能往下执行代码,容易被某个JS所影响效率。
 1 from selenium import webdriver
2 import time
3
4 driver = webdriver.Chrome()
5
6 url = "http://39.100.106.61:8080/selenium/test_wait.html"
7 driver.get(url)
8
9 # 给后续所有页面元素定位加一个时间上限(10秒)
10 # 若10秒后该元素仍定位不到,则抛异常
11 # 若定位到则马上执行后续代码
12 driver.implicitly_wait(10)
13
14 #手工点击页面按钮,则可以显示h1标签
15 driver.find_element_by_xpath("//h1")
16
17 driver.quit()

显式等待

原理:每隔一段时间(默认0.5秒)执行一下自定义的判定条件,直到超过设定的最大时长,然后抛出TimeoutException。

  • WebDriverWait(self, WebDriver实例对象, 最长等待时间, 调用频率, 执行过程中忽略的异常类型,默认只忽略NoSuchElementException)
  • WebDriverWait.until(method, message("抛出的异常提示信息"))  # 在规定等待时间内,每隔调用频率调用一次method,直到其返回值不为False
  • WebDriverWait.until_not(method, message("抛出的异常提示信息"))  # 直到其返回值不为True
 1 from selenium.webdriver.common.by import By
2 from selenium.webdriver.support.ui import WebDriverWait
3 from selenium.webdriver.support import expected_conditions as EC
4
5
6 # 显式等待对象(最多等10秒,每0.2秒判断一次等待的条件):等待某元素出现,然后输入本文。
7 WebDriverWait(driver, 10, 0.2).until(lambda x: x.find_element_by_id("")).send_keys("某某被找到")
8
9 # 显式等待中的期望场景
10 wait = WebDriverWait(driver, 10)
11 # alert_is_present():判断页面是否出现alert框,在10秒内直到出现alert框才会往下执行代码
12 wait.until(EC.alert_is_present()).text

示例:常见显式等待条件

 1 from selenium import webdriver
2 from selenium.webdriver import ActionChains
3 # 导入By类
4 from selenium.webdriver.common.by import By
5 # 导入显示等待类
6 from selenium.webdriver.support.ui import WebDriverWait
7 # 导入期望场景类
8 from selenium.webdriver.support import expected_conditions as EC
9 from selenium.common.exceptions import TimeoutException, NoSuchElementException
10 import time
11 import traceback
12
13
14 driver = webdriver.Chrome()
15 url = "http://39.100.104.214/test_explicity_wait.html"
16
17 # 访问测试网页
18 driver.get(url)
19 try:
20 wait = WebDriverWait(driver, 10, 0.2)
21 wait.until(EC.title_is("你喜欢的水果"))
22 print("网页标题是'你喜欢的水果'")
23 # 等待10秒,直到要找的按钮出现
24 element = WebDriverWait(driver, 10).until(lambda x: x.find_element_by_xpath("//input[@value='Display alert box']"))
25 element.click()
26 # 等待alert框出现
27 alert = wait.until(EC.alert_is_present())
28 # 打印alert框体消息
29 print(alert.text)
30 # 确认警告信息
31 alert.accept()
32 # 获取id属性值为"peach"的页面元素
33 peach = driver.find_element_by_id("peach")
34 # 判断id属性值为"peach"的页面元素是否能被选中
35 peachElement = wait.until(EC.element_to_be_selected(peach))
36 print("下拉列表的选项'桃子'目前处于选中状态")
37 # 判断复选框是否可见并且能被点击
38 wait.until(EC.element_to_be_clickable((By.ID, 'check')))
39 print("复选框可见并且能被点击")
40 except TimeoutException as e:
41 # 捕获TimeoutException异常
42 print(traceback.print_exc())
43 except NoSuchElementException as e:
44 # 捕获NoSuchElementException异常
45 print(traceback.print_exc())
46 except Exception as e:
47 # 捕获其他异常
48 print(traceback.print_exc())
49 driver.quit()

操作 cookies

 1 # 操作浏览器的cookie
2 cookies = driver.get_cookies()
3 for cookie in cookies:
4     print("%s -> %s -> %s -> %s -> %s" % cookie["domain"], cookie["name"], cookie["value"],
5           cookie["expiry"], cookie["path"])
6
7 # 根据Cookie的name值获取该条cookie信息
8 cookie = driver.get_cookie("AB")
9 # 删除
10 print(driver.delete_cookie("AB"))
11 # 删除全部cookie
12 driver.delete_all_cookies()
13
14 # 添加自定义Cookie信息
15 driver.add_cookie({"name":"hippop", "value":"in China"})
16 print(driver.get_cookie("hippop"))

页面加载超时

 1 from selenium.common.exceptions import TimeoutException
2 import traceback
3
4 # 指定页面加载超时时间,当到达等待时间(4秒)则不再继续等待,而是继续执行后续操作
5 driver.set_page_load_timeout(4)
6
7 try:
8     driver.get("http://www.baidu.com")
9 except TimeoutException:
10     # print(traceback.print_exc())
11     print("页面加载超过设定时间")
12     # 通过执行JS来停止加载,然后继续执行后续动作
13     driver.execute_script("window.stop()")
14
15 driver.switch_to.alert()

结束 Windows 的浏览器进程

 1 from selenium import webdriver
2 import os
3 import time
4
5
6 # 分别启动3个浏览器
7 driver1 = webdriver.Chrome()
8 url = "http://www.sogou.com"
9 # 访问baidu首页
10 driver1.get(url)
11
12 driver2 = webdriver.Firefox()
13 url = "http://www.sogou.com"
14 # 访问baidu首页
15 driver2.get(url)
16
17 driver3 = webdriver.Ie()
18 url = "http://www.sogou.com"
19 # 访问baidu首页
20 driver3.get(url)
21
22
23 # 结束Chrome浏览器进程
24 returnCode = os.system("taskkill /F /iM chrome.exe")
25 if returnCode == 0:
26 print ("结束Chrome浏览器进程成功!")
27 else:
28 print ("结束Chrome浏览器进程失败!")
29
30 # 结束Firefox浏览器进程
31 returnCode = os.system("taskkill /F /iM firefox.exe")
32 if returnCode == 0:
33 print ("结束Firefox浏览器进程成功!")
34 else:
35 print ("结束Firefox浏览器进程失败!")
36
37 returnCode = os.system("taskkill /F /iM iexplore.exe")
38 if returnCode == 0:
39 print ("结束IE浏览器进程成功!")
40 else:
41 print ("结束IE浏览器进程失败!")

浏览器相关配置

Chrome 相关配置

 1 from selenium import webdriver
2 import time
3 from selenium.webdriver.chrome.options import Options
4
5
6 # 创建Chrome的一个Options实例对象
7 chrome_options = Options()
8
9 # 禁用PDF和Flash插件
10 # 禁用Image加载
11 profile = {"plugins.plugins_disabled": ['Chrome PDF Viewer'],
12 "plugins.plugins_disabled": ['Adobe Flash Player'],
13 "profile.managed_default_content_settings.images": 2}
14
15 # 自动将文件下载到指定路径。如果目录不存在,将会自动创建
16 profile["download.default_directory"] = "e:\\Download"
17
18 # 加载profile
19 chrome_options.add_experimental_option("prefs", profile)
20
21 # 添加禁用扩展插件的设置参数项
22 chrome_options.add_argument("--disable-extensions")
23 # 添加屏蔽提示信息
24 chrome_options.add_experimental_option("excludeSwitches", ["ignore-certificate-errors"])
25 # 浏览器最大化
26 chrome_options.add_argument("--start-maximized")
27
28
29 # 测试爱奇艺首页的Flash和图片是否被禁止加载
30 if __name__ == "__main__":
31 driver = webdriver.Chrome(chrome_options=chrome_options)
32
33 url = "http://www.iqiyi.com"
34 driver.get(url)
35
36 time.sleep(10)
37 driver.quit()

Firefox 相关配置

1 profile = webdriver.FirefoxProfile()
2 # 禁用CSS
3 profile.set_preference("permissions.default.stylesheet", 2)
4 # 禁用images加载
5 profile.set_preference("permissions.default.image", 2)
6 # 禁用Flash加载
7 profile.set_preference("dom.ipc.plugins.enabled.libflashplayer.so", False)

Selenium 3 常用 API的更多相关文章

  1. Python Selenium 之常用API

    Selenium WebDriver下提供许多用来与浏览器.元素.鼠标.键盘.弹框.下拉菜单和列表的交互和设置方法.这些是计算机模拟人工进行自动化测试所必要依赖的方法.下面将用列表的方式总结出常用的A ...

  2. Selenium WebDriver 常用API

    public class Demo1 { WebDriver driver; @BeforeMethod public void visit(){ //webdriver对象的声明 System.se ...

  3. Selenium Web 自动化 - Selenium常用API

    Selenium Web 自动化 - Selenium常用API 2016-08-01 目录 1 对浏览器操作  1.1 用webdriver打开一个浏览器  1.2 最大化浏览器&关闭浏览器 ...

  4. html5 canvas常用api总结(一)

    1.监听浏览器加载事件. window.addEventListener("load",eventWindowLoaded,false); load事件在html页面加载结束时发生 ...

  5. compass General 常用api学习[Sass和compass学习笔记]

    compass 中一些常用api 包括一些浏览器hack @import "compass/utilities/general" Clearfix Clearfix 是用来清除浮动 ...

  6. java基础3.0:Java常用API

    本篇介绍Java基础中常用API使用,当然只是简单介绍,围绕重要知识点引入,巩固开发知识,深入了解每个API的使用,查看JavaAPI文档是必不可少的. 一.java.lang包下的API Java常 ...

  7. C++ 中超类化和子类化常用API

    在windows平台上,使用C++实现子类化和超类化常用的API并不多,由于这些API函数的详解和使用方法,网上一大把.本文仅作为笔记,简单的记录一下. 子类化:SetWindowLong,GetWi ...

  8. node.js整理 02文件操作-常用API

    NodeJS不仅能做网络编程,而且能够操作文件. 拷贝 小文件拷贝 var fs = require('fs'); function copy(src, dst) { fs.writeFileSync ...

  9. js的常用api

    JavaScript常用API总结 原创 2016-10-02 story JavaScript 下面是我整理的一些JavaScript常用的API清单. 目录 元素查找 class操作 节点操作 属 ...

随机推荐

  1. 基于docker快速搭建hbase集群

    一.概述 HBase是一个分布式的.面向列的开源数据库,该技术来源于 Fay Chang 所撰写的Google论文"Bigtable:一个结构化数据的分布式存储系统".就像Bigt ...

  2. 基于docker创建Cassandra集群

    一.概述 简介 Cassandra是一个开源分布式NoSQL数据库系统. 它最初由Facebook开发,用于储存收件箱等简单格式数据,集GoogleBigTable的数据模型与Amazon Dynam ...

  3. 完全基于node的web应用

    完全基于node的web应用 node js web fs fs文件路径 事实上通常"正确的方式"一般都不简单. 用例 模块 基本http服务器 基于事件驱动回调 模块化serve ...

  4. XXL-JOB v2.3.0 发布 | 易用性增强

    转: XXL-JOB v2.3.0 发布 | 易用性增强 v2.3.0 Release Notes 1.[新增]调度过期策略:调度中心错过调度时间的补偿处理策略,包括:忽略.立即补偿触发一次等: 2. ...

  5. 使用windbg定位内存问题【入门级】

    1. 背景 在开发过程中,我们可能遇到应用程序线程占用过大的问题,可以通过windbg命令去定位哪些类型,哪些内存一直占用堆资源,从而查出问题,解决问题. 2. 准备工作 工具: 抓取DUMP文件的工 ...

  6. MySql数据库列表数据分页查询、全文检索API零代码实现

    数据条件查询和分页 前面文档主要介绍了元数据配置,包括表单定义和表关系管理,以及表单数据的录入,本文主要介绍数据查询和分页在crudapi中的实现. 概要 数据查询API 数据查询主要是指按照输入条件 ...

  7. Vulkan移植GpuImage(一)高斯模糊与自适应阈值

    自适应阈值效果图 demo 这几天抽空看了下GpuImage的filter,移植了高斯模糊与自适应阈值的vulkan compute shader实现,一个是基本的图像处理,一个是组合基础图像处理聚合 ...

  8. 【vscode】【python】自定义代码自动补全

    引自:https://blog.csdn.net/Kyrielong/article/details/88058884 { "python.jediEnabled": true, ...

  9. Prometheus时序数据库-数据的查询

    Prometheus时序数据库-数据的查询 前言 在之前的博客里,笔者详细阐述了Prometheus数据的插入过程.但我们最常见的打交道的是数据的查询.Prometheus提供了强大的Promql来满 ...

  10. 01-静态web服务器(Python)-面向对象的对比

    普通写法,静态web服务器: 先创建TCP服务器套接字,然后等待客户端(这里是浏览器)请求连接. 客户端发起请求,用线程来处理连接的建立,这样可以实现多任务(也就是并发) 连接后根据请求发送指定页面 ...