1.下载文件
使用selenium.webdriver实现下载文件功能,只需要配置一下浏览器的参数即可实现
1.1 Firefox浏览器配置
对于Firefox,需要我们设置其Profile:
1.browser.download.dir:指定下载路径 os.getcwd() 该函数不需要传递参数,用于返回当前的目录。
2.browser.download.folderList:设置成 2 表示使用自定义下载路径;设置成 0 表示下载到桌面;设置成 1 表示下载到默认路径
3.browser.download.manager.showWhenStarting:在开始下载时是否显示下载管理器
4.browser.helperApps.neverAsk.saveToDisk:对所给出文件类型不再弹出框进行询问
application/octet-stream 为内容的类型
from selenium import webdriver
import time
fp = webdriver.FirefoxProfile()
# 设置使用自定义下载路径
fp.set_preference("browser.download.folderList", 2)
# 是否显示开始:True为显示开始,Flase为不显示开始
fp.set_preference("browser.download.manager.showWhenStarting", False)
# 设置当前目录为下载路径
fp.set_preference("browser.download.dir", 'd:\\')
# 对所给文件类型不再弹窗询问
fp.set_preference("browser.helperApps.neverAsk.saveToDisk", "application/octet-stream")
driver = webdriver.Firefox(firefox_profile=fp)
driver.get("http://pypi.python.org/pypi/selenium")
# 点击到selenium下载文件的页面
driver.find_element_by_css_selector("#files-tab").click()
time.sleep(2)
# 点击下载whl文件的元素
driver.find_element_by_partial_link_text("selenium-4.3.0").click()
1.2 Chrom浏览器配置:
Chrome浏览器,设置其options:
1.download.default_directory:设置下载路径
2.profile.default_content_settings.popups:设置为0禁止弹出窗口
from selenium import webdriver
import time
options = webdriver.ChromeOptions()
# 设置进制弹出窗口和下载路径
prefs = {'profile.default_content_settings.popups': 0, 'download.default_directory': 'd:\\'}
#添加配置项
options.add_experimental_option('prefs', prefs)
driver = webdriver.Chrome(chrome_options=options)
driver.get('http://pypi.python.org/pypi/selenium')
time.sleep(3)
# 点击到selenium下载文件的页面
driver.find_element_by_css_selector("#files-tab").click()
time.sleep(2)
# 点击下载whl文件的元素
driver.find_element_by_partial_link_text("selenium-4.3.0").click()
time.sleep(3)
# driver.quit()
2.Cookie处理
1. Cookie是一小段的文本信息;格式:python中的字典(键值对组成)
2. Cookie产生:客户端请求服务器,如果服务器需要记录该用户状态,就向客户端浏览器颁发一个Cookie格式
3. Cookie使用:当浏览器再请求该网站时,浏览器把请求的网址连同该Cookie一同提交给服务器,服务器检查该Cookie,以此来辨认用户状态。
为什么记录cookie
说明:
1. 用户第一次登陆时,勾选下次直接登陆或者记住密码,就是采用记录cookie实现的
2. cookie内记录用户名和密码(加密)信息,只要请求时服务器收到cookie,就识别成功,默认为已登陆。
有时候我们需要验证浏览器中是否存在某个cookie,因为基于真实的cookie 的测试是无法通过白盒和集成测试完成的。webdriver 可以读取、添加和删除cookie 信息
webdriver 操作cookie 的方法有:
get_cookies() 获得所有cookie 信息
get_cookie(name) 返回特定name 有cookie 信息
add_cookie(cookie_dict) 添加cookie,必须有name 和value 值
delete_cookie(name) 删除特定(部分)的cookie 信息
delete_all_cookies() 删除所有cookie 信息
通过webdriver 操作cookie 是一件非常有意思的事儿,有时候我们需要了解浏览器中是否存在了某个cookie 信息,webdriver 可以帮助我们读取、添加,删除cookie 信息。
3.上传文件
文件上传是web页面上很常见的一个功能,用脚本去实现文件上传却不是那么简单。
一般分两个场景:
一种是input标签,这种可以用selenium提供的send_keys()方法轻松解决;
另外一种非input标签实现起来比较困难,可以借助autoit工具或者SendKeys第三方库。
上传过程一般要打开一个系统的window 窗口,从窗口选择本地文件添加。所以,一般会卡在如何操作本地window 窗口。其实,上传本地文件没我们想的那么复杂;只要定位上传按钮,通过send_keys 添加本地文件路径就可以了。绝对路径和相对路径都可以,关键是上传的文件存在。下面通地例子演示操作过程。
"""
上传文件:
已定位成功的元素.send_keys('文件路径')
"""
from selenium import webdriver
import os
import time
driver = webdriver.Firefox()
file_path = 'file:///' + os.path.abspath('upload_file.html')
driver.get(file_path)
#定位上传按钮,添加本地文件
driver.find_element_by_name('file').send_keys('E:\\源代码教育\python自动化测试\Python自动化测试.xmind')
time.sleep(5)
driver.quit()
4.元素等待
定义:WebDriver定位页面元素时如果未找到,会在指定时间内一直等待的过程;
为了保证脚本运行的稳定性,需要脚本中添加等待时间。
4.1 隐式等待
隐式等待是通过一定的时长等待页面所有元素加载完成。如果超出了设置的时长,元素还没有被加载则抛NoSuchElementException异常。
缺点:
1、使用隐式等待,程序会一直等待整个页面加载完成,才会执行下一步操作;但有时候页面想要的元素早已经加载完成了,但是因为网页上个别元素还没有加载完成,仍要等到页面全部加载完成才能执行下一步,使用也不是很灵活。
2、在等待时间内页面没有加载完成,时间一到也会进入下一步操作;这种情况可能出现要定位的元素没有出现,从而报元素无法找到的错误。
优点:
隐式等待对整个driver的周期都起作用,每一次操作都会调用隐式等待,所以只要设置一次即可。
implicitly_wait()方法来实现隐式等待,默认单位为秒。
driver.implicitly_wait(5)
try:
driver.find_element_by_id("su").click()
except NoSuchElementException as msg:
print(msg)
4.2 显式等待
在设定时间内,针对某一个元素,默认每隔一段时间检测该元素是否存在,如果超过设定时间检测不到则抛出异常。
引包
from selenium.webdriver.support.wait import WebDriverWait
WebDriverWait()
WebDriverWait(driver, timeout, poll_frequency=0.5, ignored_exceptions=None)
driver - WebDriver的驱动程序(IE、Firefox、Chrome等)
timeout - 最长超时时间,默认以秒为单位
poll_frequency - 休眠时间的间隔(步长)时间,默认为0.5秒
ignored_exceptions - 超时后的异常信息,默认情况下抛NoSuchElementException异常。
until()、until_not()
until(method, message=’ ’)
method: 在等待期间,每隔一段时间调用这个传入的方法,直到返回True
message: 如果超时,抛出TimeoutException,将message传入异常
until_not(method, message=’ ’)
与until相反,until是当某元素出现或什么条件成立则继续执行,
until_not是当某元素消失或什么条件不成立则继续执行,参数也相同,不再赘述。
具体调用方法如下:
WebDriverWait(driver, 超时时长, 调用频率, 忽略异常).until(可执行方法, 超时时返回的信息)
例如:
# 判断id为kw元素是否可见s_box = WebDriverWait(driver, 10, 0.5).until(lambda x: x.find_element_by_id('kw'), '元素定位失败')
脚本代码:
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
from selenium.common.exceptions import NoSuchElementException
import time
driver = webdriver.Firefox()
driver.get('http://www.baidu.com')
time.sleep(5)
#显示等待:方式1配合expected_conditions类
element1 =WebDriverWait(driver,5,0.5).until(EC.presence_of_element_located((By.ID,"kw")))
#element1.send_keys('源码时代')
#显示等待:方式2使用匿名函数lambda---学习初期使用
element2 = WebDriverWait(driver,5).until(lambda x: x.find_element_by_id('kw'))
element2.send_keys('源码时代')
print(element2.id)
print(element1.id)
#隐式等待
driver.implicitly_wait(5)
try:
driver.find_element_by_id('su').click()
except NoSuchElementException as msg:
print(msg)
#sleep休眠
time.sleep(5)
driver.quit()
5.expected_conditions模块
expected_conditions 模块可以对网页上元素是否存在,可点击等等进行判断,一般用于断言或与WebDriverWait配合使用。
一般情况下,我们在使用expected_conditions类时都会对其进行重命名,通过as关键字对其重命名为EC。
引包: from selenium.webdriver.support import expected_conditions as EC
title_is(title) 判断网页title是否是特定文本(英文区分大小写),若完全相同则返回True,否则返回False
title_contains(title) 判断网页title是否包含特定文本(英文区分大小写),若包含则返回True,不包含返回False
presence_of_element_located(locator) 判断一个元素存在于页面DOM树中,存在则返回元素本身,不存在则报错。locator为一个(by, path)元组,这个(by, path)的by是Selenium的一个类(selenium.webdriver.common.by.By),包括CLASS_NAME,CSS_SELECTOR,ID,LINK_TEXT,NAME,PARTIAL_LINK_TEXT,TAG_NAME和XPATH,和我们元素定位中使用的方法相同
('id','kw') == (By.ID,'kw')
('class name','s_ipt')
('css selector','#kw')
('partial link text','链接部分文本值')
visibility_of_element_located(locator) 判断特定元素是否存在于DOM树中并且可见,可见意为元素的高和宽都大于0,元素存在返回元素本身,否则返回False
这个类和presence_of_element_located(locator)有点像,但后者只强调元素存在于DOM树中,可见不可见无所谓,而前者要求必须高和宽必须都大于0,因此后者在性能上会稍微快一点点
visibility_of(element)同上面一样,不过参数从locator的元组变为元素
presence_of_all_elements_located(locator) 判断定位的元素范围内,至少有一个元素存在于页面当中,存在则以list形式返回元素本身,不存在则报错。
text_to_be_present_in_element(locator,text) 判断给定文本是否出现在特定元素中,若存在则返回True,不存在返回False
text_to_be_present_in_element_value(locator,text) 判断某文本是否是存在于特定元素的value值中,存在则返回True,不存在则返回False,对于查看没有value值的元素,也会返回False
frame_to_be_available_and_switch_to_it(locator) 判断某个frame是否可以切换过去,若可以则切换到该frame,否则返回False .
invisibility_of_element_located(locator) 判断元素是否隐藏。
element_to_be_clickable(locator) 判断某元素是否可访问并且可启用,比如能够点击,若可以则返回元素本身,否则返回False
staleness_of(element) 判断某个元素是否不再附加于于DOM树中,不再附加的话返回True,依旧存在返回False
element_selection_state_to_be (element, is_selected) 判断某元素的选中状态是否与预期相同,相同则返回True,不同则返回False
element_located_selection_state_to_be(locator, is_selected) 判断某元素是否与预期相同,相同则返回True,不同则返回False,locator为一个(by, path)元祖
element_to_be_selected(element) 判断某元素是否被选中
element_located_to_be_selected(locator) 判断某元素是否被选,locator为一个(by, path)元祖
alert_is_present判断alert是否存在,若存在则切换到alert,若不存在则返回false
例如:
判断title方法title_is
获取页面title的方法可以直接用driver.title获取到,然后也可以把获取到的结果用做断言。
用到上面提到的expected_conditions模块里的title_is和title_contains两种方法
1.title_is源码分析:
class title_is(object):
"""An expectation for checking the title of a page.
title is the expected title, which must be an exact match
returns True if the title matches, false otherwise."""
'''翻译:检查页面的title与期望值是都完全一致,如果完全一致,返回Ture,否则返回Flase'''
def __init__(self, title):
self.title = title
def __call__(self, driver):
return self.title == driver.title
2.注释翻译:检查页面的title与期望值是都完全一致,如果完全一致,返回True,否则返回Flase
3.title_is()这个是一个class类型,里面有两个方法
4.__init__是初始化内容,参数是title,必填项
5.__call__是把实例变成一个对象,参数是driver,返回的是self.title == driver.title,布尔值
使用判断title:title_is()
1.首先导入expected_conditions模块
2.由于这个模块名称比较长,所以为了后续的调用方便,重新命名为EC了(有点像数据库里面多表查询时候重命名)
显式等待结合EC模块使用:
title = "百度一下,你就知道"
result = WebDriverWait(driver, 10).until(EC.title_is(title))
print(result)
# 6.2 定位百度首页搜索框,并输入文字
locator = ('id', 'kw')
search = WebDriverWait(driver, 10).until(EC.presence_of_element_located(locator),"元素定位失败")
search.send_keys("EC模块和显式等待配合使用")
# 5.关闭浏览器
time.sleep(5)
driver.quit()