Selenium 基础
一、 环境搭建
![](https://img-blog.csdnimg.cn/img_convert/3c6f18dcb859d7155aa6c111be03a004.jpeg)
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安装
![](https://img-blog.csdnimg.cn/img_convert/670c49d620e3241101d774bb5a0048ab.jpeg)
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 原理
![](https://img-blog.csdnimg.cn/img_convert/dd751fc4d833f8fc1af7e33a91778751.jpeg)
三、浏览器的实例管理
3.1 通过程序驱动浏览器
项目创建
-
项目名称不要与第三方的模块名同名
-
文件名称也不要与第三方的模块名或者是类名同名
-
项目创建时不要使用虚拟环境
![](https://img-blog.csdnimg.cn/img_convert/9dc663ac9f34d2b98ff9550da36fbf2a.jpeg)
![](https://img-blog.csdnimg.cn/img_convert/f8790b816e551142bb4b11dbe8228fcc.jpeg)
代码实例:
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的得力助手。
作用:快速定位元素,查看元素信息
![](https://img-blog.csdnimg.cn/img_convert/08633bc4ee7b8973f918b6bbf19b40ba.jpeg)
-
快捷键: 一般在windows系统上打开浏览器开发者工具 - 按F12
-
火狐浏览器:在页面上点击右键选择‘查看元素’
-
谷歌浏览器: 在页面上点击右键选择‘检查’ 如何进行元素定位
元素定位:通过元素的信息或元素层级结构来定位元素的
-
元素的信息: 指元素的标签名以及元素的属性 id class name
-
元素的层级结构: 指元素之间相互嵌套的层级结构
4.2 Selenium八种定位元素方法
- Selenium提供了八种定位元素方式
![](https://img-blog.csdnimg.cn/img_convert/45c2c7dff9357eaca1fb5f527b5963bc.jpeg)
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 time from selenium import webdriver # 导入键盘 from selenium.webdriver.common.keys import Keys driver = 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
![](https://img-blog.csdnimg.cn/img_convert/14eacdd9cd04f648d59e47da35ac816d.jpeg)
需求: 抓取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)