selenium的高级操作

今天接着讲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:\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系统;
        缺点:上传文件的路径中不能出现中文,且只能上传一个文件

所以,根据个人工作中的实际情况来使用

==================================================================================================

 

posted @ 2021-06-13 16:28  excellent_1  阅读(236)  评论(0编辑  收藏  举报