Selenium常用函数介绍
目录
一,元素定位
1.1 cssSeector
1.2 xpath
二,操作测试对象
三,窗口
3.1 案例
3.2 窗口切换
3.3 窗口大小
3.4 屏幕截图
3.5 关闭窗口
四,弹窗
五,等待
六,导航
七,文件上传
八,浏览器参数
一,元素定位
我们常用选择器有两个,cssSelector 和 xpath
1.1 cssSeector
编写该文章时的百度首页如下:
假设我想使用程序获取热搜部分选项中的文字内容,可以先按F12找到对应选项的selector:
如下代码:
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from webdriver_manager.chrome import ChromeDriverManager
import timeChromIns=ChromeDriverManager().install() #安装驱动,是给这个程序装一个
driver=webdriver.Chrome(service=Service(ChromIns)) #创建谷歌浏览器驱动对象,之后就可以通过这个对象来驱动浏览器
driver.get("https://www.baidu.com") #输入百度网址,要输入完整URL
ret=driver.find_elements(By.CSS_SELECTOR,"#hotsearch-content-wrapper > li:nth-child(1) > a > span.title-content-title")
for i in ret:print(i.text)
driver.quit() #关闭浏览器
cssSelector选择器功能是选中页面中指定的标签的元素,我们以前讲过css的选择器,分为基础选择器和复合选择器:前端学习(2)—— CSS详解与使用_前端css-CSDN博客
1.2 xpath
XML路径语言,可以在XML文件中查找信息,还可以在html中选取节点;xpath使用路径表达式来选择XML文档中的节点
我们也像上面一样复制元素,至是方式选择Xpath:
复制粘贴后就是://*[@id="hotsearch-content-wrapper"]/li[1]/a/span[2] 下面我们来解释下xpath的语法:
- //*:表示获取HTML页面所有的节点
- //[指定节点]:比如 //ul 表示获取HTML页面中所有的ul节点
- /:表示获取一个节点中的直接子节点,比如 //span/input ,表示获取span标签中的input标签,和选择器功能类似
- ..:这个是两个点,表示获取一个节点的父节点
- [@...]:表示实现节点属性的匹配,比如 //*[@id='kw'],表示匹配HTML页面中id属性为kw的节点
然后我们回到我们前面复制的内容,首先是//*,先获取到页面所有节点,然后就是找到对应id属性的内容,百度首页的部分源代码如下,可以看到对应id属性的标签:
然后就是 /li[1],我们把上面内容合并后是这样的:
可以看到有很多li标签,我们找到第一个li标签,然后找到里面的a标签:
然后a标签里面有两个span,我们找到第二个span,这就是我们xpath路径语言找寻目标的语法
虽然我们能手动复制,但我们需要了解xpath的语法,因为后面我们可能需要手动进行修改或编写选择器元素
二,操作测试对象
部分操作测试对象我们前面已经介绍过了
①点击事件
driver.find_element(By.CSS_SELECTOR, "#su").click()
②模拟按键输入
driver.find_element(By.CSS_SELECTOR, "#kw").send_keys("你好")
③清楚文本内容
driver.find_element(By.CSS_SELECTOR, "#kw").clear() #如果不清除连续的sendkeys,是直接拼接在后面的
④获取文本信息
使用CSS选择器和使用xpath获取文本信息我们标题一已经介绍过了这里不再赘述
下面我们尝试获取下百度以西按钮里的“百度一下”这四个字,看看效果:
可以看到打印结果为空,这是因为这是一种特殊情况:元素属性不等于文本信息(span标签中间的内容),我们看下网页源代码:
可以看到“百度一下”这四个字是放在input标签的value属性后面的,是数学值,所以我们需要用获取属性的那个方法 getAttribute("属性名称"),如下代码:
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from webdriver_manager.chrome import ChromeDriverManager
import timeChromIns=ChromeDriverManager().install() #安装驱动,是给这个程序装一个
driver=webdriver.Chrome(service=Service(ChromIns)) #创建谷歌浏览器驱动对象,之后就可以通过这个对象来驱动浏览器
driver.get("https://www.baidu.com") #输入百度网址,要输入完整URL
ret=driver.find_element(By.CSS_SELECTOR,"#su").get_attribute("value")
print(ret)
driver.quit() #关闭浏览器
⑤获取页面标题的url
三,窗口
注意:这个窗口不是弹窗哦
3.1 案例
我们先看一个案例:假设我要打开百度首页的图片:
浏览器会单独打开一个窗口,然后我们获取一下两个窗口的url和标题,如下代码:
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from webdriver_manager.chrome import ChromeDriverManager
import timeChromIns=ChromeDriverManager().install() #安装驱动,是给这个程序装一个
driver=webdriver.Chrome(service=Service(ChromIns)) #创建谷歌浏览器驱动对象,之后就可以通过这个对象来驱动浏览器
driver.get("https://www.baidu.com") #输入百度网址,要输入完整URL
print(driver.title)
print(driver.current_url)
driver.find_element(By.CSS_SELECTOR,"#s-top-left > a:nth-child(6)").click()
print(driver.title)
print(driver.current_url)
driver.quit() #关闭浏览器
可以看到程序执行后可以跳转,但是我们两次获取的网页标题和url是一样的,都是百度首页的url,不受百度图片的url,这是因为我们虽然让浏览器打开了一个新的页面,但是程序本身的操作对象还是百度首页而不是百度图片,所以我们需要让程序识别到不同的窗口
3.2 窗口切换
如何让程序识别每一个窗口呢?每个浏览器的每个窗口都有唯一的一个“属性句柄”来表示, 所以我们可以通过句柄来切换,如下代码:
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from webdriver_manager.chrome import ChromeDriverManager
import timeChromIns=ChromeDriverManager().install()
driver=webdriver.Chrome(service=Service(ChromIns))
driver.get("https://www.baidu.com")
print(driver.title)
print(driver.current_url)
driver.find_element(By.CSS_SELECTOR,"#s-top-left > a:nth-child(6)").click() #获取并点击百度图片
curHandle = driver.current_window_handle #获取当前页面句柄
allHandles = driver.window_handles #获取所有句柄
for handle in allHandles: #遍历所有句柄,第一次循环handle是百度首页,不做处理,第二次handle就是百度图片了,执行切换操作if handle != curHandle:driver.switch_to.window(handle) #切换到当前的handle
print(driver.title)
print(driver.current_url)
driver.quit() #关闭浏览器
注意:
- 测试中很少有在存在多个标签页,然后切换到一个标签页的场景,通常情况下一般会打开两个标签页进行切换测试,更多的则是直接输入URL进行测试
- 如果没有打开新的窗口,而是直接在当前窗口进行了切换,那么不需要进行窗口切换
3.3 窗口大小
这个了解即可,因为在自动化脚本执行过程中一般不关注窗口大小变化,如下代码:
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from webdriver_manager.chrome import ChromeDriverManagerChromeIns = ChromeDriverManager().install() #安装驱动
driver = webdriver.Chrome(service = Service(ChromeIns)) #创建谷歌浏览器对象
driver.get("https://www.baidu.com") #输入网址
driver.maximize_window() #窗⼝最⼩化
driver.minimize_window() #全屏窗⼝
driver.fullscreen_window() #窗口全屏
driver.set_window_size(500, 500)
driver.quit() #关闭浏览器
3.4 屏幕截图
当自动化运行报错时,仅通过终端的错误提示给到的有用信息是有限的,如果有了屏幕截图,能更好的定位问题并解决问题,截图的语句如下:
driver.save_screenshot('./baidu.png') #括号里面的是路径
由于图片给定的名称是固定的,当我们多次运行自动化脚本时,历史图片将被覆盖,所以不能将图片名称给死,我们要想办法让历史的图片文件都是唯一的,可以采用时间戳的办法:
from datetime import datetime
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from webdriver_manager.chrome import ChromeDriverManager
import timeChromIns=ChromeDriverManager().install()
driver=webdriver.Chrome(service=Service(ChromIns))
driver.get("https://www.baidu.com")
filename = "autotest-" + datetime.now().strftime('%Y-%m-%d-%H%M%S') + '.png'
driver.save_screenshot('./' + filename)
driver.quit() #关闭浏览器
3.5 关闭窗口
和quit不同的是,我们是要关闭一个窗口,而不是关闭浏览器,如下代码:
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from webdriver_manager.chrome import ChromeDriverManager
import timeChromIns=ChromeDriverManager().install()
driver=webdriver.Chrome(service=Service(ChromIns))
driver.get("https://www.baidu.com") #打开百度首页
driver.find_element(By.CSS_SELECTOR, "#s-top-left > a:nth-child(6)").click() #打开百度图片
driver.close() #关闭百度首页
time.sleep(3) #三秒后关闭浏览器
driver.quit() #关闭浏览器
四,弹窗
有三种:警告弹窗,确认弹窗,提升弹窗
我们无法在弹窗上找到弹窗的任何元素,所以通过程序点击弹窗出发按钮后,无法再通过程序找到弹窗的元素进而关闭弹唱,必须先处理弹窗后才能定位到页面的元素,所以我们的步骤就是:1,切换到弹窗 2,关闭弹窗(点击确定/取消)
下面是一个简单的html页面,里面有一个按钮,按下可以弹出弹窗:
<div><button onclick="Hello()">打开弹窗</button>
</div>
<script>function Hello(){alert("你好,祝您生活愉快");}
</script>
from datetime import datetime
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from webdriver_manager.chrome import ChromeDriverManager
import timeChromIns = ChromeDriverManager().install()
driver = webdriver.Chrome(service=Service(ChromIns))
driver.get("C:/Users/PC/PycharmProjects/hello/hello.html")
driver.find_element(By.CSS_SELECTOR, "body > div > button").click()
time.sleep(3)
alert = driver.switch_to.alert #获取窗口
alert.accept() #确认
#alert.dismiss() #确认弹窗就是确认和取消任选其一,但是警告窗口只有一个确认所以两个都可以
driver.quit()
注,python代码识别Windows的文件路径分隔符“ \ ”时可能会报错,所以复制 hello.html 路径后需要把路径分隔符换成“ / ”
然后对于提示弹窗需要我们输入信息,所以我们需要额外处理:
下面是提示痰喘,需要用到prompt方法:
<div><button onclick="Hello()">打开弹窗</button>
</div>
<script>function Hello(){prompt("你好,今天天气不错!");
}
</script>
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from webdriver_manager.chrome import ChromeDriverManager
import timeChromIns = ChromeDriverManager().install()
driver = webdriver.Chrome(service=Service(ChromIns))
driver.get("C:/Users/PC/PycharmProjects/hello/hello.html")
driver.find_element(By.CSS_SELECTOR, "body > div > button").click()
alert = driver.switch_to.alert #切换到弹窗
alert.send_keys("是的呢") #输入到弹窗中
alert.accept() #确认
注意:我们用程序在弹窗上输入信息是不显示的,但是后面我们如果去获取打印时也能打印,说明是输入成功了的
五,等待
①为什么要等待
有时候一个页面可能会有很多图片,比如一些购物网站,而图片一多,页面的加载时间就会变长
而通常,我们代码的执行速度是比页面渲染的时间要快的,所以可能会出现渲染过慢导致自动化程序出现报错,所以我们可以使用selenium的三种等待方法
②强制等待
就是我们前面使用的 time.sleep() ,程序会强制阻塞,等待指定秒数后才继续执行后面的代码,缺点很明显,非常影响运行效率,主要是在调试里使用,正式测试慎用
③隐式等待
是一种智能等待,规定在在查找元素时,在指定时间内循环查找,如果找到代码则继续运行,直到超时还没找到元素才会报错,语法如下:
driver.implicitly_wait(3)
隐等待的作用域是整个脚本的所有元素,就是只要driver对象没有被释放掉,隐式等待就会一直生效,这个生效是针对该driver的每个线性的操作,所以一般定义在程序代码开头
④显示等待
也是一种智能等待,和隐式等待不同,显示等待只作用域单独一行代码,并且实现也比较复杂,表达式如下:
WebDriverWait(driver, sec).until(functions)
driver表示要等待的对象,sec表示要等待的秒数,function表示需要满足的条件,只有在规定时间内满足条件,才会继续执行后续代码,超时则直接报错
function方法有很多,这里只介绍查找元素的方法:
wait = WebDriverWait(driver, 2).until(EC.invisibility_of_element((By.CSS_SELECTOR, "要查找的元素")))
这句代码表示先创建一个显示等待的类,然后调用这个类的until方法,参数也是一个表达式,有很多,上面只是其中一种
显示等待可以处理隐式等待无法处理的问题,比如弹窗alert_is_present(),这个方法就是检查是否出现弹窗
但是注意,显示和隐式不建议一起用,可能会导致不可预测的等待时间
六,导航
主要是四种行为:打开、前进、后退、刷新,打开网页我们就是driver,get(url),下面我们简单概括下后面三个:
driver.find_element(By.CSS_SELECTOR, "kw").send_keys("你好")
driver.back() #后退
driver.forward() #前进
driver.refresh() #刷新页面
七,文件上传
当页面元素发起上传的窗口后,文件窗口同样无法作为页面元素选中,那么该如何定位到窗口并选中文件呢?
其实我们直接使用sedkeys即可,之后后面不再带文字,而是路径信息:
driver.get("本地html文件路径") 来唤起浏览器打开这个html
driver.find_element(By.CSSSELECTOR, "").sendkeys("文件路径+名称")
八,浏览器参数
①设置页面无头模式
程序在后端运行,但是不显示浏览器的页面的表现叫做无头模式,我们前面的都是有头模式,如下代码:
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManagerChromeIns = ChromeDriverManager().install() #安装驱动
options = webdriver.ChromeOptions() #获取驱动参数
options.add_argument('--headless') #添加浏览器参数配置,--headless表示无头模式
driver = webdriver.Chrome(service = Service(ChromeIns), options=options) #创建谷歌浏览器对象
driver.get("https://www.baidu.com") #输入网址
print(driver.title)
②设置页面加载策略
一个页面可能有非常多的资源,文字图片甚至视频,假设我们让自动化程序开始运行,但由于页面还没有加载完,所以我们得等待页面完全加载完再点击测试,这样比较耗时间
driver.get() 方法默认是等所有资源全部加载完毕才继续往下执行,但是实际上,只要页面的部分内容加载完后就已经可以执行自动化了,若因为网络或者其它原有导致加载时间过长,就会导致等待超时、找不到元素等问题
设置加载策略代码如下:
options.page_load_strategy = 'eager' #eager表示DOM访问已经准备就绪但诸如图像的其他资源可能仍在加载,normal是等待所有资源就绪,none是完全不会阻塞WebDriver