今天接着讲selenium的常见的一些操作,内容稍微有点多,慢慢细品,写的还算较为清晰,请耐心看完
平时我们做功能测试,都是手动点击鼠标来完成,那么同样可以通过代码来完成;比如,打开百度网站点击左上角的新闻链接,操作鼠标即可
- """
-
- 鼠标操作:ActionChains
-
- 鼠标右击:action.context_click()
- 鼠标双击:action.double_click()
- 鼠标移动到某个节点:move_to_element()
- 鼠标左键按下鼠标:click_and_hold()
- 鼠标相对当前位置进行移动:move_by_offse()
- 在一个位置按下鼠标,到另外一个位置释放:drag_and_drop(ele1,ele2)
-
- release():释放鼠标
- perform():执行动作
-
- """
- import time
- from selenium.webdriver import Chrome
- from selenium.webdriver import ActionChains
- from selenium.webdriver.common.by import By
-
- driver = Chrome()
- driver.implicitly_wait(10)
- driver.get("https://www.baidu.com/")
-
- news_ele = driver.find_element(By.XPATH, '//a[text()="新闻"]')
-
- # 创建一个鼠标对象
- action = ActionChains(driver)
- # click:点击某个元素
- # 点击某个元素;此时点击的百度网站的左上角的新闻链接,实现用鼠标去点
- action.click(news_ele)
- # 执行动作
- action.perform()
-
- time.sleep(2)
- driver.quit()
如果鼠标来悬浮拖拽怎么来实现,看下图
同样通过代码来实现
- import time
- from selenium.webdriver import Chrome
- from selenium.webdriver import ActionChains
- from selenium.webdriver.common.by import By
-
- driver = Chrome()
- driver.implicitly_wait(10)
- driver.get("https://www.cdsy.xyz/try/try.php?filename=jqueryui-api-droppable")
-
- # 因为是iframe标签,所以要进行切换
- frame_ele = driver.find_element(By.ID, "iframeResult")
- driver.switch_to.frame(frame_ele)
- ele1 = driver.find_element(By.ID, "draggable")
- ele2 = driver.find_element(By.ID, "droppable")
-
- # 创建一个鼠标对象
- action = ActionChains(driver)
- # 点击按住鼠标不放;在ele1处按下鼠标
- action.click_and_hold(ele1)
- # 移动鼠标到某个ele2上
- action.move_to_element(ele2)
- # 释放鼠标
- action.release()
-
- # 执行动作
- action.perform()
-
- time.sleep(2)
- driver.quit()
来看运行后的效果:
当然了,这种从一个位置拖动到另一个位置,不用这么麻烦,也可以直接用一个已封装好的方法去实现:drag_and_drop(ele1,ele2),有兴趣的可以自己尝试,道理是一样的
接下来,拓展一个问题,可不可以根据坐标来移动呢?
答:是可以的
- import time
- from selenium.webdriver import Chrome
- from selenium.webdriver import ActionChains
- from selenium.webdriver.common.by import By
-
- driver = Chrome()
- driver.implicitly_wait(10)
- driver.get("https://www.cdsy.xyz/try/try.php?filename=jqueryui-api-droppable")
-
- # 因为是iframe标签,所以要进行切换
- frame_ele = driver.find_element(By.ID, "iframeResult")
- driver.switch_to.frame(frame_ele)
- ele1 = driver.find_element(By.ID, "draggable")
- ele2 = driver.find_element(By.ID, "droppable")
-
- # 创建一个鼠标对象
- action = ActionChains(driver)
- # 按下ele1这个元素
- action.click_and_hold(ele1)
- # 根据坐标来移动
- action.move_by_offset(xoffset=100, yoffset=300)
-
- # 释放鼠标
- action.release()
- # 执行动作
- action.perform()
-
- time.sleep(2)
- driver.quit()
因此:关于selenium的鼠标操作,在此做个小总结:
1、要导入ActionChains这个类,from selenium.webdriver import ActionChains;在这个的基础上再来谈鼠标操作
2、执行动作:perform不能忘,没有这个执行动作是无法点击鼠标实现操作的
3、如果遇到iframe标签,要先切换好
4、相对于位置来移动坐标,最好不要使用,因为每种电脑屏幕的分辨率不太一样,很容易乱的
5、有些方法是已经封装好的,能简单使用就最好不要绕圈子,简单粗暴是最好用的
6、点击元素的时候,别忘了后边的括号里面传元素
7、其实说白了就是一句话;①导入ActionChains②action.方法③执行动作;想用什么方法自己去选择就行
标准的下拉选择框,为什么要这样讲呢,我们所说的标准的下拉选择框其实就是select和option组成的,这种的下拉框怎么来选中下拉列表中的选项呢?
步骤很简单:导入一个Select,然后调用方法来选择,方式一般有常见的这么3种,较为简单
非标准的下拉选择框:在其他的网站上各种组件各种插件组成,对于这种,我们要怎么样来处理呢?
- """
-
- 非标准的下拉框,只能一步一步点击
- """
-
- import time
- from selenium.webdriver.common.by import By
- from selenium.webdriver import Chrome
-
- driver = Chrome()
- driver.implicitly_wait(5)
- driver.get("https://www.layui.com/demo/form.html")
-
- # 第一步:点击选择框
- driver.find_element(By.XPATH, "//input[@placeholder='直接选择或搜索选择']")
- time.sleep(2)
- # 第二步:找到对应的元素进行点击
- driver.find_element(By.XPATH, "//dd[text()='form']").click()
-
- time.sleep(10)
- driver.quit()
一步一步来,先点击出现下拉列表,再从里面选
也许有的同学不太理解,什么叫键盘操作?比如说,键盘的回车键Enter,清除键delete等等
- import time
- from selenium.webdriver.common.keys import Keys
- from selenium.webdriver import Chrome
- from selenium.webdriver.common.by import By
-
- driver = Chrome()
- driver.implicitly_wait(10)
- driver.get("http://www.elong.com/")
-
- # 先定位元素
- input_ele = driver.find_element(By.XPATH, '//input[@data-bindid="city"]')
- # 清空该元素内容
- input_ele.clear()
- # 在输入框输入深圳
- input_ele.send_keys("深圳")
- time.sleep(2)
- # 输入完内容后敲个Enter键
- input_ele.send_keys(Keys.ENTER)
- time.sleep(2)
-
- driver.find_element(By.XPATH, '//span[@data-bindid="search"]').click()
-
- time.sleep(10)
- driver.quit()
如果我此时需要粘贴复制呢?要通过键盘操作ctrl+c或者ctrl+v,怎么来用代码实现
- import time
- from selenium.webdriver.common.keys import Keys
- from selenium.webdriver import Chrome
- from selenium.webdriver.common.by import By
-
- driver = Chrome()
- driver.implicitly_wait(10)
- driver.get("http://www.elong.com/")
-
- input_ele = driver.find_element(By.XPATH, '//input[@data-bindid="city"]')
- # -----组合键输入
- # ctrl+a 全选
- input_ele.send_keys((Keys.CONTROL, 'a'))
- time.sleep(2)
- # ctrl+c 粘贴
- input_ele.send_keys((Keys.CONTROL, 'c'))
- time.sleep(2)
- # ctrl+v 复制
- input_ele.send_keys((Keys.CONTROL, 'v'))
- input_ele.send_keys((Keys.CONTROL, 'v'))
- input_ele.send_keys((Keys.CONTROL, 'v')) # 运行结果的目的地输入框显示三个北京
-
- time.sleep(10)
- driver.quit()
在python代码中,如何执行js代码,比如用12306的购票网站来举例,出发日期的选择框,是可以输入的,我们如何做到直接手动输入日期?有这么几种方式
方式一:直接js代码,不参任何参数,把console的js包起来直接在python中执行
- """
- 通过js代码修改元素属性
-
- """
-
- import time
- from selenium.webdriver import Chrome
- from selenium.webdriver.common.by import By
-
- driver = Chrome()
- driver.implicitly_wait(10)
- driver.get("https://www.12306.cn/index/")
-
- date_input = driver.find_element(By.XPATH, '//input[@id="train_date"]')
- # -----selenium中执行js代码-------
- # 纯粹的js代码,不涉及到参数的传递
- js = """
- ele = document.getElementById('train_date');
- ele.readOnly=false;
- """
- # 执行js代码,将日期的readOnly属性改为false
- driver.execute_script(js)
- time.sleep(2)
- # 把默认的日期清空
- date_input.clear()
- # 输入你要输入的日期
- date_input.send_keys("2021-06-17")
-
- time.sleep(10)
- driver.quit()
方式二:通过arguments用来接收参数
- import time
- from selenium.webdriver import Chrome
- from selenium.webdriver.common.by import By
-
- driver = Chrome()
- driver.implicitly_wait(10)
- driver.get("https://www.12306.cn/index/")
-
- date_input = driver.find_element(By.XPATH, '//input[@id="train_date"]')
- # -----selenium中执行js代码-------
- # 往js代码中传参数,arguments是用来接收我们传进去的参数,他是类似一个列表的一种数据类型们,可以通过下标获取对应的参数值
- js = """
- arguments[0].readOnly=false;
- console.log(arguments[0]);
- console.log(arguments[1]);
- console.log(arguments[2]);
- """
-
- driver.execute_script(js, date_input, 11, 22)
-
- time.sleep(2)
- # 把默认的日期清空
- date_input.clear()
- # 输入你要输入的日期
- date_input.send_keys("2021-06-17")
-
- time.sleep(20)
- driver.quit()
方式三:直接修改value属性,不用再在外面传输入的日期内容
- """
- 通过js代码修改value属性
-
- """
-
- import time
- from selenium.webdriver import Chrome
- from selenium.webdriver.common.by import By
-
- driver = Chrome()
- driver.implicitly_wait(10)
- driver.get("https://www.12306.cn/index/")
-
- date_input = driver.find_element(By.XPATH, '//input[@id="train_date"]')
- # -----selenium中执行js代码-------
- js1 = """arguments[0].readOnly=false;"""
- driver.execute_script(js1, date_input)
- time.sleep(1)
- js2 = """arguments[0].value = '2021-06-18';"""
- driver.execute_script(js2, date_input)
-
- time.sleep(20)
- driver.quit()
因此,我们如果以后想通过js代码来实现手动也是可以的,就拿12306网站来说,无论是出发日期还是出发地目的地都是可以修改,在实际项目中,可灵活根据需求应用
滑动到元素可见,比如网页中一开始看不见底部的信息,需要滚动条往下滑才能看到,这种情况如何处理?
有一个方法:location_once_scrolled_into_view
- import time
- from selenium.webdriver.common.by import By
- from selenium.webdriver import Chrome
-
- driver = Chrome()
- driver.get("https://www.layui.com/demo/form.html")
- driver.implicitly_wait(10)
-
- # 先找到这个元素,再滑动到可见
- ele1 = driver.find_element(By.XPATH, "//button[text()='跳转式提交']")
- # 再滑动到可见
- ele1.location_once_scrolled_into_view
-
- time.sleep(10)
- driver.quit()
当然,也可以直接js滑动页面
1、滑动到元素可见:元素.scrollIntoView(true) 工作中常用
2、相对当前位置滑动窗口 window.scrollBy(x,y)
x:x轴滑动的像素
y:y轴滑动的像素(往下滑为正,往上滑为负)
3、滑动到页面指定位置:window.scrollTo(x,y)
x:x轴滑动的像素
y:y轴滑动的像素(往下滑为正,往上滑为负)
4、滑动到底部:window.scrollTo(0,document.body.scrollHeight)
滑动到顶部:window.scrollTo(0,0)
另外还有一种常见的场景:如何要去下拉选择框中再通过滚动条滑到下边的不可见元素点击,怎么操作?
- import time
- from selenium.webdriver.common.by import By
- from selenium.webdriver import Chrome
- from selenium.webdriver.support.wait import WebDriverWait
- from selenium.webdriver.support import expected_conditions as EC
-
- driver = Chrome()
- driver.get("https://www.layui.com/demo/form.html")
- driver.implicitly_wait(10)
-
- driver.find_element(By.XPATH, '//input[@placeholder="直接选择或搜索选择"]').click()
- location = (By.XPATH, '//dd[@lay-value="20"]')
- ele = driver.find_element(*location)
- ele.location_once_scrolled_into_view
-
- WebDriverWait(driver, 5, 0.5).until(EC.visibility_of_element_located(location)).click()
-
- time.sleep(20)
- driver.quit()
增加显式等待,等它可见后再点击
通过js打开浏览器新的窗口,比如打开了一个网页后,想中途打开其他的网页,怎么在python代码中实现?
- import time
- from selenium.webdriver import Chrome
-
- driver = Chrome()
- driver.get("https://www.layui.com/demo/form.html")
- driver.implicitly_wait(10)
- # 方式一
- js = "window.open('http://www.taobao.com')"
- driver.execute_script(js)
- # 方式二
- js2 = "window.open(arguments[0])"
- driver.execute_script(js2, 'http://www.baidu.com')
-
- time.sleep(10)
- driver.quit()
所以,我们可以将其封装成一个方法,后续可以直接调用
- def open_window(driver: WebDriver, url):
- """
- 打开新的窗口,并切换
- :param url:
- :return:
- """
- windows = driver.window_handles
- js2 = "window.open(arguments[0])"
- driver.execute_script(js2, 'http://www.baidu.com')
- # 等待新窗口的出现
- WebDriverWait(driver, 3, 0.5).until(EC.number_of_windows_to_be(windows))
- # 切换到打开的新窗口
- driver.switch_to.window(driver.window_handles[-1])
把图片或者文件夹进行上传操作,又怎么来实现?
- import time
-
- from selenium.webdriver import Chrome
- from selenium.webdriver.common.by import By
- from pywinauto.keyboard import send_keys
-
- driver = Chrome()
- driver.implicitly_wait(10)
- driver.get("https://www.layui.com/demo/upload.html")
- # pywinauto这个模式只能在windows环境中使用
- # 点击上传图片的按钮
- driver.find_element_by_id("test1").click()
- # 输入文件的路径
- time.sleep(2)
- send_keys(r"C:\Users\xiaojiang\Desktop\baidu.png")
- send_keys("{VK_RETURN}")
-
- time.sleep(5)
- driver.quit()
首先得安装pywinauto,有可能你会在安装过程中遇到报错,怎么来顺利安装呢?
跟着报错提示的命令,依照输入即可安装成功
那么如果我要上传多个文件怎么办?只需要修改一行代码就行
- import time
-
- from selenium.webdriver import Chrome
- from pywinauto.keyboard import send_keys
-
- driver = Chrome()
- driver.implicitly_wait(10)
- driver.get("https://www.layui.com/demo/upload.html")
- # pywinauto这个模式只能在windows环境中使用
- # 点击上传图片的按钮
- driver.find_element_by_id("test2").click()
- # 输入文件的路径
- time.sleep(2)
- send_keys(r'"C:\Users\xiaojiang\Desktop\baidu.png" "C:\Users\xiaojiang\Desktop\taobao.png"')
- send_keys("{VK_RETURN}")
-
- time.sleep(5)
- driver.quit()
拓展:这些pywinauto都是在windows电脑上环境使用,如果是mac电脑怎么办呢?
教大家一招:pyautogui
pyautogui----->优点:兼容window linux mac系统;
缺点:上传文件的路径中不能出现中文,且只能上传一个文件
所以,根据个人工作中的实际情况来使用
==================================================================================================