一、环境搭建及配置
1.1 selenium介绍
Selenium是一个用于Web应用程序测试的工具行。Selenium测试直接运在浏览器中,就像真正的用户在操作一样。支持的浏览器包括IE(7, 8, 9, 10, 11),Mozilla Firefox,Safari,Google Chrome,Opera,Edge等。这个工具的主要功能包括:测试与浏览器的兼容性——测试你的应用程序看是否能够很好得工作在不同浏览器和操作系统之上。测试系统功能——创建回归测试检验软件功能和用户需求。支持自动录制动作和自动生成 .Net、Java、Perl等不同语言的测试脚本。
1.2 selenium+python环境搭建及配置
前提条件:已安装好Python开发环境(推荐安装Python3.5及以上版本)
安装步骤:
1、安装selenium
1)Win:pip install selenium Mac:pip3 install selenium
2)
2、安装Webdirver
各大浏览器webdriver地址可参见:https://docs.seleniumhq.org/download/ Firefox:https://github.com/mozilla/geckodriver/releases/ Chrome:https://sites.google.com/a/chromium.org/chromedriver/ 或者
http://chromedriver.storage.googleapis.com/index.html IE:http://selenium-release.storage.googleapis.com/index.html 注:webdriver需要和对应的浏览器版本以及selenium版本对应
二、元素定位及浏览器基本操作
2.1 浏览器的启动
注:浏览器后写入安装的webdirver路径
启动Chrome浏览器:
from selenium import webdriver
driver=webdriver.Chrome("E:\jnpx\soft\chromedriver.exe") 注:写入安装webdirver的路径
driver.get('http://www.baidu.com')
启动Fiefox浏览器:
from selenium import webdriver
browser = webdriver.Firefox("E:\jnpx\soft\chromedriver.exe")
browser.get('http://www.baidu.com/')
启动IE浏览器:
from selenium import webdriver
browser = webdriver.Ie("E:\jnpx\soft\chromedriver.exe")
browser.get('http://www.baidu.com/')
2.2 元素定位
想要操作这个元素,就要拿到这个元素,识别这个元素。如同每个人的身份证一样,一个对象也有类似的属性,我们可以通过属性找到这个对象。
webdriver中提供了一些定位对象的方法,常用的有以下几种:
- id定位:find_element_by_id()
- name定位:find_element_by_name()
- class定位:find_element_by_class_name()
- link定位:find_element_by_link_text()
- partial link定位:find_element_by_partial_link_text()
- tag定位:find_element_by_tag_name()
- xpath定位:find_element_by_xpath()
- css定位:find_element_by_css_selector()
id定位
from selenium import webdriver
#启动浏览器
driver=webdriver.Chrome("E:\jnpx\soft\chromedriver.exe") webdriver安装地址
#打开百度首页
driver.get('http://www.baidu.com')
#通过id定位输入框,输入selenium内容
driver.find_element_by_id('kw').send_keys("selenium")
name定位
from selenium import webdriver
driver=webdriver.Chrome("E:\jnpx\soft\chromedriver.exe")
driver.get('http://www.baidu.com')
#通过name定位输入框位置
driver.find_element_by_name('wd').send_keys("selenium")
class定位
from selenium import webdriver
driver=webdriver.Chrome("E:\jnpx\soft\chromedriver.exe")
driver.get('http://www.baidu.com')
#通过class定位输入框位置并输入内容
driver.find_element_by_class_name('s_ipt').send_keys('selenium')
link定位
from selenium import webdriver
driver=webdriver.Chrome("E:\jnpx\soft\chromedriver.exe")
driver.get('http://www.baidu.com')
#通过文本定位叫新闻的位置并且点击
driver.find_element_by_link_text('新闻').click()
partial link定位
from selenium import webdriver
driver=webdriver.Chrome("E:\jnpx\soft\chromedriver.exe")
driver.get('http://www.baidu.com')
#模糊查询,查询包含闻字的位置且点击
driver.find_element_by_partial_link_text('闻').click()
tag定位
from selenium import webdriver
driver=webdriver.Chrome("E:\jnpx\soft\chromedriver.exe")
driver.get('http://www.baidu.com')
#通过tag name定位功能的位置,定位input位置且输入内容,由于有很多input功能,所以次代码会报错
driver.find_element_by_tag_name('input').send_keys('selenium')
xpath定位
from selenium import webdriver
driver=webdriver.Chrome("E:\jnpx\soft\chromedriver.exe")
driver.get('http://www.baidu.com')
#通过位置定位,次代码意思为定位所有input元素且id为kw并输入内容
driver.find_element_by_xpath("//input[@id='kw']").send_keys('selenium')
css定位
from selenium import webdriver
driver=webdriver.Chrome("E:\jnpx\soft\chromedriver.exe")
driver.get('http://www.baidu.com')
#通过css定位搜索框位置,且输入内容
driver.find_element_by_css_selector('#kw').send_keys('selenium')
2.2.1 class含有空格的处理方式
在定位元素时,class name是有多个class组合的复合类,中间以空格隔开,如果直接定位元素会报错,以下有几种处理方式
例:
- class属性唯一但是有空格,选择空格两边唯一的那一个
- 若空格隔开的class不唯一可以通过索引进行定位self.driver.find_elements_by_class_name('table-dragColumn')[0].click()
- 通过css方法进行定位(空格以‘.’代替)#前面加(.)空格地方用点(.)来代替self.driver.find_element_by_css_selector('.dtb-style-1.table-dragColumns').click()#包含整个类self.driver.find_element_by_css_selector('class="dtb-style-1 table-dragColumns').click()
代码展示
from selenium import webdriver
driver=webdriver.Chrome("E:\jnpx\soft\chromedriver.exe")
driver.get("http://mail.126.com/")
driver.implicitly_wait(20)
driver.switch_to.frame("x-URS-iframe")
# 方法一:取单个class属性
driver.find_element_by_class_name("dlemail").send_keys("yoyo")
driver.find_element_by_class_name("dlpwd").send_keys("12333")
# 方法二:定位一组取下标定位(乃下策)
driver.find_elements_by_class_name("j-inputtext")[0].send_keys("yoyo")
driver.find_elements_by_class_name("j-inputtext")[1].send_keys("12333")
# 方法三:css定位
driver.find_element_by_css_selector(".j-inputtext.dlemail").send_keys("yoyo")
driver.find_element_by_css_selector(".j-inputtext.dlpwd").send_keys("123")
# 方法四:取单个class属性也是可以的
driver.find_element_by_css_selector(".dlemail").send_keys("yoyo")
driver.find_element_by_css_selector(".dlpwd").send_keys("123")
# 方法五:直接包含空格的CSS属性定位大法
driver.find_element_by_css_selector("[class='j-inputtext dlemail']").send_keys("yoyo")
2.3 selenium的三种等待方式
有时候为了保证脚本运行的稳定性,需要脚本中添加等待时间。
2.3.1 selenium 强制等待
第一种也是最简单粗暴的一种办法就是强制等待sleep(xx),需要引入“time”模块,这种叫强制等待,不管你浏览器是否加载完了,程序都得等待3秒,3秒一到,继续执行下面的代码,作为调试很有用,有时候也可以在代码里这样等待,不过不建议总用这种等待方式,太死板,严重影响程序执行速度。
from selenium import webdriver
import time
driver=webdriver.Chrome("E:\jnpx\soft\chromedriver.exe")
driver.get('http://www.baidu.com')
time.sleep(3) # 强制等待3秒再执行下一步
print(driver.current_url)
driver.quit()
2.3.2 隐形等待
第二种办法叫隐性等待,通过添加 implicitly_wait() 方法就可以方便的实现智能等待;implicitly_wait(30) 的用法应该比 time.sleep() 更智能,前者只能选择一个固定的时间的等待,后者可以 在一个时间范围内智能的等待。
from selenium import webdriver
driver=webdriver.Chrome("E:\jnpx\soft\chromedriver.exe")
driver.implicitly_wait(30) # 隐性等待,最长等30秒
driver.get('http://baidu.com')
print(driver.current_url)
driver.quit()
2.3.3显性等待
第三种办法就是显性等待,WebDriverWait,配合该类的until()和until_not()方法,就能够根据判断条件而进行灵活地等待了。它主要的意思就是:程序每隔xx秒看一眼,如果条件成立了,则执行下一步,否则继续等待,直到超过设置的最长时间,然后抛出TimeoutException。
wait模块的WebDriverWait类是显性等待类,先看下它有哪些参数与方法:
第三种办法就是显性等待,WebDriverWait,配合该类的until()和until_not()方法,就能够根据判断条件而进行灵活地等待了。它主要的意思就是:程序每隔xx秒看一眼,如果条件成立了,则执行下一步,否则继续等待,直到超过设置的最长时间,然后抛出TimeoutException。
selenium.webdriver.support.wait.WebDriverWait(类)
init
driver: 传入WebDriver实例,即我们上例中的driver
timeout: 超时时间,等待的最长时间(同时要考虑隐性等待时间)
poll_frequency: 调用until或until_not中的方法的间隔时间,默认是0.5秒
ignored_exceptions: 忽略的异常,如果在调用until或until_not的过程中抛出这个元组中的异常,则不中断代码,继续等待,如果抛出的是这个元组外的异常,则中断代码,抛出异常。默认只有NoSuchElementException。
until
method: 在等待期间,每隔一段时间(__init__中的poll_frequency)调用这个传入的方法,直到返回值不是False
message: 如果超时,抛出TimeoutException,将message传入异常
until_not
与until相反,until是当某元素出现或什么条件成立则继续执行,
until_not是当某元素消失或什么条件不成立则继续执行,参数也相同,不再赘述。
看了以上内容基本上很清楚了,调用方法如下:
WebDriverWait(driver, 超时时长, 调用频率, 忽略异常).until(可执行方法, 超时时返回的信息)
这里需要特别注意的是until或until_not中的可执行方法method参数,很多人传入了WebElement对象,如下:
WebDriverWait(driver, 10).until(driver.find_element_by_id('kw')) # 错误
这是错误的用法,这里的参数一定要是可以调用的,即这个对象一定有 call() 方法,否则会抛出异常:
TypeError: 'xxx' object is not callable
在这里,你可以用selenium提供的 expected_conditions 模块中的各种条件,也可以用WebElement的 is_displayed() 、is_enabled()、**is_selected() **方法,或者用自己封装的方法都可以。
2.4 浏览器操作
2.4.1 浏览器最大化,最小化
最大化
driver.maximize_window()
最小化
driver.minimize_window()
2.4.2 浏览器设置窗口大小
设置显示浏览器宽400 高800
driver.set_window_size(400, 800)
2.4.2 浏览器设置前进后退
前进
driver.forword()
后退
driver back()
2.5 操作测试对象
一般来说,webdriver 中比较常用的操作对象的方法有下面几个:
- clic——点击对象
- send_keys——在对象上模拟按键输入
- clear——清除对象的内容,如果可以的话
- submit——提交对象的内容,如果可以的话
- text——用于获取元素的文本信息
2.6 键盘事件
要想调用键盘按键操作需要引入 keys 包:
from selenium.webdriver.common.keys import Keys通过 send_keys()调用按键:
send_keys(Keys.TAB) #模拟tab键
send keys(Keys.Enter) #模拟enter键
from selenium import webdriver
from selenium.webdriver.common.keys import Keys #需要引入 keys 包
import os,time
from selenium import webdriver
driver=webdriver.Chrome("E:\jnpx\soft\chromedriver.exe")
driver.get("http://passport.kuaibo.com/login/?referrer=http%3A%2F%2Fwebcloud .kuaibo.com%2F")
time.sleep(3)
driver.maximize_window() # 浏览器全屏显示
driver.find_element_by_id("user_name").clear()
driver.find_element_by_id("user_name").send_keys("fnngj")
#tab 的定位相相于清除了密码框的默认提示信息,等同上面的 clear()
driver.find_element_by_id("user_name").send_keys(Keys.TAB)
time.sleep(3)
driver.find_element_by_id("user_pwd").send_keys("123456")
#通过定位密码框,enter(回车)来代替登陆按钮
driver.find_element_by_id("user_pwd").send_keys(Keys.ENTER)
#也可定位登陆按钮,通过 enter(回车)代替 click()
driver.find_element_by_id("login").send_keys(Keys.ENTER)
time.sleep(3)
driver.quit()
2.6.1 键盘组合键
ctrl+a
#ctrl+a 全选输入框内容
driver.find_element_by_id("kw").send_keys(Keys.CONTROL,'a')
ctrl+x
#ctrl+x 剪切输入框内容
driver.find_element_by_id("kw").send_keys(Keys.CONTROL,'x')
2.7 鼠标事件
鼠标事件一般包括鼠标右键、双击、拖动、移动鼠标到某个元素上等等。
需要引入ActionChains类。
引入方法:
from selenium.webdriver.common.action_chains import ActionChains
ActionChains 常用方法:
perform() 执行所有ActionChains 中存储的行为;
context_click() 右击;
double_click() 双击;
drag_and_drop() 拖动;
move_to_element() 鼠标悬停。
鼠标双击示例:
#定位到要双击的元素
qqq =driver.find_element_by_xpath("xxx")
#对定位到的元素执行鼠标双击操作
ActionChains(driver).double_click(qqq).perform()
鼠标拖放示例:
#定位元素的原位置
element = driver.find_element_by_name("source")
#定位元素要移动到的目标位置
target = driver.find_element_by_name("target")
#执行元素的移动操作
ActionChains(driver).drag_and_drop(element, target).perform()
2.8 多层框架/层级定位
定位元素过程中经常会遇到找不到元素的问题,出现该问题一般都是以下因素导致:
- 元素定位方法不对
- 页面存在iframe或内嵌窗口
- 页面超时
- webdriver 提供了一个 switch_to_frame 方法,可以很轻松的来解决这个问题。
用法:
#先找到到 ifrome1(id = f1)
browser.switch_to_frame("f1")
同样的,如果是内嵌窗口:browser.switch_to_window("f1")