Web自动化工具——Selenium
一、Selenium简介
Selenium是一个用于Web应用程序测试的工具
Selenium测试直接运行在浏览器中,就像真正的用户在操作一样
支持的浏览器包括IE(7, 8, 9, 10, 11),Mozilla Firefox,Safari,Google Chrome,Opera,Edge等
二、Selenium主要功能
测试与浏览器的兼容性——测试应用程序看是否能够很好得工作在不同浏览器和操作系统之上
测试系统功能——创建回归测试检验软件功能和用户需求。支持自动录制动作和自动生成 .Net、Java、Perl等不同语言的测试脚本
三、Selenium的优点
Selenium 测试直接在浏览器中运行,就像真实用户所做的一样
Selenium 测试可以在 Windows、Linux 和 Macintosh上的 Internet Explorer、Chrome和 Firefox 中运行
四、Selenium测试脚本
通过编写模仿用户操作的 Selenium 测试脚本,可以从终端用户的角度来测试应用程序。通过在不同浏览器中运行测试,更容易发现浏览器的不兼容性
Selenium 的核心,也称browser bot,是用 JavaScript 编写的。这使得测试脚本可以在受支持的浏览器中运行。browser bot 负责执行从测试脚本接收到的命令,测试脚本要么是用 HTML 的表布局编写的,要么是使用一种受支持的编程语言编写的
五、Selenium基础使用方法
5.1 声明浏览对象
from selenium import webdriver
#构造模拟浏览器
firefox_login=webdriver.Ie() # Firefox()
firefox_login=webdriver.Chrome()
这一步可设定无界面模式,即操作浏览器时,隐层浏览器
options = webdriver.ChromeOptions()
options.add_argument('--headless') # 设置无界面 可选
firefox_login=webdriver.Chrome(chrome_options=options)
5.2 访问页面
firefox_login.get('http://www.renren.com/')
firefox_login.maximize_window() # 窗口最大化,可有可无,看情况
firefox_login.minimize_window()
5.3 查找元素并交互
firefox_login.find_element_by_id('email').clear()
firefox_login.find_element_by_id('email').send_keys('xxx@sina.com')
5.4 操作浏览器
#导入 webdriver
from selenium import webdriver
#要想调用键盘按键操作需要引入keys包
from selenium.webdriver.common.keys import Keys
#调用环境变量指定的PhantomJS浏览器创建浏览器对象
driver = webdriver.PhantomJS()
#如果没有在环境变量指定PhantomJS位置
#driver = webdriver.PhantomJS(executable_path="./phantomjs"))
#get方法会一直等到页面被完全加载,然后才会继续程序,通常测试会在这里选择 time.sleep(2)
driver.get("http://www.baidu.com/")
#获取页面名为 wrapper的id标签的文本内容
data = driver.find_element_by_id("wrapper").text
#打印数据内容
print data
#打印页面标题 "百度一下,你就知道"
print driver.title
#生成当前页面快照并保存
driver.save_screenshot("baidu.png")
#id="kw"是百度搜索输入框,输入字符串"长城"
driver.find_element_by_id("kw").send_keys(u"马云")
#id="su"是百度搜索按钮,click() 是模拟点击
driver.find_element_by_id("su").click()
#获取新的页面快照
driver.save_screenshot("马云.png")
#打印网页渲染后的源代码
print driver.page_source
#获取当前页面Cookie
print driver.get_cookies()
#ctrl+a 全选输入框内容
driver.find_element_by_id("kw").send_keys(Keys.CONTROL,'a')
#ctrl+x 剪切输入框内容
driver.find_element_by_id("kw").send_keys(Keys.CONTROL,'x')
#输入框重新输入内容
driver.find_element_by_id("kw").send_keys(u"王健林")
#模拟Enter回车键
driver.find_element_by_id("su").send_keys(Keys.RETURN)
#清除输入框内容
driver.find_element_by_id("kw").clear()
#生成新的页面快照
driver.save_screenshot("王健林.png")
#获取当前url
print driver.current_url
#关闭当前页面,如果只有一个页面,会关闭浏览器
#driver.close()
#关闭浏览器
driver.quit()
5.5 页面操作
Selenium 的 WebDriver提供了各种方法来寻找元素,有一个表单输入框
<input type="text" name="user-name" id="passwd-id" />
不同的标签获取页面元素:
#获取id标签值
element = driver.find_element_by_id("passwd-id")
#获取name标签值
element = driver.find_element_by_name("user-name")
#获取标签名值
element = driver.find_elements_by_tag_name("input")
#也可以通过XPath来匹配
element = driver.find_element_by_xpath("//input[@id='passwd-id']")
5.6 定位UI元素
关于元素的选取,有如下的API 单个元素选取
find_element_by_id
find_elements_by_name
find_elements_by_xpath
find_elements_by_link_text
find_elements_by_partial_link_text
find_elements_by_tag_name
find_elements_by_class_name
find_elements_by_css_selector
1.By ID
<div id="coolestWidgetEvah">...</div>
实现
element = driver.find_element_by_id("coolestWidgetEvah")
2.By Class Name
<div class="cheese"><span>Cheddar</span></div><div class="cheese"><span>Gouda</span></div>
实现
cheeses = driver.find_elements_by_class_name("cheese")
3.By Tag Name
<iframe src="..."></iframe>
实现
frame = driver.find_element_by_tag_name("iframe")
4.By Name
<input name="cheese" type="text"/>
实现
cheese = driver.find_element_by_name("cheese")
5.By Link Text
<a href="http://www.google.com/search?q=cheese">cheese</a>
实现
cheese = driver.find_element_by_link_text("cheese")
6.By Partial Link Text
<a href="http://www.google.com/search?q=cheese">search for cheese</a>>
实现
cheese = driver.find_element_by_partial_link_text("cheese")
7.By CSS
<div id="food"><span class="dairy">milk</span><span class="dairy aged">cheese</span></div>
实现
cheese = driver.find_element_by_css_selector("#food span.dairy.aged")
8.By XPath
<input type="text" name="example" />
<INPUT type="text" name="other" />
实现
inputs = driver.find_elements_by_xpath("//input")
5.7 获取日志
c.log_types #获取当前日志类型
c.get_log('browser')#浏览器操作日志
c.get_log('driver') #设备日志
c.get_log('client') #客户端日志
c.get_log('server') #服务端日志
#3.窗口操作
c.maximize_window()#最大化
c.fullscreen_window() #全屏
c.minimize_window() #最小化
c.get_window_position() #获取窗口的坐标
c.get_window_rect()#获取窗口的大小和坐标
c.get_window_size()#获取窗口的大小
c.set_window_position(100,200)#设置窗口的坐标
c.set_window_rect(100,200,32,50) #设置窗口的大小和坐标
c.set_window_size(400,600)#设置窗口的大小
c.current_window_handle #返回当前窗口的句柄
c.window_handles #返回当前会话中的所有窗口的句柄
5.8 cookie 操作
get_cookies()
delete_all_cookies()
add_cookie()
from selenium import webdriver
browser = webdriver.Chrome()
browser.get('https://www.zhihu.com/explore')
print(browser.get_cookies())
browser.add_cookie({'name': 'name', 'domain': 'www.zhihu.com', 'value': 'zhaofan'})
print(browser.get_cookies())
browser.delete_all_cookies()
print(browser.get_cookies())
5.9 鼠标动作链
有些时候,我们需要再页面上模拟一些鼠标操作,比如双击、右击、拖拽甚至按住不动等,我们可以通过导入 ActionChains 类来做到
#导入 ActionChains 类
from selenium.webdriver import ActionChains
#鼠标移动到 c 位置
c = driver.find_element_by_xpath('element')
ActionChains(driver).move_to_element(c).perform()
#在 c 位置单击
c = driver.find_element_by_xpath("elementA")
ActionChains(driver).move_to_element(c).click(c).perform()
#在 c 位置双击
c = driver.find_element_by_xpath("elementB")
ActionChains(driver).move_to_element(c).double_click(c).perform()
#在 c 位置右击
c = driver.find_element_by_xpath("elementC")
ActionChains(driver).move_to_element(c).context_click(c).perform()
#在 c 位置左键单击hold住
c = driver.find_element_by_xpath('elementF')
ActionChains(driver).move_to_element(c).click_and_hold(c).perform()
#将 c1 拖拽到 c2 位置
c1 = driver.find_element_by_xpath('elementD')
c2 = driver.find_element_by_xpath('elementE')
ActionChains(driver).drag_and_drop(c1, c2).perform()
5.10 Alert
当你触发了某个事件之后,页面出现了弹窗提示,处理这个提示或者获取提示信息,在弹窗处理中有三种情况,浏览器弹出框,新窗口弹出框,人为弹出框
浏览器弹出框
from selenium.webdriver.common.alert import Alert
c=webdriver.Chrome(executable_path=r'C:\Users\chromedriver.exe')
c.implicitly_wait(10)
c.get('https://www.baidu.com')
a1=Alert(c)
a1.accept() #确定
a1.dismiss() #取消
新窗口弹出框
新窗口弹出就不一样需要通过句柄来定位
from selenium import webdriver
from selenium.webdriver.common.by import By
import time
c=webdriver.Chrome(executable_path=r'C:\Users\chromedriver.exe')
c.implicitly_wait(10)
c.get('https://www.baidu.com')
kw1=c.find_element(By.ID,'1')
tj=c.find_element(By.ID,'2')
hwnd=c.window_handles #所有窗口句柄
for h in hwnd:
if h !=c.current_window_handle: #如果句柄不是当前窗口句柄则切换 c.switch_to_window(h) #切换窗口
else:
print('无需切换窗口')
time.sleep(3)
c.close()
c.quit()
人为弹出框
5.11 显式等待和隐式等待
显式等待
显式等待指定某个条件,然后设置最长等待时间。如果在这个时间还没有找到元素,那么便会抛出异常了
如果不写参数,程序默认会 0.5s 调用一次来查看元素是否已经生成,如果本来元素就是存在的,那么会立即返回
from selenium import webdriver
from selenium.webdriver.common.by import By
#WebDriverWait 库,负责循环等待
from selenium.webdriver.support.ui import WebDriverWait
#expected_conditions 类,负责条件出发
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Chrome()
driver.get("http://www.xxxxx.com/loading")
try:
# 页面一直循环,直到 id="myDynamicElement" 出现
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, "myDynamicElement"))
)
finally:
driver.quit()
隐式等待
隐式等待就是简单地设置一个等待时间,单位为秒
当然如果不设置,默认等待时间为0
from selenium import webdriver
driver = webdriver.Chrome()
driver.implicitly_wait(10) # seconds
driver.get("http://www.xxxxx.com/loading")
myDynamicElement = driver.find_element_by_id("myDynamicElement")