1、简单元素操作
- clear() 清除文本,如果是一个文本输入框
- send_keys(*value) 在元素上模拟按键输入
- click() 单击元素
- submit() 用于提交表单,特别用于没提交按钮的情况
- assert 断言
- text 获取元素的文本
# baidu.py
from selenium import webdriver
from time import sleep
dr=webdriver.Chrome()
dr.get("https://www.baidu.com/")
'''
before_title = dr.title
print(before_title)
before_url = dr.current_url
print(before_url)
'''
'''
#通过点击百度一下按钮搜索
dr.find_element_by_id('kw').send_keys('selenium')
dr.find_element_by_id('su').click()
'''
#通过键盘“回车”搜索
search_key = dr.find_element_by_id('kw')
search_key.send_keys('selenium')
search_key.submit()
sleep(3) #休眠很必要,可以等浏览器反应刷新后,再获取title
# title、url有变化的情况
assert dr.title == "selenium_百度搜索"
assert "wd=selenium" in dr.current_url
# title、url不变化的情况,抓取文本的变化来区别
text3 = dr.find_element_by_xpath("//div/h3[@class='t c-gap-bottom-small']/a").text # 定位一个文本
print(text3)
titles = dr.find_elements_by_xpath("//div/h3/a") #获得一组文本元素
print(len(titles))
print(titles[0].text) #获取第几个元素
for i in titles:
print(i.text)
dr.quit()
'''
if dr.title != "selenium_百度搜索":
print('用例失败')
else:
print('用例通过')
if "wd=selenium" in dr.current_url : # url不适合做断言,适合匹配片段做断言
print('用例通过')
else:
print('用例失败')
'''
'''
after_title = dr.title
print(after_title)
after_url = dr.current_url
print(after_url)
'''
2、控制浏览器
- size 返回元素的尺寸
- get_attribute() 获取属性值
- is_displayed() 设置该元素用户是否可见
- refresh 刷新当前页面
# baidu2.py
from selenium import webdriver
from time import sleep
dr=webdriver.Chrome()
dr.get("https://www.baidu.com/")
dr.find_element_by_id('kw').send_keys('selenium')
# 获得输入框尺寸
size = dr.find_element_by_id('kw').size
print(size)
#返回元素的属性值,可以是id,name.tape或元素拥有的任意属性
attribute = dr.find_element_by_id('kw').get_attribute('name')
print(attribute)
#返回元素的结果是否可见,返回结果为True或False
displayed = dr.find_element_by_id('kw').is_displayed()
print(displayed)
dr.find_element_by_id('su').click()
# 点击百度图标,后退到百度首页
dr.find_element_by_xpath("//img[@title='到百度首页']").click()
sleep(2)
#刷新当前页面
dr.refresh()
dr.quit()
3、鼠标事件、警告框处理
ActionChains 类提供的鼠标操作的常用方法:
- perform() 执行所有 ActionChains 中存储的行为
- context_click() 右击
- double_click() 双击
- drag_and_drop() 拖动
- move_to_element() 鼠标悬停
警告框处理
- text: 返回 alert/confirm/prompt 中的文字信息。
- accept(): 接受现有警告框。
- dismiss(): 解散现有警告框。
- send_keys(keysToSend): 发送文本至警告框。 keysToSend: 将文本发送至警告框。
#判断一个定位元素是否唯一
settings = dr.find_elements_by_name('tj_settingicon')
print(len(settings))
'''
- 隐藏的功能,不能直接点击
- 通过switch_to.alert()方法获取当前页面上的警告框,并使用accept()方法接受警告框。
- Select类用于定位select标签。 select_by_value() 方法用于定位下接选项中的value值。
# baidu3.py
from selenium import webdriver
from time import sleep
#引入 ActionChains 类
from selenium.webdriver.common.action_chains import ActionChains # 悬停
from selenium.webdriver.support.select import Select #下拉框
dr=webdriver.Chrome()
dr.get("https://www.baidu.com/")
# 鼠标悬停至“设置” 链接
setting = dr.find_element_by_link_text("设置")
ActionChains(dr).move_to_element(setting).perform()
sleep(2)
# 打开搜索设置
dr.find_element_by_class_name("setpref").click() #若鼠标不悬停,直接点击“搜索设置”,会报错
sleep(2)
# 单选按钮
#dr.find_element_by_id("SL_1").click()
dr.find_element_by_id("SL_1").click()
sleep(2)
# 下拉框
select = dr.find_element_by_xpath("//select[@name='NR' and @id='nr']")
Select(select).select_by_value('20') # 可以直接操作select中value值
sleep(2)
# 保存设置
dr.find_element_by_class_name('prefpanelgo').click()
# 获取警告框
alert = dr.switch_to.alert()
print(alert.text) # 返回警告框文本信息
alert.accept() # 接收警告框
#alert.dismiss() # 取消警告框
dr.quit()
4、163邮箱
- 方式正确,定位不到元素时,确认是否嵌套在 iframe表单中
- switch_to.frame() 默认可以直接取表单的id 或name属性。
- switch_to.default_content() 退出所有表单,跳回最外层的页面
#163_mail.py
from selenium import webdriver
from time import sleep
dr = webdriver.Firefox()
dr.get("http://mail.163.com/")
sleep(2) #不等待,会报错
# 切换表单
#iframe有可用的id和name属性
dr.switch_to.frame("x-URS-iframe") # 默认可以直接取表单的id 或name属性
'''
# iframe没有可用的id和name属性
login_frame = dr.find_element_by_xpath("//iframe[@id='x-URS-iframe']") #先通过xpth定位到iframe
dr.switch_to.frame(login_frame) #再将定位对象传给switch_to.frame()方法
'''
dr.find_element_by_name("email").clear()
dr.find_element_by_name("email").send_keys("mayayasoft")
dr.find_element_by_name("password").clear()
dr.find_element_by_name("password").send_keys("youcan")
dr.find_element_by_id("dologin").click()
# 退出所有表单
dr.switch_to.default_content()
5、QQ注册
- current_window_handle:获得当前窗口句柄。
- window_handles:返回所有窗口的句柄到当前会话。
- switch_to.window():用于切换到相应的窗口,与上一节的switch_to.frame()类似,前者用于不同窗口的切换,后者用于不同表单之间的切换。
- dr.close() #关闭一个窗口。若只有一个窗口,就是关闭浏览器;有两个窗口,关闭当前窗口
- dr.quit() #关闭所有窗口
- 两个窗口切换
#QQ_register.py
from selenium import webdriver
from time import sleep
dr = webdriver.Chrome()
dr.get("https://mail.qq.com/")
dr.switch_to.frame("login_frame") # 切换表单
login_handle = dr.current_window_handle # 获取当前窗口句柄
dr.find_element_by_link_text("注册新帐号").click()
all_handle = dr.window_handles # 获取当前所有打开窗口的句柄
# 进入注册窗口
for handle in all_handle:
if handle != login_handle:
zhuce_handle = handle # 获取注册窗口
dr.switch_to.window(handle)
print(dr.title)
dr.find_element_by_id("nickname").send_keys("coin7653")
dr.find_element_by_id("password").send_keys("934895792asdfadf")
dr.find_element_by_id("phone").send_keys("13556765432d")
dr.close() #关闭注册窗口
#dr.quit() #关闭所有窗口
dr.switch_to.window(login_handle) # 关闭注册窗口后,切换到登录窗口
print(dr.title)
- 如果有三个窗口怎么办?
all_handle = dr.window_handles # 3个窗口
for handle in all_handle:
if handle != login_handle and handle != zhuce_handle:
three_handle = handle
6、设置元素等待
- 自己手写隐式等待
# wait_element_01.py
from selenium import webdriver
from time import sleep,ctime
from selenium.common.exceptions import NoSuchElementException
dr=webdriver.Chrome()
dr.get("https://www.baidu.com/")
# 元素超时
print("wait start:"+ str(ctime()))
for i in range(10):
try:
serach_input = dr.find_element_by_id('kw') # serach_input赋值是为了元素保持一致
except NoSuchElementException:
sleep(1) # 元素不存在,等待1s 后,再次开始循环
else:
break
else:
print("time out") # 循环10s 后,执行time out
print("wait end:" + str(ctime()))
serach_input.send_keys('selenium') # serach_input 保持一致
- implicitly_wait()方法来实现隐式等待
- 默认设置为0
- 建议都加上
- 但不是万能的,处理异步加载,这个方式就失效了,可以用显示等待
# wait_element_03.py
from selenium import webdriver
dr=webdriver.Chrome()
dr.get("https://www.baidu.com/")
#设置隐式等待为10秒
dr.implicitly_wait(10) # 每种定位方式都隐式等待10秒
dr.find_element_by_id('kw').send_keys('selenium')
dr.find_element_by_id('su....').click() # 超出10s没有定位到元素,抛出异常
- 显示等待
- -
WebDriverWait(driver, timeout, poll_frequency=0.5,
ignored_exceptions=None)
- driver :浏览器驱动。
- timeout :最长超时时间,默认以秒为单位。
- poll_frequency :检测的间隔(步长)时间,默认为0.5S。
- ignored_exceptions :超时后的异常信息,默认情况下抛NoSuchElementException异常。
until ( EC.presence_of_element_located((By.ID, “kw”) )
- until : 返回True或False
- EC.presence_of_element_located():元素定位
# wait_element_02.py
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.Firefox()
driver.get("http://www.baidu.com")
element = WebDriverWait(driver, 5, 0.5).until(
EC.presence_of_element_located((By.ID, "kw"))
)
element.send_keys('selenium')
driver.quit()
7、javascript,滚动条
window.scrollTo(左边距,上边距);
execute_script() :执行JavaScripts代码来移动滚动条的位置
from selenium import webdriver
from time import sleep
driver=webdriver.Firefox()
driver.get("http://www.baidu.com")
# 设置浏览器窗口大小
driver.set_window_size(800, 600)
driver.find_element_by_id("kw").send_keys("selenium")
driver.find_element_by_id("su").click()
sleep(2)
# 通过javascript设置浏览器窗口的滚动条位置
js="window.scrollTo(100,450);"
#js="window.scrollTo(10000,10000);" # 设置足够大,滚动条位于底部
driver.execute_script(js)
sleep(3)
driver.quit()
8、文件上传,元素隐藏
#upfile.html 文件上传
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8" />
<title>upload_file</title>
<link href="http://cdn.bootcss.com/bootstrap/3.3.0/css/bootstrap.min.css" rel="stylesheet" />
</head>
<body>
<div class="row-fluid">
<div class="span6 well" >
<h3>upload_file</h3>
<input type="file" name="file" />
</div>
</div>
</body>
<script src="http://cdn.bootcss.com/bootstrap/3.3.0/css/bootstrap.min.js"></script>
</html>
send_keys()实现上传
- 通过send_keys()指定本地文件路径的方式实现文件上传
- 文件上传的 type=”file”
# upfile2.py
from selenium import webdriver
import os
driver = webdriver.Firefox()
file_path = 'file:///' + os.path.abspath('upfile.html') # file:/// 打开本地文件方式。os.path.abspath()当前目录下文件
driver.get(file_path)
# 定位上传按钮,添加本地文件
driver.find_element_by_name("file").send_keys('D:\\upload_file.txt')
driver.quit()
元素不可见 <div class="row-fluid" style="display:none;">
# upfile.py
from selenium import webdriver
import os
driver = webdriver.Firefox()
file_path = 'file:///' + os.path.abspath('upfile.html')
driver.get(file_path)
# javaScript修改display的值显示元素可见
js = 'document.querySelectorAll("div")[0].style.display="block";'
driver.execute_script(js)
driver.quit()
AutoIt实现上传
AutoIt工具
- AutoIt Windows Info: 用于识别 Windows 控件信息。
- Compile Script to.exe:用于将 AutoIt 生成 exe 执行文件
- Run Script: 用于执行 AutoIt 脚本。
- SciTE Script Editor: 用于编写 AutoIt 脚本
- AutoIt脚本模板
- 通过autoit3操作windows窗口上传文件
- ControlFocus() 方 法 用 于 识 别 Window 窗 口title
- WinWait() 方 法 设 置 10 秒 钟 用 于 等 待 窗 口 的 显 示 。
- ControlSetText()方法用于向“文件名”输入框内输入本地上传文件的路径
- ControlClick()用于单击上传窗口中的“打开” 按钮。
;ControlFocus("title","text",controlID) Edit1=Edit instance 1
ControlFocus("选择要加载的文件", "","Edit1")
; Wait 10 seconds for the Upload window to appear
WinWait("[CLASS:#32770]","",10)
; Set the File name text on the Edit field
ControlSetText("选择要加载的文件", "", "Edit1", "D:\\upload_file.txt")
Sleep(2000)
; Click on the Open button
ControlClick("选择要加载的文件", "","Button1");
- 注意: 在运行时文件上传窗口应处于打开状态。
# autoit_upfile.au3脚本
;ControlFocus("title","text",controlID) Edit1=Edit instance 1
ControlFocus("文件上传", "","Edit1")
; Wait 10 seconds for the Upload window to appear
WinWait("[CLASS:#32770]","",10)
; Set the File name text on the Edit field
ControlSetText("文件上传", "", "Edit1", "C:\Users\yaya\Desktop\test.txt")
Sleep(2000)
; Click on the Open button
ControlClick("文件上传", "","Button1");
# upfile_au3.py
from selenium import webdriver
import os
driver = webdriver.Chrome()
file_path = 'file:///' + os.path.abspath('upfile.html') # file:/// 打开本地文件方式。os.path.abspath()当前目录下文件
driver.get(file_path)
# autoit实现上传
driver.find_element_by_name("file").click() # 单击打开上传窗口
os.system(r"E:/webdriver_api/autoit_upfile..exe") #调用autoit_upfile..exe程序
driver.quit()
缺点
不太推荐这种解决方案
- autoit脚本对于浏览器不通用。不同浏览器写不同的脚本。
- 通Python 调用的 exe 程序并不在 Python 的可控范围内。 换句话说, exe 执行多长时间, 执行是否出错, Python
程序都无法得知
9、文件下载
browser.download.folderList 设置成 0 代表下载到浏览器默认下载路径, 设置成 2 则可以保存到指定目录。
browser.download.dir 用于指定所下载文件的目录。 os.getcwd() 函数不需要传递参数, 用于返回当前的目录。
browser.helperApps.neverAsk.saveToDisk 指定要下载页面的 Content-type 值, “application/octet-stream” 为文件的类型。 HTTP Content-type 常用对照表: http://tool.oschina.net/commons
这些参数的设置可以通过在 Firefox 浏览器地址栏输入: about:config 进行设置
- 如果下载失败,设置一下滚动条
# download_file.py
from selenium import webdriver
import os
#文件的配置
fp = webdriver.FirefoxProfile() # 打开浏览器设置
fp.set_preference("browser.download.folderList",2) #下载到指定目录
fp.set_preference("browser.download.dir", os.getcwd()) #下载到当前路径
#下载文件的类型。通过Fiddler抓取,查询Content-type值
fp.set_preference("browser.helperApps.neverAsk.saveToDisk", "binary/octet-stream")
driver = webdriver.Firefox(firefox_profile=fp) #传入配置参数
#driver = webdriver.Firefox() # 弹窗提示下载目录
driver.get("http://pypi.Python.org/pypi/selenium")
driver.find_element_by_partial_link_text("selenium-3.7.0.tar.gz").click()