今天接着讲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.runoob.com/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.runoob.com/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()
四、JS脚本操作
在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:UsersxiaojiangDesktopaidu.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:UsersxiaojiangDesktopaidu.png" "C:UsersxiaojiangDesktop aobao.png"') send_keys("{VK_RETURN}") time.sleep(5) driver.quit()
拓展:这些pywinauto都是在windows电脑上环境使用,如果是mac电脑怎么办呢?
教大家一招:pyautogui
pyautogui----->优点:兼容window linux mac系统;
缺点:上传文件的路径中不能出现中文,且只能上传一个文件
所以,根据个人工作中的实际情况来使用
==================================================================================================