三大等待
-
强制等待 time.sleep(5)
-
隐式等待 driver.implicitly_wait(20)
-
显性等待
- 明确等到某个条件满足之后,再去执行下一步操作。程序每隔xx秒看一眼,如果条件成立了,则执行下一步,否则继续等待,直到超过设置得最长时间,然后抛出TimeoutException
- webDriverWait类:显性等待类
- from selenium.webdriver.support.wait import WebDriverWait
- WebDriverWait(driver,等待时长,轮询周期=0.5).until()/until_not()
- WebDriverWait(driver, 10).until(expected_conditions.visibility_of_element_located((By.ID, “TANGRAM__PSP_11__footerULoginBtn”)))
- expected_conditions模块:提供了一系列期望发生的条件
- from selenium.webdriver.support import expected_conditions
- presence_of_element_located:元素存在
- visibility_of_element_located:元素可见
- element_to_be_clickable:元素可点击
- ……
- expected_conditions.visibility_of_element_located((By.ID, “TANGRAM__PSP_11__footerULoginBtn”))
- 当操作引起页面的变化,并且要操作变化的元素的时候,就一定要加等待
三大切换(iframe,window,alert)
- window
- 获取当前窗口
- driver.current_window_handle
- 获取所有窗口
- driver.window_handles
- 窗口切换
- handles = driver.window_handles
- driver.switch_to.window(handles[-1])
- 等待新窗口出现
- 点击链接前获取窗口数:handles = driver.window_handles
- WebDriverWait(driver, 20).until(expected_conditions.new_window_is_opened(handles))
- 这样可用确保窗口被打开
- 获取当前窗口
- iframe
- 识别
- 切换
- 找到iframe
- 切换到新iframe(三种方法)
- driver.switch_to.frame(‘frame_name’)
- driver.switch_to.frame(1)
- driver.switch_to.frame(driver.find_elements_by_tag_name(“iframe”)[0])
- 退出iframe
- driver.switch_to.parent_frame()
- driver.switch_to.default_content():一步到位,直接回到main页面
- 切换后最好强制等待1-3s
- driver.refresh()有时也可以使用
- 不用强制等待的操作:expected_conditions.frame_to_be_available_and_switch_to_it
- loc_frame = (By.NAME, “login_frame_qq”)
- WebDriverWait(driver,20).until(expected_conditions.frame_to_be_available_and_switch_to_it(loc_frame))
- 如何切换到父级iframe/default_content不用强制等待呢?
- 识别
- Alert类:from selenium.webdriver.common.alert import Alert
- 三种弹框
- 详细请参考cnblogs
- https://www.cnblogs.com/xyao1/p/7451518.html
- alert()–警告消息框
- confirm()–确认消息框
- prompt()–提示消息框
- 详细请参考cnblogs
- Alert类(出现时无法定位元素)
- Alert.accept(driver.switch_to.alert)
- Alert.dismiss(driver.switch_to.alert)
- Alert.send_keys(driver.switch_to.alert, “输点什么呢?”)
- driver.switch_to.alert.text 获取弹框的文本内容
- 不用强制等待的操作
- WebDriverWait(driver, 10).until(expected_conditions.alert_is_present())
- 这个有返回值,返回值为Alert对象
- a = WebDriverWait(driver, 10).until(expected_conditions.alert_is_present())
- a.text
- a.accept()
- a.dismiss()
- a.send_keys(“输点什么呢?”)
- 三种弹框
鼠标和键盘
-
鼠标操作
-
from selenium.webdriver import ActionChains
-
ActionChains类:
-
def __init__(self, driver): """ Creates a new ActionChains. :Args: - driver: The WebDriver instance which performs user actions. """ self._driver = driver self._actions = [] if self._driver.w3c: self.w3c_actions = ActionBuilder(driver)
-
主要操作流程
- 1、存储鼠标操作
- 2、perform()来执行鼠标操作
-
支持的操作
- 双击操作ActionChains.double_click()
- 右键操作ActionChains.context_click()
- 拖拽操作ActionChains.drag_and_drop()
- 鼠标悬停ActionChains.move_to_element()
- 暂停ActionChains.pause()
- perform()
- 示例:
- from selenium.webdriver.common.action_chains import ActionChains
- ActionChains.方法名1().方法名2().perform()
- 案例
- mouse = driver.find_element_by_id(“s-usersetting-top”)
- ActionChains(driver).move_to_element(mouse).pause(0.5).perform()
-
-
-
键盘
-
from selenium.webdriver.common.keys import Keys
-
常用键盘操作
-
删除键(BackSpace) send_keys(Keys.BACK_SPACE) centered空格键(Space)** send_keys(Keys.SPACE) 制表键(Tab) send_keys(Keys.TAB) 回退键(Esc) send_keys(Keys.ESCAPE) 回车键(Enter) send_keys(Keys.ENTER) 全选(Ctrl+A) send_keys(Keys.CONTROL,‘a’) 复制(Ctrl+C) send_keys(Keys.CONTROL,‘c’) 剪切(Ctrl+X) send_keys(Keys.CONTROL,‘x’) 粘贴(Ctrl+V) send_keys(Keys.CONTROL,‘v’) 键盘 F1 send_keys(Keys.F1) 键盘 F12 send_keys(Keys.F12)
-
-
案例
-
import time from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.common.keys import Keys driver = webdriver.Chrome() driver.maximize_window() driver.get("http://www.baidu.com") driver.find_element(By.ID, "kw").send_keys("百度一下,也不知道!") time.sleep(1) driver.find_element(By.ID, "kw").send_keys(Keys.BACK_SPACE) time.sleep(1) driver.find_element(By.ID, "kw").send_keys(Keys.CONTROL, 'a') time.sleep(1) driver.find_element(By.ID, "kw").send_keys(Keys.CONTROL, 'c') time.sleep(1) driver.find_element(By.ID, "kw").send_keys(Keys.CONTROL, 'x') time.sleep(1) driver.find_element(By.ID, "kw").send_keys(Keys.CONTROL, 'v') time.sleep(1) driver.find_element(By.ID, "kw").send_keys(Keys.ENTER) time.sleep(1) driver.quit()
-
-
下拉列表
-
定位鼠标悬浮才出现的元素。ctrl+shift+c小技巧
-
下拉列表包括
- 非 select 元素
- 通过文本值定位元素,建议直接进行点击操作
- 下拉列表未显示属性值为:display:none
- 下拉列表显示属性值为:display: block
- select 元素
- from selenium.webdriver.support.ui import Select
- 选择下拉列表值的方法:
- 通过下标选择:select_by_index(index) 从0开始;
- 通过value属性:select_by_value(value值)
- 通过文本内容:select_by_visible_text(文本内容)
- 其他方法
- deselect_by_value(self, value)
- deselect_by_index(self, value)
- deselect_by_visible_text(self, text)
- deselect_all(self):
- all_selected_options(self)
- 非 select 元素
-
案例
-
import time from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import Select driver = webdriver.Chrome() driver.maximize_window() driver.get("file:///C:/Users/86186/WebstormProjects/practice/index.html") ele = driver.find_element(By.NAME,"course") s = Select(ele) s.select_by_value("selenium") time.sleep(2) s.select_by_index(0) time.sleep(2) s.select_by_visible_text("自动化") time.sleep(5) driver.quit()
-
js+dom应用()
-
滚动条操作
- 当操作的元素在页面可视区域之外
- 步骤
- 先找到元素
- 再将元素拖到到可见区域
- 移动到元素element对象的”底端“与当前窗口的”底部“对齐:
- document.getElementById(“4”).scrollIntoView(false)
- ele = driver.find_element(By.ID, “7”)
- driver.execute_script(“arguments[0].scrollIntoView(false);”, ele)
- 移动到元素element对象的”顶端“与当前窗口的”顶部“对齐:
- document.getElementById(“4”).scrollIntoView()
- ele = driver.find_element(By.ID, “7”)
- driver.execute_script(“arguments[0].scrollIntoView();”, ele)
- 移动到页面底部:
- window.scrollTo(0,document.body.scrollHeight)
- driver.execute_script(“window.scrollTo(0,document.body.scrollHeight)”)
- 移动到页面顶部:
- window.scrollTo(document.body.scrollHeight,0)
- driver.execute_script(“window.scrollTo(document.body.scrollHeight,0)”)
- 移动到元素element对象的”底端“与当前窗口的”底部“对齐:
- 再操作元素
-
日期操作
-
loc1 = (By.ID, "train_date") wait.until(expected_conditions.visibility_of_element_located(loc1)) driver.execute_script("arguments[0].readOnly=false", driver.find_element(*loc1)) driver.execute_script("arguments[0].value='2020-05-20'", driver.find_element(*loc1))
-
new_date = (datetime.datetime.now() + datetime.timedelta(days=10)).strftime("%Y-%m-%d") js_pha = """ var a = document.getElementById("train_date") a.readOnly = false a.value = "{}" """.format(new_date) driver.execute_script(js_pha)
-
-
选择城市12306(元素之间的关联性)
-
正常选择
-
driver.find_element_by_id("fromStationText").send_keys(Keys.CONTROL, 'a', "北京") loc = (By.XPATH, "//div[@id='panel_cities']//span[text()='北京']") wait.until(expected_conditions.visibility_of_element_located(loc)) driver.find_element(*loc).click() driver.find_element_by_id("toStationText").send_keys(Keys.CONTROL, 'a', "成都") loc = (By.XPATH, "//div[@id='panel_cities']//span[text()='成都']") wait.until(expected_conditions.visibility_of_element_located(loc)) driver.find_element(*loc).click() driver.find_element_by_id("search_one").click()
-
-
通过js选择(这里的地点输入框的值改变后,其兄弟标签的value值改变了)
-
js_location = """ var a = document.getElementById("fromStationText") a.value = "北京" var b = document.getElementById("fromStation") b.value = "BJP" var c = document.getElementById("toStationText") c.value = "成都" var d = document.getElementById("toStation") d.value = "CDW" """ driver.execute_script(js_location) driver.find_element_by_id("search_one").click()
-
-
上传操作
-
如果是input可以直接输入路径的,那么直接调send_keys输入路径
-
非input标签的上传,则需要借助第三方工具
-
AutoIt
-
SendKeys第三方库(目前只支持到2.7版本)
- SendKeys 是 Visual Basic 中的一个编程语句,可将一个或多个按键消息发送到活动窗口,如同用键盘进行输入一样。发送某些特殊字符时须用一对大括号(“{}”)围起来,某些特殊按键要使用专用代码,也可设置为各类组合键
-
Python pywin32库,识别对话框句柄,进而操作
- Pywin32提供了很多访问windows的API。较重要的三个模块就是win32api、win32gui和win32con
- pip install pywin32
-
pyautoit库
- pip install pyautoit
-
工具
- pywin32
- spy++
- Spy++ (SPYXX.EXE) 是一个基于 Win32 的实用工具,它提供系统的进程、线程、窗口和窗口消息的图形视图。使用 Spy++ 可以执行下列操作: 显示系统对象(包括进程、线程和窗口)之间关系的图形树。 搜索指定的窗口、线程、进程或消息。 查看选定的窗口、线程、进程或消息的属性
-
upload(火狐的窗口名和其他不一样)
-
import win32gui import win32con def upload(filepath, browser_type="chrome"): if browser_type == "firefox": title = "文件上传" else: title = "打开" # 一级窗口 dialog = win32gui.FindWindow("#32770", title) # 二级 comboBoxEx32 = win32gui.FindWindowEx(dialog, 0, "ComboBoxEx32", None) # 三级 comboBox = win32gui.FindWindowEx(comboBoxEx32, 0, "ComboBox", None) # 四级 edit = win32gui.FindWindowEx(comboBox, 0, "Edit", None) # 二级(打开按钮) button = win32gui.FindWindowEx(dialog, 0, "Button", "打开(&O)") # 往编辑窗口输入文件路径 win32gui.SendMessage(edit, win32con.WM_SETTEXT, None, filepath) win32gui.SendMessage(dialog, win32con.WM_COMMAND, 1, button) upload("C:\\Users\\86186\\Desktop\\1.jpg")
-
-
-
PyUserInput
- pip install PyUserInput(直接安装会有问题)
- pymouse
- pykeyboard
- 需要对应版本的pyHook
- pyHook下载地址
- https://www.lfd.uci.edu/~gohlke/pythonlibs/
- 下载后pip install pyHook-1.5.1-cp37-cp37m-win_amd64.whl(对应版本)
- pyHook下载地址
- pip install PyUserInput
- 需要对应版本的pyHook
- pip install PyUserInput(直接安装会有问题)