Selenium 基础
一、 环境搭建
1.1 基于Python环境搭建
- Python 开发环境
- 安装Selenium包
- 安装浏览器
- 安装对应版本浏览器驱动
1.2 安装Selenium包
- 前置条件:Python环境已成功安装并运行
1.2.1 pip工具
Python包管理工具,对Python提供包的查找、下载、安装、卸载等功能
- 安装
pip install selenium 默认命令安装selenium最新版本指定版本安裝 - 卸载
pip install selenium==3.141.0
pip uninstall selenium - 查询 pip list
1.2.2 源码安装
若pip不能安装selenium,可通过源码包安装
- 下载后解压,cmd环境进入到setup.py文件所在目录
- 运行 python setup.py install命令进行安装
- 安装完后用pip show selenium 可看到selenium的信息
1.2.3 Pycharm安装
1.3 安装浏览器驱动
1.3.1 谷歌浏览器
- Selenium3.x + Chrome驱动 (chromedriver)
- 驱动下载地址: http://npm.taobao.org/mirrors/chromedriver/
- 地址栏输入: chrome://version/ 查询chrome版本
配置Chromedriver的环境变量
windows:
直接对应的driver放在python根目录下
Mac:
vim ~/.bash_profile 修改环境变量的配置
export PATH=$PATH:[chromedriver所在路径]
1.3.2 Firefox浏览器
- Firefox 48 以上版本
- selenium 3.x + Firefox驱动(geckodriver)
- 驱动版本匹配地址https://firefox-source-docs.mozilla.org/testing/geckodriver/Support.html
- 驱动下载地址: https://github.com/mozilla/geckodriver/releases
二、Selenium介绍
2.1 概念
- Selenium是一个Web应用程序测试工具,化学元素 硒
2.2 原理
三、浏览器的实例管理
3.1 通过程序驱动浏览器
项目创建
- 项目名称不要与第三方的模块名同名
- 文件名称也不要与第三方的模块名或者是类名同名
- 项目创建时不要使用虚拟环境
代码实例:
from selenium import webdriver
# 创建浏览器驱动对象
Firefox浏览器: driver = webdriver.Firefox()
Chrome浏览器: driver = webdriver.Chrome()
3.2 四个导航
- get()
- back O
- forward()
- refresh()
3.3 三个页面属性
- title
- current_url
- page_source
3.4 两个关闭方法
- close: 关闭当前操作的窗口(并非关闭超链接新打开的窗口)
- quit: 关闭client与远端浏览器的会话–关闭该浏览器启动的所有窗口
3.5 一组管理窗口的方法
- maximize_window
- get_window_size
- set_window_size
3.6 截图方法
为什么窗口截图:
自动化脚本程序执行,单纯看打印信息不是很准确,如果出粗对窗口截图,图片是可以很直观的看到错误
get_screenshot_as_file(imgpath)
截图动态获取
driver.get_screenshot_as_file('\{\}.png'.format(time.strftime('%Y%m%d-%H%M%S')))
四、Selenium 元素定位
4.1 浏览器开发者工具
浏览器开发者工具就是给专业的web应用和网站开发人员使用的工具。 包含了对HTML查看和编辑 Javascript控制台 网络状况监视等功能,是开发JavaScript CSS HTML和Ajax的得力助手。
作用:快速定位元素,查看元素信息
- 快捷键: 一般在windows系统上打开浏览器开发者工具 - 按F12
- 火狐浏览器:在页面上点击右键选择‘查看元素’
- 谷歌浏览器: 在页面上点击右键选择‘检查’ 如何进行元素定位
元素定位:通过元素的信息或元素层级结构来定位元素的
- 元素的信息: 指元素的标签名以及元素的属性 id class name
- 元素的层级结构: 指元素之间相互嵌套的层级结构
4.2 Selenium八种定位元素方法
- Selenium提供了八种定位元素方式
4.2.1 ID定位
id定位:通过元素的id属性来定位元素,HTML规定id属性在整个HTML文档中必须是唯一的
需求:驱动谷歌浏览器 打开搜狗浏览器 搜索框输入‘python’
- id定位方法
find_element_by_id(id)# id参数表示的是id的属性值
案例实现
# 导包from selenium import webdriver
# 实例化浏览器
driver =webdriver.Chrome()# 打开搜狗浏览器
driver.get('https://sogou.com')# 定位搜索框, 输入拉勾教育
driver.find_element_by_id('query').send_keys('python')
4.2.2 name定位
name定位:通过name属性进行定位,name属性可以重复
- 定位方法
find_element_by_name(name)# name 参数表示的是name的属性值
案例实现
# 导包from selenium import webdriver
# 实例化浏览器
driver = webdriver.Chrome()# 打开搜狗浏览器
driver.get('https://sogou.com')# 定位搜索框, 输入python# driver.find_element_by_id('query').send_keys('python')# 使用name属性定位
driver.find_element_by_name('query').send_keys('python')
4.2.3 classname定位
通过元素的class属性值进行元素定位 class属性值是可重复的
- 定位方法
find_element_by_class_name(class_name)# class_name参数表示的是class的其中一个属性值
案例实现
# 导包from selenium import webdriver
# 实例化浏览器
driver =webdriver.chrome()# 打开搜狗浏览器
driver.get('https://sogou.com')# 定位搜索框, 输入拉勾教育# driver.find_element_by_id('query').send_keys('python')# 使用name属性定位# driver.find_element_by_name('query').send_keys('python')
4.2.4 tag_name定位
通过标签名称进行定位,在同一个html页面当中,相同标签会有很多
如果有重复的标签,定位到的元素默认都是第一个标签需求: - 定位方法
find_element_by_tag_name(tag_name)#tag_name表示的是元素的标签名称。
4.2.5 link_text定位
通过超链接的全部文本信息进行元素定位,主要用来定位a标签
- 定位方法
find_element_by_link_text(link_text)# link_text 参数代表的是a标签的全部文本内容
4.2.6 partial_link_text定位
通过超链接的局部文本信息进行元素定位,主要用来定位a标签
- 定位方法
find_element_by_partial_link_text(partial_link_text)
- partial_link_text表示的是a标签的局部文本内容
4.2.7 定位一组元素
- 定位一组元素的方法
find_elements_by_tag_name(tag_name)
- 定位一组元素返回的值是一个列表
- 可以通过下标来使用列表中的元素,下标是从0开始
- 需求 通过li标签定位一组元素,通过索引方法对知乎链接点击
4.2.8 Xpath定位
- XPath即为XML Path的简称,它是一门在 XML 文档中查找元素信息的语言
- HTML可以看做是XML的一种实现,所以Selenium用户可以使用这种强大的语言在Web应用中定位元素
- 定位思路 - 路径-定位- 利用元素属性-定位- 层级与属性结合-定位
举例:https://www.w3school.com.cn/example/xmle/books.xml
定位方法
driver.find_element_by_xpath(xpath)
路径定位
- 绝对路径:从最外层元素到指定元素之间所有经过元素层级的路径,绝对路径以/html根节点开始,使用/来分隔元素层级;
- 如: /html/body/div/fieldset/p[1]/input
xpath扩展-了解
一个/是绝对路径,从根元素开始
两个//是相对路径,递归查找所有子孙
一个. 是当前层,两个.是上一层
@表示取属性
[]叫谓语,里面跟的是查询条件
条件支持算数运算 ( + - * / > < ) ,条件支持逻辑运算 and or
取文本值用text(),不加@因为它是个函数
常用函数:contains(属性名或者节点名,文本值)
( \operatorname{text}\left( \right) ) 是取文本值,也可以当做一个查询条件
last()取末尾,倒数第二last()-1
starts-with(),表示以XX开头,写法是括号加两个入参
not(),表示否定,把内容全包进去
count(),取节点或属性个数
4.2.9 CSS定位
- CSS是一种语言,它用来描述HTML元素的显示样式;
- 在CSS中,选择器是一种模式,用于选择需要添加样式的元素;
- 在Selenium中也可以使用这种选择器来定位元素。
- 提示: CSS定位比XPath定位速度要快 - 定位思路 - id选择器- class选择器- 属性选择器- 层级选择器
五、页面元素处理
5.1 找到元素后操作
点击操作:
element.click() #element表示的是元素对象输入操作:
element.send_keys(“value”) element表示的是元素对象, value表示的是要输入的内容
5.2 获取常用元素方法
5.2.1 text
- 获取元素的文本内容
5.2.2 get_attribute(“attribute”)
- 获取元素对应属性名称的属性值, attribute表示的是属性
5.2.3 is_enabled()
- 判断元素是否可用,返回值为true或者false
5.2.4 is_selected()
- 判断复选框或者单选框是否被选中,返回值为true或者false
六、Selenium鼠标键盘操作
6.1 鼠标操作
6.1.1 鼠标操作实现方式
Selenium提供鼠标操作的方法及步骤
需要导入ActionChains类
from selenium.webdriver.common.action_chains import ActionChains
action =ActionChains(driver)# driver表示的是浏览器驱动对象
action.perform()
- 通过ActionChains实例化鼠标对象
- 调用鼠标的事件方法
- 调用鼠标的执行方法
6.1.2 鼠标悬停
- 案例 demo页面鼠标在Focused按钮悬停
# 导包from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
import time
# 实例化浏览器
driver=webdriver.Chrome()# 打开demo 网站
driver.get('file:///D:/demo.html')# 鼠标操作 导包# 实例化 Actionchains
action =ActionChains(driver)
e1 = driver.find_element_by_class_name('over')
action.move_to_element(el)
action.perform()
6.1.3 鼠标双击
- 案例 demo页面鼠标在DoubleClick按钮双击
# 导包from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains import time
# 实例化浏览器
driver =webdriver.Chrome()# 打开demo 网站
driver.get('file:///D:/demo.html')# 鼠标操作 导包# 实例化 Actionchains
action = ActionChains(driver)# 鼠标双击
el = driver.find_element_by_class_name('double')
action.double_click(el).perform()# 组合一起操作# action.move_to_element(move).pause(5).double_click(double).perform()
6.1.4 鼠标拖动
实现方式
- 鼠标拖拽方法 1 按住不抬起 – 移动到拖拽的位置 – 释放 – 执行
- 鼠标拖拽方法2 通过元素
action.drag_and_drop(div1,div2).perform()
action.drag_and_drop_by_offset(div1,xoffset=,yoffset=).perform()
案例 drop文件 红色的滑块移动到绿色滑块上
- 鼠标拖拽方法1
# 导包from selenium import webdriver
import time
from selenium.webdriver.common.action_chains import ActionChains
# 实例化浏览器
driver=webdriver.Chrome()# actionchains实例化
action=ActionChains(driver)# 第一种方法 通过鼠标组合 按住不抬起--移动div2 -- 释放--执行
div1 = driver.find_element_by_id('div1')
div2 = driver.find_element_by_id('div2')
action.click_and_hold(div1).move_to_element(div2).release().perform()
- 案例 鼠标拖拽方法2
# 第二种方法 通过元素滑动
time.sleep(2)# action.drag_and_drop(div1,div2).perform()
- 案例 鼠标拖拽方法3
# 第三种方法 通过坐标print(div1.location)print(div2.location)
action.drag_and_drop_by_offset(div1, xoffset=162, yoffset=0).perform()
6.2 键盘操作
6.2.1 键盘常见快捷键删除、全选、复制、粘贴
- 模拟键盘上面的快捷键的操作
- 调用键盘操作的快捷键的方法
- 导包
from selenium.webdriver.common.keys import Keys
element.send_keys(快捷键的键值)
需要导入Keys类 单键值: 直接传入对应的键值
- 键盘常见快捷键
send_keys (Keys.BACK_SPACE) 删除键(BackSpace)
send_keys(Keys.SPACE) 空格键(Space)
send_keys (Keys.TAB) 制表键(Tab)
send_keys(Keys.ESCAPE) 回退键(Esc)
send_keys(Keys.ENTER) 回车键(Enter)
send_keys(Keys.CONTROL,‘a’) 全选(Ctrl+A)
send_keys(Keys.control, ‘c’) 复制(Ctrl+C)
send_keys(Keys.CONTROL, ‘v’) 粘贴
- 案例 打开网站注册页面 定位手机号码输入框信息18800–删除0–复制值-粘贴到验证码输入框
# 导包from selenium import webdriver
from selenium.webdriver.common.keys import Keys
# 实例化浏览器
driver = webdriver.Chrome()# 键盘调用
river.get('http://localhost:8081/')# 点击注册
driver.find_element_by_link_text('注册').click()# 手机号码 输入18800
e1 = driver.find_element_by_name('username')
e1.send_keys('18800')# 删除
e1.send_keys(Keys.BACK_SPACE)# 全选
e1.send_keys(Keys.control,'a')# 复制
e1.send_keys(Keys.CONTROL,'c')# 粘贴图像验证码
driver.find_element_by_name('verify_code').send_keys(Keys.CONTROL,'v')
七、Selenium 元素等待
7.1 元素等待概念
- 元素等待
概念: 在定位页面元素时如果未找到, 会在指定时间内一直等待的过程
- 为什么要设置元素等待?
网络速度慢电脑配置低服务器处理请求慢
- Selenium中元素等待有几种类型呢?
三种元素等待类型
7.2 三种等待类型
7.2.1 Time (强制等待)
- 案例 demo页面点击wait按钮,等待6s,打印提示信息
# 导包from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverwait
import time
# 实例化浏览器
driver = webdriver.chrome()
driver.implicitly_wait(8)
driver.get('file:///D:/demo.html')# 定位wait 按钮 打印提示信息
driver.find_element_by_class_name('wait').click()# 强制等待# time.sleep(8)
driver.find_element_by_class_name('red')
7.2.2 Implicitly_Wait() (隐式等待)
- 概念
定位元素时,如果能定位到元素则直接返回该元素,不触发等待;如果不能定位到该元 素,则间隔一段时间后再去定位元素;如果在达到最大时长时还没有找到指定元素,则抛出元素 不存在的异常 NoSuchElementException
- 案例 demo页面点击wait按钮,等待6s,打印提示信息
# 导包from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
import time
# 隐式等待# driver.implicitly_wait(8)# 定位wait 按钮 打印提示信息print(driver.find_element_by_class_name('red').text)
2.2.3 WebDriverWait() (显示等待)
- 操作步骤
导包:
from selenium.webdriver.support.wait import webDriverwait
webDriverWait(driver, timeout, poll_frequency=0.5)
- driver:浏览器驱动对象
- timeout :超时的时长,单位:秒
- po11_frequency : 检测间隔时间,默认为0.5秒
- 调用方法 until(method):直到…时
- method : 函数名称,该函数用来实现对元素的定位,一般使用匿名函数来实现
lambda x:driver.find_element_by_name('username')
el = WebDriverWait(driver,timeout=5).until(lambda x:
x.find_element_by_name("username"))
- 可以通过as关键字将expected_conditions 重命名为EC,并调用presence_of_element_located()方法判断元素是否存在
- lambda
el = WebDriverWait(driver,timeout=6).until(lambda x :
driver.find_element(By.CLASS_NAME,'red'))print(el.text)
- 期望条件
e1 =webDriverWait(driver, timeout=6).until(EC.presence_of_element_located((By.CLASS_NAME,'red')))print(el.text)
八、Selenium Alert、多窗口、Frame切换
8.1 Alert处理
8.1.1 操作步骤
driver.switch_to.alert 获取弹出框对象
8.1.2 处理弹出框
alert.text 获取弹出框提示信息 alert.accept() 确定弹出框
alert.dismiss() 取消弹出框
alert.send_keys() 输入信息
- 案例 demo页面点击alert按钮,点确定
# 导包import time
from selenium import webdriver
driver = webdriver.Chrome()
driver.get('file:///D:/demo.html')# 切换警告窗口
driver.find_element_by_class_name('alert').click()# 确认
driver.switch_to.alert.accept()
alert.dismiss()
- 案例 demo页面点击confirm按钮,取消弹窗
# 导包import time
from selenium import webdriver
driver = webdriver.Chrome()
driver.get('file:///D:/demo.html')# 切换警告窗口# driver.find_element_by_class_name('alert').click()# 确认# driver.switch_to.alert.accept()# driver.find_element_by_class_name('confirm').click()# 取消# driver.switch_to.alert.dismiss()# time.sleep(2)## alert.send_keys- 案例 demo页面点击cprompt按钮,输入信息
# 输入信息# driver.find_element_by_class_name('prompt').click()# time.sleep(3)# driver.switch_to.alert.send_keys('123')# driver.switch_to.alert.accept()## alert.text- 案例 demo页面点击order_confirm按钮,打印订单信息
# 打印文本信息# driver.find_element_by_class_name('order_confirm').click()# time.sleep(8)# print(driver.switch_to.alert.text)
8.2 多窗口处理
多窗口,点击某些链接会重新打开一个窗口,若想在在新页面操作,需要切换窗口
- 实现方法- 获取当前窗口句柄: driver.current_window_handle- 获取所有窗口句柄: driver.window_handles 返回的是一个列表- 切换窗口句柄: driver.switch_to.window(window_handle) ,window_handle是窗口句柄- 窗口句柄:由操作系统生成的一串唯 一识别码,是一串字符- 案例 demo页面 - 点击百度超链接输入软件测试 - 获取句柄 - 切换百度 - 输入框输入信息 - 切换
# 导包import timefrom selenium import webdriver# 导入键盘from selenium.webdriver.common.keys import Keysdriver = webdriver.chrome()driver.get('file:///D:/demo.html')# 切換窗口# 定位百度超链接 定位百度搜索框 输入 软件测试driver.find_element_by_link_text('baidu').click()# 获取句柄print(driver.window_handles)handles=driver.window_handles# 切换到最新打开的窗口driver.switch_to.window(handles[-1])driver.find_element_by_id('kw').send_keys('软件测试')time.sleep(5)# 跳转到demo 输入 我回来了# 切换到第一个打开的窗口driver.switch_to.window(handles[0])driver.find_element_by_id('user').send_keys('我回来了')time.sleep(2)
8.3 Frame处理
8.31frame
HTML页面中的一种框架,主要作用是在当前页面中指定区域显示另一页面元素
frame分类
iframe与frame定位方法selenium是统一的
driver.switch_to.frame(frame_reference)#切换到指定
8.3.2 frame的方法
- frame框架的name、id或者定位到的frame元素
- index
- 元素标签
driver.switch_to.default_content()#恢复默认页面方法
需求:demo页面 定位
- 通过id/name方式
案例
# 导包import time
from selenium import webdriver
driver = webdriver.Chrome()
driver.get('file:///D:/demo.html')# 切换 第一种方式 id name 直接取属性值# driver.switch_to.frame('aa')# time.sleep(2)# driver.find_element_by_id('kw').send_keys('好好学习')
- 通过index方式
# 导包import time
from selenium import webdriver
driver = webdriver.Chrome()
driver.get('file:///D:/demo.html')# 第二种方式 通过索引# driver.switch_to.frame(0)# driver.find_element_by_id('kw').send_keys('好好学习')
- 通过元素标签
# 导包import time
from selenium import webdriver
driver = webdriver.Chrome()
driver.get('file:///D:/demo.html')# 第三种方式
driver.switch_to.frame(driver.find_element_by_tag_name('iframe'))
driver.find_element_by_id('kw').send_keys('好好学习')
- 案例 demo页面进入百度输入好好学习,返回demo主页面定位input输入框输入‘天天向上’
# 导包import time
from selenium import webdriver
driver=webdriver.Chrome()
driver.get('file:///D:/demo.html')# 切换 第一种方式 id name 直接取属性值# driver.switch_to.frame('aa')# time.sleep(2)# driver.find_element_by_id('kw').send_keys('好好学习')# 调用恢复默认页面方法(switch_to.default_content())
driver.switch_to.default_content()
driver.find_element_by_id('user').send_keys('天天向上')
8.3.3总结
- 针对同一层级的 frame, 如果要进行切换的话, 需要切回到默认首页
- 不管当前在哪个层级, 如果要回到默认首页, 只需要调用一次
- 回到默认首页的方法(driver.switch_to.default_content())
九、Selenium 处理验证码及上传文件
9.1 Selenium处理验证码
9.1.1 什么是验证码
指一种随机生成的信息(数字、字母、汉字、图片、算术题)等为了防止恶意的请求行为, 增加应用的安全性
自动化过程中也是需要进行注册或者登陆的操作, 所以需要处理验证
9.1.2 验证码处理方式
- 去掉验证码 由开发操作 , 用在测试环境
- 设置万能验证码 由开发 操作, 一般也只使用在测试环境
- 验证码识别技术 由于技术难度高, 识别率很难达到 ( {100}% ) ,一般不建议使用
- 记录COOKIE 通过记录cookie来跳过登陆的操作
9.1.3 Cookie原理
- Cookie是由Web服务器生成的, 并且保存在用户浏览器上的小文本文件, 它可以包含用户相关的信息
- Cookie数据格式: 键值对组成 (python中的字典)
- Cookie产生: 客户端请求服务器, 如果服务器需要记录该用户状态, 就向客户端浏览器颁发一个Cookie数据 Cookie使用: 当浏览器再次请求该网站时, 浏览器把请求的数据和Cookie数据一同提交给服务器, 服务器检查Cookie, 以此来辨认用户状态
9.1.4 Selenium操作cookie
driver.get_cookie(name) 获取指名称的cookie信息 返回的是一个字典
driver.get_cookies() 获取的是所有cookie的信息, 返回的是一个列表
driver.add_cookie(dict_cookie) 往浏览器驱动增加cookie,
dict_cookie是一字典
Progress Telerik Fiddler Web Debugger
需求: 抓取cookie信息案例
# 导包from selenium import webdriver
driver = webdriver.Chrome()
driver.get('http://localhost:8081/')# cookie 注入# 绕过登录# driver.add_cookie({'name' : 'foo', 'value' : 'bar'})
driver.add_cookie({'name':'uname','value':'18888888888'})
driver.add_cookie({'name':'user_id','value':'2593'})# 刷新
driver.refresh()
9.2 selenium上传文件
- 实现方式
input标签,组合send_keys () 文件路径传入
- 案例
# 导包import time
from selenium import webdriver
driver = webdriver.Chrome()
driver.get('https://image.baidu.com/')# 点击上传按钮
driver.find_element_by_xpath('//a[@id="sttb"]/img[1]').click()# 上传 send-keys
driver.find_element_by_id('stfile').send_keys(r'c:\\Users\\ThinkPad\\Desktop\\Day2\\1 .png')
time.sleep(5)
版权归原作者 不知名-测试开发 所有, 如有侵权,请联系我们删除。