Selenium 3 常用 API
元素定位
获取页面元素属性
元素判断
元素操作
断言
截屏
隐式等待
显式等待
操作 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,否则返回F alse。
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)