提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
python Selenium
一、简介
Selenium是一个用于测试网站的自动化测试工具,支持各种浏览器包括Chrome、Firefox、Safari等主流界面浏览器。
Selenium是ThoughtWorks公司研发的一个强大的基于浏览器的开源自动化测试工具。
Selenium测试直接运行在浏览器中,就像真正的用户在操作一样。
详细原理:Selenium 原理探秘
二、安装及下载
1.安装
pip install Selenium
2.下载浏览器驱动
谷歌浏览器驱动下载地址:
https://chromedriver.storage.googleapis.com/index.html
三、快速入门
1. 实例分析
简单的使用
# -*- coding: utf-8 -*-
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
options = webdriver.ChromeOptions()
options.add_argument('ignore-certificate-errors')
driver = webdriver.Chrome(
executable_path="C:\\Google\\Chrome\\Application\\chromedriver.exe",
chrome_options=options
)
driver.get("https://10.192.100.100:8080/login")
ele1 = driver.find_element_by_xpath('//input[@placeholder="请输入用户名"]')
ele2 = driver.find_element_by_xpath('//input[@placeholder="请输入密码"]')
ele1.send_keys("username")
ele2.send_keys("password")
ele2.send_keys(Keys.RETURN)
driver.close()
实例分析
selenium.webdriver
模块提供了所有 WebDriver
的实现,现在支持的WebDriver
的实现有 Firefox,Ie,Chrome,Remote, Keys
类提供了键盘的代码(回车,ALT,F1等等)
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
由于我们要访问的是https的网址,需要设置忽略ssl证书认证的错误。
options = webdriver.ChromeOptions()
options.add_argument('ignore-certificate-errors')
然后我们创建一个Chrome的实例,第一个参数是浏览器驱动,第二个参数书浏览器选项:
driver = webdriver.Chrome(
executable_path="C:\\Google\\Chrome\\Application\\chromedriver.exe",
chrome_options=options
)
driver.get
方法会导向给定的URL的页面,WebDriver会等待页面完全加载完(就是onload函数被触发了)。注意:如果页面用了太多的AJAX,这个机制就需要修改,因为它不知道页面到底是什么时候加载完。
driver.get("https://10.192.100.100:8080/login")
WebDrive提供了一系统类似于find_element_by_*
的方法来寻找页面元素,例如,我们利用find_element_by_xpath
方法,通过元素的xpath
来定位一个文本输入框元素。
ele1 = driver.find_element_by_xpath('//input[@placeholder="请输入用户名"]')
ele2 = driver.find_element_by_xpath('//input[@placeholder="请输入密码"]')
接着我们向输入框发送了一些字符,类似于用键盘直接输入。特殊的键盘符我们可以导入selenium.webdriver.common.keys,然后用Keys类来表示:
ele1.send_keys("username")
ele2.send_keys("password")
ele2.send_keys(Keys.RETURN)
最后要关闭浏览器,你也可以调用quit
方法来代替close
,区别在于quit
会退出整个浏览器,而close
只会关闭一个标签,但是如果浏览器只有一个标签,那么这两个方法完全一样,都会关闭整个浏览器。
driver.close()
2. 元素定位
定位方式有很多种:
- id
- name
- class name
- tag name
- link text
- xpath
- css selector
- partial link text
3. 元素定位方法
定位一个元素 | 定位多个元素 | 说明 |
---|---|---|
find_element_by_id | find_elements_by_id | 通过元素id定位 |
find_element_by_name | find_elements_by_name | 通过元素name定位 |
find_element_by_class_name | find_elements_by_class_name | 通过类名进行定位 |
find_element_by_tag_name | find_elements_by_tag_name | 通过标签定位 |
find_element_by_link_text | find_elements_by_link_text | 通过完整超链接定位 |
find_element_by_xpath | find_elements_by_xpath | 通过xpath表达式定位 |
find_element_by_css_selector | find_elements_by_css_selector | 通过css选择器进行定位 |
find_element_by_partial_link_text | find_elements_by_partial_link_text | 通过部分链接定位 |
例:
<html>
<body>
<h1>Welcome</h1>
<p class="content">Site content goes here.</p>
<a href="continue.html">Continue</a>
<form id="loginForm">
<input name="username" type="text" />
<input name="password" type="password" />
<input name="continue" type="submit" value="Login" />
</form>
</body>
<html>
通过 id 定位表单:
login_form = driver.find_element_by_id('loginForm')
通过 name 定位用户名和密码:
username = driver.find_element_by_name('username')
password = driver.find_element_by_name('password')
通过xpath定位 (注意一下,xpath的下标从1开始,详细xpath语法可学习:xpath语法):
login_form = driver.find_element_by_xpath("/html/body/form[1]")
login_form = driver.find_element_by_xpath("//form[1]")
login_form = driver.find_element_by_xpath("//form[@id='loginForm']")
通过标签定位:
heading1 = driver.find_element_by_tag_name('h1')
通过class定位:
content = driver.find_element_by_class_name('content')
通过css样式定位:
content = driver.find_element_by_css_selector('p.content')
通过链接文本定位超链接定位:
continue_link = driver.find_element_by_link_text('Continue')
continue_link = driver.find_element_by_partial_link_text('Conti')
4. 控制浏览器的常用方法
方法 | 说明 |
---|---|
maximize_window() | 最大化 |
set_window_size() | 设置浏览器的大小 |
back() | 返回 |
forward() | 前进 |
refresh() | 刷新 |
close() | 关闭标签页 |
quit() | 关闭浏览器 |
5. 节点的常用方法
方法 | 说明 |
---|---|
clear() | 清除输入框内容 |
send_keys() | 键盘输入 |
get_attribute() | 获取元素属性值 |
click() | 单击元素 |
键盘操作方法
- 回车键
Keys.ENTER
- Shift键
Keys.SHIFT
- Tab键
Keys.TAB
- Ctrl键
Keys.CONTROL
- 空格键
Keys.SPACE
…
其他键盘操作,请看 selenium.webdriver.common.keys
6. 行为链 ActionChains
ActionChains
可以完成简单的交互行为,例如鼠标移动,鼠标点击事件,键盘输入,以及内容菜单交互。这对于模拟那些复杂的类似于鼠标悬停和拖拽行为很有用。
当你在ActionChains
对象上调用行为方法时,这些行为会存储在ActionChains
对象的一个队列里。调用perform()
时,这些动作就以他们队列的顺序来触发(注意:如果不调用perform,那么这一系列的动作都不会被触发)
写法1:
menu = driver.find_element_by_css_selector(".nav")
hidden_submenu = driver.find_element_by_css_selector(".nav #submenu1")
ActionChains(driver).move_to_element(menu).click(hidden_submenu).perform()
写法2:
menu = driver.find_element_by_css_selector(".nav")
hidden_submenu = driver.find_element_by_css_selector(".nav #submenu1")
actions = ActionChains(driver)
actions.move_to_element(menu)
actions.click(hidden_submenu)
actions.perform()
常用方法
-
向当前的焦点元素发送键
send_keys(*keys_to_send)
-
鼠标左击
click(on_element=None)
-
双击
double_click(on_element=None)
-
右击
context_click(on_element=None)
-
鼠标左键点击一个元素并且保持
click_and_hold(on_element=None)
-
鼠标拖拽到指定节点
drag_and_drop(source, target)
-
拖拽目标元素到指定的偏移点释放
drag_and_drop_by_offset(source, xoffset,yoffset)
-
释放一个元素上的鼠标按键
release(on_element=None)
-
按下键盘,不释放
key_down(value,element=None)
-
释放key_down按下的按键
key_up(value,element=None)
-
将当前鼠标的位置进行移动
move_by_offset(xoffset,yoffset)
-
把鼠标移到一个元素的中间(悬停)
move_to_element(to_element)
-
鼠标移动到元素的指定位置,偏移量以元素的左上角为基准
move_to_element_with_offset(to_element,xoffset,yoffset)
参数:
- on_element: 要点击的元素,如果是None,点击鼠标当前的位置
- source: 鼠标点击的元素
- target: 鼠标松开的元素
- xoffset:X偏移量
- yoffset:Y偏移量
- keys_to_send:要发送的键
7. 等待事件 Wait
由于Web AJAX技术的使用,浏览器载入一个页面时,页面内的元素可能是在不同的时间载入的,这会加大定位元素的困难程度,因为元素不在DOM里,会抛出ElementNotVisibleException
异常,使用waits
,我们就可以解决这个问题。
Selenium WebDriver提供了两类 waits
- 隐式和显式。显式的 waits
会让WebDriver在更深一步的执行前等待一个确定的条件触发,隐式的 waits
则会让WebDriver试图定位元素的时候对DOM进行指定次数的轮询。
显示等待: WebDriverWait
导入模块:
from selenium.webdriver.support.wait import WebDriverWait
使用:
WebDriverWait(driver,timeout,poll_frequency=0.5,ignored_exceptions=None)
- driver:浏览器驱动
- timeout:最长超时时间,默认以秒为单位
- poll_frequency:检测的间隔步长,默认为0.5s
- ignored_exceptions:超时后的抛出的异常信息,默认抛出NoSuchElementExeception异常。
与until()或者until_not()方法结合使用
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# 创建一个实例
driver = webdriver.Chrome(
executable_path="chromedriver.exe"
)
driver.get("http://www.baidu.com")
try:
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, "s-hotsearch-wrapper"))
)
finally:
driver.quit()
until
是指等到指定条件出现,而until_not
是指等到指定条件消失。
ExpectedCondition
里封装了许多频繁使用到的通用条件。
- title_is
- title_contains
- presence_of_element_located
- visibility_of_element_located
- …
隐式等待: implicitly_wait
from selenium import webdriver
driver = webdriver.Chrome()
driver.implicitly_wait(10) # seconds
driver.get("http://www.baidu.com")
myDynamicElement = driver.find_element_by_id('s-hotsearch-wrapper')
一旦设置,这个隐式等待会在WebDriver
对象实例的整个生命周期起作用,它不针对某一个元素。
缺点
:当页面某些js无法加载,但是想找的元素已经出来了,它还是会继续等待,直到页面加载完成(浏览器标签左上角圈圈不再转),才会执行下一句。某些情况下会影响脚本执行速度。
8. 警告框处理 Alert
接受弹框:
Alert(driver).accept()
忽略弹框:
Alert(driver).dismiss()
输入字符:
Alert(driver).send_keys("Willian Shakephere")
读取提示字符:
Alert(driver).text
9. 上传文件 send_keys
通过send_keys
可以实现上传文件:
driver.find_element_by_name("file").send_keys('D:\\upload_file.txt')
10. 操作 cookies
- 获取所有cookies
get_cookies()
- 获取指定cookie
get_cookie(name)
- 添加cookie
add_cookie(cookie_dict)
- 删除cookie
delete_cookie(name,optionsString)
删除cookie信息。“name”是要删除的cookie的名称,“optionsString”是该cookie的选项,目前支持的选项包括“路径”,“域” - 删除所有cookie
delete_all_cookies()
11. 调用JavaScript代码
其实滚动条之类的操作,WebDriver
是没有封装方法的,这时候,就可以通过调用JavaScript
解决。
示例:
js = "window.scrollTo(100,450);"
driver.execute_script(js)
12. 窗口截图
driver.get_screenshot_as_file(file_path)
示例:
# 截取当前窗口,并指定截图图片的保存位置
driver.get_screenshot_as_file("D:\\baidu_img.jpg")
13. 浏览器配置 ChromeOptions
options = webdriver.ChromeOptions()
options.add_argument('ignore-certificate-errors')
四、Selenium 优缺点
1. 优点
- 免费
- 灵活:多平台移植
- 广泛支持的语言,平台和浏览器
Python、Java、C#、PHP、Perl、JS…
Windows、Linux、Mac、Android、IOS
谷歌、火狐、Safari… - 庞大的社区
- 大型插件库
2. 缺点
- 依赖产品的稳定性,前期需要投入一定的开发成本
- 需要一定的编码能力,对测试人员有一定要求
- 框架本身没有报告功能