TAB 键自动补全
Alt+P 回退到上一次编辑的 Python 代码,Alt+ N 与之相反,可以前进至下一次编辑的代码
#coding=utf-8
from selenium import webdriver
driver=webdriver.Firefox()
driver.get("http://192.168.10.80/common/login")
driver.find_element_by_id("loginName").send_keys("HZ00305")
driver.find_element_by_id("loginPwd").send_keys("123456")
driver.find_element_by_id("loginCode").send_keys("CL30")
driver.find_element_by_id("loginBtn").click()
#coding=utf-8
from selenium import webdriver
driver=webdriver.Firefox()
driver.get("http://www.baidu.com")
driver.find_element_by_id("kw").send_keys("Selenium2")
driver.find_element_by_id("su").click()
driver.quit()
谷歌浏览器出现chromedriver.exe已停止工作(谷歌浏览器版本和驱动不符)
selenium之 chromedriver与chrome版本映射表(更新至v2.30)
http://blog.csdn.net/huilan_same/article/details/51896672
所有chromedriver均可在下面链接中下载到:
http://chromedriver.storage.googleapis.com/index.html
python
%s(string)只能打印字符串,如果想打印数字,那么就要使用%d(data)。
有时候我们并不知道自己要打印的是什么类型的数据,那么可以用%r来表示。
>>> name = "zhangsan"
>>> print "hello %s ,Nice to meet you!" %name
hello zhangsan ,Nice to meet you!
>>> age=27
>>> print "You are %d !" %age
>>> n = 100
>>> print "You print is %r ." %n You print is 100 .
>>> n = "abc"
>>> print "You print is %r ." %n You print is 'abc' .
*input矫情 (raw_input任何类型的输入都可以接收)
#coding=utf-8
n = input("Enter any content:")
print "Your input is %r " %n
Python当中,不区分单引号('')与双引号(""),也就是说单、双引号都可以表示一个字符串。可嵌套,不可交叉
注释 #
*if 语句
#coding=utf-8
results=72
if results >= 90:
print u'优秀'
elif results >= 70:
print u'良好'
elif results >= 60 :
print u'及格'
else:
print u'不及格'
*for语句
循环数字要借助range()函数。
for i in range(1,10):
print i
如果我只想打印1到10之间的奇数:
for i in range(1,10,2): print i
range(start,end,scan) range()函数,start表示开始位置,end表示结束位置,scan表示每一次循环的步长。
数组
字典
>>> zidian = {"username":"password",'man':'woman',1:2}
>>> zidian.keys()
['username', 1, 'man']
>>> zidian.values()
['password', 2, 'woman']
>>> zidian.items()
[('username', 'password'), (1, 2), ('man', 'woman')]
函数
def关键字定义函数
def add(a=1,b=2): return a+b
方法和类
class A():
def add(self,a,b):return a+b
count=A()
print count.add(3,5)
创建了一个A()类,在类下面创建了一个add()方法。
方法的创建同样使用关键字def,维一不同的是方法必须有一个且必须是第一个默认参数self,
但是这个参数不用传值。
class A:
def add(self,a,b):return a+b
class B(A):
def sub(self,a,b):return a-b
count = B()
print count.add(4,5)
用count变量来等于B类,因为B类继承了A类,所以B类自然也拥有了add()方法,所以count可以调用add()方法。
模组(包/模块/头文件)
在Python语言中通过from...import...的方式引用模块
import time
print time.ctime()
time 模块下面有一个ctime()方法获得当前时间,如果确定了只会用到time下面的ctime()方法,那么可以这样:
from time import ctime
print ctime()
有时候我们还可能会用到time模块下面的sleep()休眠方法
一次性把time模块下面的所有方法都引入进来:
#coding=utf-8
from time import *
print ctime()
print "休息一两秒"
sleep(2)
print ctime()
异常
执行open()一个不存在的文件时会抛IOError异常
try:
open("abc.txt","r")
except IOError:
print "异常了!"
抛的是个NameError类型的错误
try:
print aa
except NameError:
print "这是一个name异常!"
在Python中所有的异常类都继承Exception,所以我们可以使用它来接收所有的异常。
try:
open("abc.txt",'r')
print aa
except Exception:
print "异常了!"
Exception 同样也继承 BaseException
try:
open("abc.txt",'r')
print aa
except BaseException:
print "异常了!"
msg 变量用于接收异常信息,通过 print 将其打印出来
try:
open("aaa.txt","r")
print aa
except BaseException,msg:
print msg
异常 描述
BaseException 新的所有异常类的基类
Exception 所有异常类的基类,但继承 BaseException 类
AssertionError assert 语句失败
AttributeError 试图访问一个对象没有属性
IOError 输入输出异常,试图打一个不存的文件(包括其它情况)时引起
NameError 使用一个还未赋值对象的变量
IndexError 在使用序列中不存在的所引进引发
IndentationError 语法错误,代码没有正确的对齐
KeyboardInterrupt Ctrl+C 被按下,程序被强行终止
TypeError 传入的对象类型与要求不符
SyntaxError Python 代码逻辑语法出错,不能执行
从定位元素开始
webdriver 提供了八种元素定位方法:
id
name
class name
tag name
link text
partial link text
xpath
css selector
在 Python 语言中对应的定位方法如下:
find_element_by_id()
find_element_by_name()
find_element_by_class_name()
find_element_by_tag_name()
find_element_by_link_text()
find_element_by_partial_link_text()
find_element_by_xpath()
find_element_by_css_selector()
控制浏览器器窗口大小
set_window_size
#coding=utf-8
from selenium import webdriver
driver = webdriver.Firefox()
driver.get("http://m.mail.10086.cn")
#参数数字为像素点
print "设置浏览器宽480、高800显示"
driver.set_window_size(480, 800)
driver.quit()
希望浏览器在全屏幕模式下执行,可以使用 maximize_window()方法,
用法与 set_window_size() 相同,但它不需要传参
driver.maximize_window()最大化浏览器
控制浏览器后退、前进
back()和 forward()
#coding=utf-8
from selenium import webdriver
driver = webdriver.Firefox()
#访问百度首页
first_url= 'http://www.baidu.com'
print "now access %s" %(first_url)
driver.get(first_url)
#访问新闻页面
second_url='http://news.baidu.com'
print "now access %s" %(second_url)
driver.get(second_url)
#返回(后退)到百度首页
print "back to %s "%(first_url)
driver.back()
#前进到新闻页
print "forward to %s"%(second_url)
driver.forward()
driver.quit()
#coding=utf-8
from selenium import webdriver
driver=webdriver.Chrome()
A="http://www.baidu.com"
driver.get(A)
print "now access %s"%A
B="http://news.baidu.com"
driver.get(B)
print "now access %s"%B
driver.back()
driver.forward()
driver.quit()
简单元素操作
clear() 清除文本,如果是一个文件输入框
send_keys(*value) 在元素上模拟按键输入
click() 单击元素
WebElement 接口常用方法
submit
submit()方法用于提交表单,特别用于没提交按钮的情况,相当于“回车”操作
#coding=utf-8
from selenium import webdriver
driver = webdriver.Firefox()
driver.get("http://www.youdao.com")
driver.find_element_by_id('query').send_keys('hello')
#提交输入框的内容
driver.find_element_by_id('query').submit()
driver.quit()
size 返回元素的尺寸。
text 获取元素的文本。
get_attribute(name) 获得属性值。
is_displayed() 设置该元素是否用户可见。
#coding=utf-8
from selenium import webdriver
driver = webdriver.Firefox()
driver.get("http://www.baidu.com")
#获得输入框的尺寸
size=driver.find_element_by_id('kw').size
print size
#返回百度页面底部备案信息
text=driver.find_element_by_id("cp").text
print text
#返回元素的属性值,可以是id、name、type或元素拥有的其它任意属性
attribute=driver.find_element_by_id("kw").get_attribute('type')
print attribute
#返回元素的结果是否可见,返回结果为True或False
result=driver.find_element_by_id("kw").is_displayed()
print result driver.quit()
鼠标事件
ActionChains 类提供的鼠标操作的常用方法:
perform() 执行所有ActionChains中存储的行为
context_click() 右击
double_click() 双击
drag_and_drop() 拖动
move_to_element() 鼠标悬停
鼠标右击操作
from selenium import webdriver
#引入ActionChains类
from selenium.webdriver.common.action_chains import ActionChains
driver = webdriver.Firefox()
driver.get("http://yunpan.360.cn")
....
#定位到要右击的元素
right_click =driver.find_element_by_id("xx")
#对定位到的元素执行鼠标右键操作
ActionChains(driver).context_click(right_click).perform()
....
fromselenium.webdriver import ActionChains
对于 ActionChains 类下面的方法,在使用之前需要先将模块导入。
ActionChains(driver)
调用 ActionChains()方法,在使用将浏览器驱动 driver 作为参数传入。
context_click(right_click)
context_click()方法用于模拟鼠标右键事件,在调用时需要传入右键的元素。
perform()
执行所有 ActionChains 中存储的行为,可以理解成是对整个操作事件的提交动作
鼠标悬停
move_to_element()方法可以模拟鼠标悬停的动作,其用法与 context_click()相同
#coding=utf-8
from selenium import webdriver
#引入ActionChains类
from selenium.webdriver.common.action_chains import ActionChains
driver = webdriver.Firefox()
driver.get("http://www.baidu.com")
above =driver.find_element_by_link_text("设置")
ActionChains(driver).move_to_element(above).perform()
鼠标双击操作
double_click(on_element)方法用于模拟鼠标双击操作,用法同上
……
from selenium import webdriver
#引入ActionChains类
from selenium.webdriver.common.action_chains import ActionChains
driver = webdriver.Firefox()
....
#定位到要悬停的元素
double_click = driver.find_element_by_id("xx")
#对定位到的元素执行双击操作
ActionChains(driver).double_click(double_click).perform()
....
鼠标推放拖拽操作
drag_and_drop(source,target)在源元素上按下鼠标左键,然后移动到目标元素上释放。
source: 鼠标拖动的源元素。
target: 鼠标释放的目标元素
……
from selenium import webdriver
#引入ActionChains类
from selenium.webdriver.common.action_chains import ActionChains
driver = webdriver.Firefox()
....
#定位元素的源位置
element = driver.find_element_by_name("xxx")
#定位元素要移动到的目标位置
target = driver.find_element_by_name("xxx")
#执行元素的拖放操作
ActionChains(driver).drag_and_drop(element,target).perform()
....
键盘事件
#coding=utf-8
from selenium import webdriver
#引入Keys模块
from selenium.webdriver.common.keys import Keys
driver = webdriver.Firefox()
driver.get("http://www.baidu.com")
#输入框输入内容
driver.find_element_by_id("kw").send_keys("seleniumm")
#删除多输入的一个m
driver.find_element_by_id("kw").send_keys(Keys.BACK_SPACE)
#输入空格键+“教程”
driver.find_element_by_id("kw").send_keys(Keys.SPACE)
driver.find_element_by_id("kw").send_keys(u"教程")
#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')
#ctrl+v 粘贴内容到输入框
driver.find_element_by_id("kw").send_keys(Keys.CONTROL,'v')
#通过回车键盘来代替点击操作
driver.find_element_by_id("su").send_keys(Keys.ENTER)
driver.quit()
fromselenium.webdriver.common.keys import Keys
在使用键盘按键方法前需要先导入 keys 类包
下面经常使用到的键盘操作:
send_keys(Keys.BACK_SPACE) 删除键(BackSpace)
send_keys(Keys.SPACE) 空格键(Space)
send_keys(Keys.TAB) 制表键(Tab)
send_keys(Keys.ESCAPE) 回退键(Esc)
send_keys(Keys.ENTER) 回车键(Enter)
send_keys(Keys.CONTROL,'a') 全选(Ctrl+A)
send_keys(Keys.CONTROL,'c') 复制(Ctrl+C)
send_keys(Keys.CONTROL,'x') 剪切(Ctrl+X)
send_keys(Keys.CONTROL,'v') 粘贴(Ctrl+V)
send_keys(Keys.F1) 键盘 F1
……
send_keys(Keys.F12) 键盘 F12
获得验证信息
#coding=utf-8
from selenium import webdriver
driver = webdriver.Firefox()
driver.get("http://www.126.com")
print 'Before login================'
#打印当前页面title
title = driver.title
print title
#打印当前页面URL
now_url = driver.current_url
print now_url
#执行邮箱登录
driver.find_element_by_id("idInput").clear()
driver.find_element_by_id("idInput").send_keys("username")
driver.find_element_by_id("pwdInput").clear()
driver.find_element_by_id("pwdInput").send_keys("password")
driver.find_element_by_id("loginBtn").click()
print 'After login================'
#再次打印当前页面title
title = driver.title
print title
#打印当前页面URL
now_url = driver.current_url
print now_url
#获得登录的用户名
user = driver.find_element_by_id('spnUid').text
print user
driver.quit()
driver.title
title 用于获得当前页面的标题。
driver.current_url
current_url 用户获得当页面的 URL。
设置元素等待
显式等待
#coding=utf-8
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()
WebDriverWait()
由 webdirver 提供的等待方法。在设置时间内,默认每隔一段时间检测一次当前页面元素是否存
在,如果超过设置时间检测不到则抛出异常。具体格式如下:
WebDriverWait(driver, timeout, poll_frequency=0.5, ignored_exceptions=None)
driver -WebDriver 的驱动程序(Ie, Firefox,Chrome 等)
timeout - 最长超时时间,默认以秒为单位
poll_frequency -休眠时间的间隔(步长)时间,默认为 0.5 秒
gnored_exceptions -超时后的异常信息,默认情况下抛 NoSuchElementException 异常
WebDriverWait() 一般由 until()(或 until_not())方法配合使用
Expected Conditions
在本例中,我们在使用 expected_conditions 类时对其时行了重命名,通过 as 关键字对其重命名为 EC,
并调用 presence_of_element_located()判断元素是否存在
expected_conditions 类提供一些预期条件的实现。
title_is 用于判断标题是否 xx。
title_contains 用于判断标题是否包含 xx 信息。
presence_of_element_located 元素是否存在。
visibility_of_element_located 元素是否可见。
visibility_of 是否可见
presence_of_all_elements_located 判断一组元素的是否存在
text_to_be_present_in_element 判断元素是否有 xx 文本信息
text_to_be_present_in_element_value 判断元素值是否有 xx 文本信息
frame_to_be_available_and_switch_to_it 表单是否可用,并切换到该表单。
invisibility_of_element_located 判断元素是否隐藏
element_to_be_clickable 判断元素是否点击,它处于可见和启动状态
staleness_of 等到一个元素不再是依附于 DOM。
element_to_be_selected 被选中的元素。
element_located_to_be_selected 一个期望的元素位于被选中。
element_selection_state_to_be 一个期望检查如果给定的元素被选中。
element_located_selection_state_to_be 期望找到一个元素并检查是否选择状态
alert_is_present 预期一个警告信息
隐式等待
隐式等待是通过一定的时长等待页面所有元素加载完成。哪果超出了设置的时长元素还没有被加载则抛出
NoSuchElementException 异常。
WebDriver 提供了 implicitly_wait()方法来实现隐式等待,默认设置为 0。
#coding=utf-8
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
driver = webdriver.Firefox()
driver.implicitly_wait(10)
driver.get("http://www.baidu.com")
input_ = driver.find_element_by_id("kw22")
input_.send_keys('selenium')
driver.quit()
在上面的例子中,显然百度输入框的定位 id=kw22 是有误的,那么在超出 10 秒后将抛出异常。
sleep 休眠方法
#coding=utf-8
from selenium import webdriver
from time import sleep
driver = webdriver.Firefox()
driver.get("http://www.baidu.com")
sleep(2)
driver.find_element_by_id("kw").send_keys("webdriver")
driver.find_element_by_id("su").click()
sleep(3)
driver.quit()
★正则表达式
在python正则表达式语法中,Python中字符串前面加上 r 表示原生字符串,
用\w表示匹配字母数字及下划线。re模块下findall方法返回的是一个匹配子字符串的列表。
# coding=utf-8
from selenium import webdriver
import re
driver = webdriver.Chrome()
driver.maximize_window()
driver.implicitly_wait(6)
driver.get("http://home.baidu.com/contact.html")
# 得到页面源代码
doc = driver.page_source
emails = re.findall(r'[\w]+@[\w\.-]+',doc) # 利用正则,找出 xxx@xxx.xxx 的字段,保存到emails列表
# 循环打印匹配的邮箱
for email in emails:
print (email)
1. 查看页面的源代码,在Selenium中有driver.page_source 这个方法得到
2. Python中利用正则,需要导入re模块
3. for email in emails :
print email
driver.refresh()刷新当前页面
打开一个新的tab
ctrl+ t
from selenium.webdriver.common.keys import Keys
。。。
driver.find_element_by_tag_name('body').send_keys(Keys.CONTROL + 't')
。。
?send_keys(Keys.CONTROL,'t')
定位一组元素
#coding=utf-8
from selenium import webdriver
import os
driver = webdriver.Firefox()
file_path = 'file:///' + os.path.abspath('checkbox.html')
driver.get(file_path)
# 选择页面上所有的tag name为input的元素
inputs = driver.find_elements_by_tag_name('input')
#然后从中过滤出tpye为checkbox的元素,单击勾选
for i in inputs:
if i.get_attribute('type') == 'checkbox':
i.click()
driver.quit()
因为通过浏览器打开的是一个本地的 html 文件,所以需要用到 Python 的 os 模块,
path.abspath()方法用于获取当前路径下的文件。
checkbox/radio复选框/单选框
find_elements是不能直接点击的,它是复数的,所以只能先获取到所有的checkbox对象,然后通过for循环去一个个点击操作
多表单切换
switch_to_frame() 方法
#coding=utf-8
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
driver = webdriver.Chrome()
driver.get("https://mail.qq.com/")
driver.switch_to_frame("login_frame")
a=driver.find_element_by_link_text("帐号密码登录")
ActionChains(driver).click(a).perform()
switch_to_frame()默认可以直接去表单的id或name属性进行切换,如果没有id/name,
可以通过xpath定位到iframe,再将定位对象传给switch_to_frame()方法
......
xf = driver.find_element_by_xpath('//*[@class="if"]')
driver.switch_to_frame(xf)
......
driver.switch_to_default_content()
可以通过 switch_to_default_content()方法返回上一层表单
该方法不用指定某个表单的返回,默认对应与它最近的 switch_to_frame()方法
嵌套frame的操作(switch_to.parent_frame())
html>
<iframe id="frame1">
<iframe id="frame2" / >
</iframe>
</html>
从主文档切到frame2,一层层切进去
driver.switch_to.frame("frame1")
driver.switch_to.frame("frame2")
从frame2再切回frame1 selenium给我们提供了一个方法能够从子frame切回到父frame,而不用我们切回主文档再切进来。
driver.switch_to.parent_frame() # 如果当前已是主文档,则无效果
所以只要善用以下三个方法,遇到frame分分钟搞定:
driver.switch_to.frame(reference)
driver.switch_to.parent_frame()
driver.switch_to.default_content()
多窗口切换
switch_to_window()
#coding=utf-8
from selenium import webdriver
driver = webdriver.Firefox()
driver.implicitly_wait(10)
driver.get("http://www.baidu.com")
#获得百度搜索窗口句柄
sreach_windows= driver.current_window_handle
driver.find_element_by_link_text(u'登录').click()
driver.find_element_by_link_text(u"立即注册").click() #获得当前所有打开的窗口的句柄
all_handles = driver.window_handles
#进入注册窗口
for handle in all_handles:
if handle != sreach_windows:
driver.switch_to_window(handle)
print 'now register window!'
driver.find_element_by_name("account").send_keys('username')
driver.find_element_by_name('password').send_keys('password')
#……
#进入搜索窗口
for handle in all_handles:
if handle == sreach_windows:
driver.switch_to_window(handle)
print 'now sreach window!'
driver.find_element_by_id('TANGRAM__PSP_2__closeBtn').click()
driver.find_element_by_id("kw").send_keys("selenium")
driver.find_element_by_id("su").click()
time.sleep(5)
driver.quit()
先打开百度首页,通过 current_window_handle 获得当前窗口的句柄,并给变量 sreach_handle。
接着打开登录弹窗,在登录窗口上点击“立即注册”从而打开新的注册窗口。通过 window_handles
获得当前打开的所窗口的句柄,赋值给变量 all_handles。
第一个循环遍历 all_handles,如果 handle 不等于 sreach_handle,那么一定是注册窗口,
因为脚本执行只打开的两个窗口。所以,通过 switch_to_window()切换到注册页进行注册操作。
第二个循环类似,不过这一次判断如果 handle 等于 sreach_handle,那么切换到百度搜索页,
关闭之前打开的登录弹窗,然后时行搜索操作。
current_window_handle 获得当前窗口句柄
window_handles 返回的所有窗口的句柄到当前会话
switch_to_window() 用于切换到相应的窗口,与上一节的 switch_to_frame() 是类似,
前者用于不同窗口的切换,后者用于不同表单之间的切换
警告框处理
switch_to_alert()
在 WebDriver 中处理 JavaScript 所生成的 alert、confirm 以及 prompt 是很简单的。
具体做法是使用 switch_to_alert()方法定位到 alert/confirm/prompt。
然后使用 text/accept/dismiss/send_keys 按需进行操做。
#coding=utf-8
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
driver = webdriver.Firefox()
driver.implicitly_wait(10)
driver.get('http://www.baidu.com')
#鼠标悬停相“设置”链接
link = driver.find_element_by_link_text(u'设置')
ActionChains(driver).move_to_element(link).perform()
#打开搜索设置
driver.find_element_by_class_name('setpref').click()
#保存设置
driver.find_element_by_css_selector('#gxszButton > a.prefpanelgo').click()
#接收弹窗
driver.switch_to_alert().accept()
driver.quit()
text 返回 alert/confirm/prompt 中的文字信息。
accept 点击确认按钮。
dismiss 点击取消按钮,如果有的话。
send_keys 输入值,这个 alert\confirm 没有对话框就不能用了,不然会报错。
通过 switch_to_alert()方法获取当前页上的警告框,accept()接受警告框
上传文件
send_keys实现上传
#coding=utf-8
from selenium import webdriver
import os
driver = webdriver.Firefox()
#打开上传功能页面
file_path = 'file:///' + os.path.abspath('upfile.html')
driver.get(file_path)
#定位上传按钮,添加本地文件
driver.find_element_by_name("file").send_keys('D:\\upload_file.txt')
driver.quit()
通过 Python 的 os 模块的 system()方法可以调用 exe 程序并执行。
AutoIt 实现上传
....
下载文件
#coding=utf-8
from selenium import webdriver
import os
fp = webdriver.FirefoxProfile()
fp.set_preference("browser.download.folderList",2)
fp.set_preference("browser.download.manager.showWhenStarting",False)
fp.set_preference("browser.download.dir", os.getcwd())
fp.set_preference("browser.helperApps.neverAsk.saveToDisk",
"application/octet-stream") #下载文件的类型
driver = webdriver.Firefox(firefox_profile=fp)
driver.get("http://pypi.Python.org/pypi/selenium")
driver.find_element_by_partial_link_text("selenium-2").click()
为了让 FireFox 让浏览器能实现文件的下载,我们需要通过 FirefoxProfile() 对其参数做一个设置。
browser.download.folderList
设置成 0 代表下载到浏览器默认下载路径;设置成 2 则可以保存到指定目录。
browser.download.manager.showWhenStarting
是否显示开始,Ture 为显示,Flase 为不显示。
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 进行设置
操作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 信息下面通过 get_cookies()来获取当前浏览器的 cookie 信息。
#coding=utf-8
from selenium import webdriver
import time
driver = webdriver.Firefox()
driver.get("http://www.youdao.com")
#向cookie的name 和value添加会话信息。
driver.add_cookie({'name':'key-aaaaaaa', 'value':'value-bbbbbb'})
#遍历cookies中的name 和value信息打印,当然还有上面添加的信息
for cookie in driver.get_cookies():
print "%s -> %s" % (cookie['name'], cookie['value'])
driver.quit()
delete_cookie() 和 delete_all_cookies() 的使用也很简单,
前者通过 name 值到一个特定的 cookie 将其删除,后者直接删除浏览器中的所有 cookies()信息。
操作浏览器上的滚动条
#coding=utf-8
from selenium import webdriver import time
#访问百度
driver=webdriver.Firefox()
driver.get("http://www.baidu.com")
#搜索
driver.find_element_by_id("kw").send_keys("selenium")
driver.find_element_by_id("su").click()
time.sleep(3)
#将页面滚动条拖到底部
js="var q=document.documentElement.scrollTop=10000"
driver.execute_script(js)
time.sleep(3)
#将滚动条移动到页面的顶部
js_="var q=document.documentElement.scrollTop=0"
driver.execute_script(js_)
time.sleep(3)
driver.quit()
JavaScript 代码控制滚动条在任意位置,需要改变的就是 scrollTop 的值。
通过 execute_script()方法来执行
窗口截图
get_screenshot_as_file()
#coding=utf-8
from selenium import webdriver
driver = webdriver.Chrome()
driver.get('http://www.baidu.com')
try:
driver.find_element_by_id('kw_error').send_key('selenium')
driver.find_element_by_id('su').click()
except :
driver.get_screenshot_as_file("D:\\baidu_error.jpg")
driver.quit()
在本例中用到了 Python 的异常处理,要本例中百度输入框的 id=kw_error 会定位不到元素,
那么 try 就会捕捉到这个异常,从而执行 except,在 except 中执行 get_screenshot_as_file()
对当前窗口进行截图,这里需要指定图片的保存路径及文件名,并且关闭当前驱动。
脚本运行完成打开 D 盘就可以找到 baidu_error.jpg 图片文件了
关闭窗口
close()
在前页的例子中我们一直在使用 quit()方法,其含义为退出相关的驱动程序和关闭所有窗口。
除此之外 WebDriver 还提供了 close()方法,用于关闭当前窗口。
当脚本在执行时打开了多个窗口,如本章的第 10 小节多窗口的处理,
这个时候只能关闭其中的某一个窗口,这个时候就需要使用 close()来关闭。
验证码的处理
1、去掉验证码
2、设置万能码
#coding=utf-8
import random
#生成一个1000到9999之间的随机整数
verify = random.randint(1000,9999)
print u"生成的随机数:%d " %verify
number = input(u"请输入随机数:")
print number
if number == verify:
print u"登录成功!!"
elif number == 132741:
print u"登录成功!!"
else:
print u"验证码输入有误!"
randint()用于生成随机数,设置随机数的范围为1000~9999之间
3、验证码识别技术
例如可以通过 Python-tesseract 来识别图片验证码,Python-tesseract 是光学字符识别
Tesseract OCR 引擎的 Python 封装类。能够读取任何常规的图片文件(JPG, GIF ,PNG , TIFF 等)。
不过,目前市面上的验证码形式繁多,目前任何一种验证码识别技术,识别率都不是100% 。
4、记录 cookie
模块化
对登录和退出进行模块的封装
#coding=utf-8
from selenium import webdriver
#登陆
def login():
driver.find_element_by_id("idInput").clear()
driver.find_element_by_id("idInput").send_keys("username")
driver.find_element_by_id("pwdInput").clear()
driver.find_element_by_id("pwdInput").send_keys("password")
driver.find_element_by_id("loginBtn").click()
#退出
def logout():
driver.find_element_by_link_text(u"退出").click()
driver.quit()
driver = webdriver.Firefox()
driver.implicitly_wait(10)
driver.get("http://www.126.com")
login() #调用登陆模块 #收信、写信、删除信件等操作
logout() #调用退出模块
将登录的操作步骤封装到login()函数中,把退出的操作封装到logout()函数中,
对于用例本身只用调用这两个函数即可
只是把步骤封装成函数并没简便太多,我们需要将其放到单独的文件中供其它用例调用。
#coding=utf-8
#登陆
def login(driver):
driver.find_element_by_id("idInput").clear()
driver.find_element_by_id("idInput").send_keys("username")
driver.find_element_by_id("pwdInput").clear()
driver.find_element_by_id("pwdInput").send_keys("password")
driver.find_element_by_id("loginBtn").click()
#退出
def logout(driver):
driver.find_element_by_link_text(u"退出").click()
driver.quit()
当函数被独立到单独的文件中时做了一点调整,主要在函数的传参上,
因为函数内部的操作需要使用driver,但是driver并没有在此文件中定义,
所以需要调用的用例传递driver给调用的函数。
#coding=utf-8
from selenium import webdriver import public
driver = webdriver.Firefox()
driver.implicitly_wait(10)
driver.get("http://www.126.com")
#调用登陆模块
public.login(driver)
#收信、写信、删除信件等操作
#调用退出模块
public.logout(driver)
首先,需要导入当前目录中的public.py,在需要的位置调用文件中的login()和和logout()函数。
这样对于每个用例来说就简便了许多,也更易于维护。
数据驱动实例
1.邮箱登录
#coding=utf-8
from selenium import webdriver
driver = webdriver.Firefox()
driver.implicitly_wait(10)
driver.get("http://www.126.com")
class Account(object):
"""docstring for Account"""
def __init__(self,username ='', password =''):
self.username = username
self.password = password
def do_login_as(user_info):
driver.find_element_by_id("idInput").clear()
driver.find_element_by_id("idInput").send_keys(user_info.username)
driver.find_element_by_id("pwdInput").clear()
driver.find_element_by_id("pwdInput").send_keys(user_info.password)
driver.find_element_by_id("loginBtn").click()
#实例化登陆信息
admin = Account(username='admin',password='123')
guset = Account(username='guset',password='321')
#调用登陆函数
do_login_as(admin)
do_login_as(guset)
首先创建表Account类,对用户名密码进行初始化设置,紧接着创建do_login_as()函数用于实现用户的
登录操作,它需要一个user_info参数用于接收用户的登录信息。取user_info中的username输入到
用户名输入框,取user_info中的password输入密码输入框。
紧接着下面的操作就是通过调用Account实例化用户admin和guset,进行个性化的参数设置。
最后分别调用do_login_as()函数来实现不同用户的登录。
2.百度搜索
创建info.txt文件,每一行写上需要搜索的“关键字”
【info.txt】
selenium
webdriver
Python
#coding=utf-8
from selenium import webdriver
file_info = open('info.txt','r')
values = file_info.readlines()
file_info.close()
for serch in values:
driver = webdriver.Firefox()
driver.implicitly_wait(10)
driver.get("http://www.baidu.com")
driver.find_element_by_id('kw').send_keys(serch)
driver.find_element_by_id('su').click()
driver.quit()
通过open()方法以读的方式打开info.txt文件
通过readlines()方法获取文件中所有行的数据,并赋值给变量
通过close()关闭文件
3.读取txt文件
read() 读取整个文件。
readline() 读取一行数据。
readlines() 读取所有行的数据。
user_info.txt
(zhangsan,123
lisi,456
wangwu,789)
#coding=utf-8
from selenium import webdriver
user_file = open('user_info.txt','r')
values = user_file.readlines()
user_file.close()
for serch in values:
username =serch.split(',')[0]
print username
password =serch.split(',')[1]
print password
使用split()进行拆分,它可将一个字符符串通过某一符号拆分成左右两部分,这里逗号(,)为分割点
用[0]可以取到左半部分的字符串,[1]可以取到右半部分的字符串
例子:
#coding=utf-8
from selenium import webdriver
a=open('aa.txt','r')
values=a.readlines()
a.close()
for b in values:
c=b.split(',')[0]
d=b.split(',')[1]
driver=webdriver.Chrome()
driver.get('http://192.168.10.80/common/login')
driver.find_element_by_id("loginName").send_keys(c)
driver.find_element_by_id("loginPwd").send_keys(d)
driver.find_element_by_id("loginCode").send_keys("CL31")
driver.find_element_by_id("loginBtn").click()
4.读取CSV文件
#coding=utf-8
import csv #导入 csv 包 excel(xlrd)
#读取本地 CSV 文件
my_file='info.csv'
date=csv.reader(file(my_file,'rb'))
#循环输出每一行信息
for user in date:
print user[1]
导入csv模块,通过reader()方法读取csv文件
5.读取xml文件
#coding=utf-8
import xml.dom.minidom
#打开xml文档
dom=xml.dom.minidom.parse('info.xml')
#得到文档元素对象
root=dom.documentElement
print root.nodeName
print root.nodeValue
print root.nodeType
print root.ELEMENT_NODE
xml.dom.minidom
xml.dom.minidom 模块被用来处理xml文件,所以要先引入。
parse()
xml.dom.minidom.parse() 用于打开一个xml文件,并将这个文件对象dom变量。
documentElement
documentElement 用于得到dom对象的文档元素,并把获得的对象给root
每一个结点都有它的nodeName,nodeValue,nodeType属性。
nodeName 为结点名字。
nodeValue 是结点的值,只对文本结点有效。
nodeType 是结点的类型。
Selenium IDE
Ctrl+Alt+S 打开窗口
Action 有两种形式:action和actionAndWait
action会立即执行,而actionAndWait会假设需要较长时间才能得到该action的相响,
而作出等待,open则是会自动处理等待时间。
Title ,获取页面的标题。
Value 获得元素的值。
Text 获得元素的文本信息。
Table 获得元素的标签。
ElementPresent 获得当前元素。
验证(verify)和断言(assert)
区别:
断言失败,脚本终止继续执行
验证失败,脚本还将继续执行
等待(waitFor)和变量(store)
Selenium IDE中提供了pause来设置固定的休眠时间,waitFor在一定时间内等待某一元素显示
waitFor如果Value为空,默认为60秒。
store用于定义变量
可把页面中获取到的标题、文本信息和元素定义成变理title、text和element
get_screenshot_as_file
窗口截图
driver.maximize_window
窗口最大化
TAB 键自动补全
Alt+P 回退到上一次编辑的 Python 代码,Alt+ N 与之相反,可以前进至下一次编辑的代码
#coding=utf-8
from selenium import webdriver
driver=webdriver.Firefox()
driver.get("http://192.168.10.80/common/login")
driver.find_element_by_id("loginName").send_keys("HZ00305")
driver.find_element_by_id("loginPwd").send_keys("123456")
driver.find_element_by_id("loginCode").send_keys("CL30")
driver.find_element_by_id("loginBtn").click()
#coding=utf-8
from selenium import webdriver
driver=webdriver.Firefox()
driver.get("http://www.baidu.com")
driver.find_element_by_id("kw").send_keys("Selenium2")
driver.find_element_by_id("su").click()
driver.quit()
谷歌浏览器出现chromedriver.exe已停止工作(谷歌浏览器版本和驱动不符)
selenium之 chromedriver与chrome版本映射表(更新至v2.30)
http://blog.csdn.net/huilan_same/article/details/51896672
所有chromedriver均可在下面链接中下载到:
http://chromedriver.storage.googleapis.com/index.html
python
%s(string)只能打印字符串,如果想打印数字,那么就要使用%d(data)。
有时候我们并不知道自己要打印的是什么类型的数据,那么可以用%r来表示。
>>> name = "zhangsan"
>>> print "hello %s ,Nice to meet you!" %name
hello zhangsan ,Nice to meet you!
>>> age=27
>>> print "You are %d !" %age
>>> n = 100
>>> print "You print is %r ." %n You print is 100 .
>>> n = "abc"
>>> print "You print is %r ." %n You print is 'abc' .
*input矫情 (raw_input任何类型的输入都可以接收)
#coding=utf-8
n = input("Enter any content:")
print "Your input is %r " %n
Python当中,不区分单引号('')与双引号(""),也就是说单、双引号都可以表示一个字符串。可嵌套,不可交叉
注释 #
*if 语句
#coding=utf-8
results=72
if results >= 90:
print u'优秀'
elif results >= 70:
print u'良好'
elif results >= 60 :
print u'及格'
else:
print u'不及格'
*for语句
循环数字要借助range()函数。
for i in range(1,10):
print i
如果我只想打印1到10之间的奇数:
for i in range(1,10,2): print i
range(start,end,scan) range()函数,start表示开始位置,end表示结束位置,scan表示每一次循环的步长。
数组
字典
>>> zidian = {"username":"password",'man':'woman',1:2}
>>> zidian.keys()
['username', 1, 'man']
>>> zidian.values()
['password', 2, 'woman']
>>> zidian.items()
[('username', 'password'), (1, 2), ('man', 'woman')]
函数
def关键字定义函数
def add(a=1,b=2): return a+b
方法和类
class A():
def add(self,a,b):return a+b
count=A()
print count.add(3,5)
创建了一个A()类,在类下面创建了一个add()方法。
方法的创建同样使用关键字def,维一不同的是方法必须有一个且必须是第一个默认参数self,
但是这个参数不用传值。
class A:
def add(self,a,b):return a+b
class B(A):
def sub(self,a,b):return a-b
count = B()
print count.add(4,5)
用count变量来等于B类,因为B类继承了A类,所以B类自然也拥有了add()方法,所以count可以调用add()方法。
模组(包/模块/头文件)
在Python语言中通过from...import...的方式引用模块
import time
print time.ctime()
time 模块下面有一个ctime()方法获得当前时间,如果确定了只会用到time下面的ctime()方法,那么可以这样:
from time import ctime
print ctime()
有时候我们还可能会用到time模块下面的sleep()休眠方法
一次性把time模块下面的所有方法都引入进来:
#coding=utf-8
from time import *
print ctime()
print "休息一两秒"
sleep(2)
print ctime()
异常
执行open()一个不存在的文件时会抛IOError异常
try:
open("abc.txt","r")
except IOError:
print "异常了!"
抛的是个NameError类型的错误
try:
print aa
except NameError:
print "这是一个name异常!"
在Python中所有的异常类都继承Exception,所以我们可以使用它来接收所有的异常。
try:
open("abc.txt",'r')
print aa
except Exception:
print "异常了!"
Exception 同样也继承 BaseException
try:
open("abc.txt",'r')
print aa
except BaseException:
print "异常了!"
msg 变量用于接收异常信息,通过 print 将其打印出来
try:
open("aaa.txt","r")
print aa
except BaseException,msg:
print msg
异常 描述
BaseException 新的所有异常类的基类
Exception 所有异常类的基类,但继承 BaseException 类
AssertionError assert 语句失败
AttributeError 试图访问一个对象没有属性
IOError 输入输出异常,试图打一个不存的文件(包括其它情况)时引起
NameError 使用一个还未赋值对象的变量
IndexError 在使用序列中不存在的所引进引发
IndentationError 语法错误,代码没有正确的对齐
KeyboardInterrupt Ctrl+C 被按下,程序被强行终止
TypeError 传入的对象类型与要求不符
SyntaxError Python 代码逻辑语法出错,不能执行
从定位元素开始
webdriver 提供了八种元素定位方法:
id
name
class name
tag name
link text
partial link text
xpath
css selector
在 Python 语言中对应的定位方法如下:
find_element_by_id()
find_element_by_name()
find_element_by_class_name()
find_element_by_tag_name()
find_element_by_link_text()
find_element_by_partial_link_text()
find_element_by_xpath()
find_element_by_css_selector()
控制浏览器器窗口大小
set_window_size
#coding=utf-8
from selenium import webdriver
driver = webdriver.Firefox()
driver.get("http://m.mail.10086.cn")
#参数数字为像素点
print "设置浏览器宽480、高800显示"
driver.set_window_size(480, 800)
driver.quit()
希望浏览器在全屏幕模式下执行,可以使用 maximize_window()方法,
用法与 set_window_size() 相同,但它不需要传参
driver.maximize_window()最大化浏览器
控制浏览器后退、前进
back()和 forward()
#coding=utf-8
from selenium import webdriver
driver = webdriver.Firefox()
#访问百度首页
first_url= 'http://www.baidu.com'
print "now access %s" %(first_url)
driver.get(first_url)
#访问新闻页面
second_url='http://news.baidu.com'
print "now access %s" %(second_url)
driver.get(second_url)
#返回(后退)到百度首页
print "back to %s "%(first_url)
driver.back()
#前进到新闻页
print "forward to %s"%(second_url)
driver.forward()
driver.quit()
#coding=utf-8
from selenium import webdriver
driver=webdriver.Chrome()
A="http://www.baidu.com"
driver.get(A)
print "now access %s"%A
B="http://news.baidu.com"
driver.get(B)
print "now access %s"%B
driver.back()
driver.forward()
driver.quit()
简单元素操作
clear() 清除文本,如果是一个文件输入框
send_keys(*value) 在元素上模拟按键输入
click() 单击元素
WebElement 接口常用方法
submit
submit()方法用于提交表单,特别用于没提交按钮的情况,相当于“回车”操作
#coding=utf-8
from selenium import webdriver
driver = webdriver.Firefox()
driver.get("http://www.youdao.com")
driver.find_element_by_id('query').send_keys('hello')
#提交输入框的内容
driver.find_element_by_id('query').submit()
driver.quit()
size 返回元素的尺寸。
text 获取元素的文本。
get_attribute(name) 获得属性值。
is_displayed() 设置该元素是否用户可见。
#coding=utf-8
from selenium import webdriver
driver = webdriver.Firefox()
driver.get("http://www.baidu.com")
#获得输入框的尺寸
size=driver.find_element_by_id('kw').size
print size
#返回百度页面底部备案信息
text=driver.find_element_by_id("cp").text
print text
#返回元素的属性值,可以是id、name、type或元素拥有的其它任意属性
attribute=driver.find_element_by_id("kw").get_attribute('type')
print attribute
#返回元素的结果是否可见,返回结果为True或False
result=driver.find_element_by_id("kw").is_displayed()
print result driver.quit()
鼠标事件
ActionChains 类提供的鼠标操作的常用方法:
perform() 执行所有ActionChains中存储的行为
context_click() 右击
double_click() 双击
drag_and_drop() 拖动
move_to_element() 鼠标悬停
鼠标右击操作
from selenium import webdriver
#引入ActionChains类
from selenium.webdriver.common.action_chains import ActionChains
driver = webdriver.Firefox()
driver.get("http://yunpan.360.cn")
....
#定位到要右击的元素
right_click =driver.find_element_by_id("xx")
#对定位到的元素执行鼠标右键操作
ActionChains(driver).context_click(right_click).perform()
....
fromselenium.webdriver import ActionChains
对于 ActionChains 类下面的方法,在使用之前需要先将模块导入。
ActionChains(driver)
调用 ActionChains()方法,在使用将浏览器驱动 driver 作为参数传入。
context_click(right_click)
context_click()方法用于模拟鼠标右键事件,在调用时需要传入右键的元素。
perform()
执行所有 ActionChains 中存储的行为,可以理解成是对整个操作事件的提交动作
鼠标悬停
move_to_element()方法可以模拟鼠标悬停的动作,其用法与 context_click()相同
#coding=utf-8
from selenium import webdriver
#引入ActionChains类
from selenium.webdriver.common.action_chains import ActionChains
driver = webdriver.Firefox()
driver.get("http://www.baidu.com")
above =driver.find_element_by_link_text("设置")
ActionChains(driver).move_to_element(above).perform()
鼠标双击操作
double_click(on_element)方法用于模拟鼠标双击操作,用法同上
……
from selenium import webdriver
#引入ActionChains类
from selenium.webdriver.common.action_chains import ActionChains
driver = webdriver.Firefox()
....
#定位到要悬停的元素
double_click = driver.find_element_by_id("xx")
#对定位到的元素执行双击操作
ActionChains(driver).double_click(double_click).perform()
....
鼠标推放拖拽操作
drag_and_drop(source,target)在源元素上按下鼠标左键,然后移动到目标元素上释放。
source: 鼠标拖动的源元素。
target: 鼠标释放的目标元素
……
from selenium import webdriver
#引入ActionChains类
from selenium.webdriver.common.action_chains import ActionChains
driver = webdriver.Firefox()
....
#定位元素的源位置
element = driver.find_element_by_name("xxx")
#定位元素要移动到的目标位置
target = driver.find_element_by_name("xxx")
#执行元素的拖放操作
ActionChains(driver).drag_and_drop(element,target).perform()
....
键盘事件
#coding=utf-8
from selenium import webdriver
#引入Keys模块
from selenium.webdriver.common.keys import Keys
driver = webdriver.Firefox()
driver.get("http://www.baidu.com")
#输入框输入内容
driver.find_element_by_id("kw").send_keys("seleniumm")
#删除多输入的一个m
driver.find_element_by_id("kw").send_keys(Keys.BACK_SPACE)
#输入空格键+“教程”
driver.find_element_by_id("kw").send_keys(Keys.SPACE)
driver.find_element_by_id("kw").send_keys(u"教程")
#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')
#ctrl+v 粘贴内容到输入框
driver.find_element_by_id("kw").send_keys(Keys.CONTROL,'v')
#通过回车键盘来代替点击操作
driver.find_element_by_id("su").send_keys(Keys.ENTER)
driver.quit()
fromselenium.webdriver.common.keys import Keys
在使用键盘按键方法前需要先导入 keys 类包
下面经常使用到的键盘操作:
send_keys(Keys.BACK_SPACE) 删除键(BackSpace)
send_keys(Keys.SPACE) 空格键(Space)
send_keys(Keys.TAB) 制表键(Tab)
send_keys(Keys.ESCAPE) 回退键(Esc)
send_keys(Keys.ENTER) 回车键(Enter)
send_keys(Keys.CONTROL,'a') 全选(Ctrl+A)
send_keys(Keys.CONTROL,'c') 复制(Ctrl+C)
send_keys(Keys.CONTROL,'x') 剪切(Ctrl+X)
send_keys(Keys.CONTROL,'v') 粘贴(Ctrl+V)
send_keys(Keys.F1) 键盘 F1
……
send_keys(Keys.F12) 键盘 F12
获得验证信息
#coding=utf-8
from selenium import webdriver
driver = webdriver.Firefox()
driver.get("http://www.126.com")
print 'Before login================'
#打印当前页面title
title = driver.title
print title
#打印当前页面URL
now_url = driver.current_url
print now_url
#执行邮箱登录
driver.find_element_by_id("idInput").clear()
driver.find_element_by_id("idInput").send_keys("username")
driver.find_element_by_id("pwdInput").clear()
driver.find_element_by_id("pwdInput").send_keys("password")
driver.find_element_by_id("loginBtn").click()
print 'After login================'
#再次打印当前页面title
title = driver.title
print title
#打印当前页面URL
now_url = driver.current_url
print now_url
#获得登录的用户名
user = driver.find_element_by_id('spnUid').text
print user
driver.quit()
driver.title
title 用于获得当前页面的标题。
driver.current_url
current_url 用户获得当页面的 URL。
设置元素等待
显式等待
#coding=utf-8
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()
WebDriverWait()
由 webdirver 提供的等待方法。在设置时间内,默认每隔一段时间检测一次当前页面元素是否存
在,如果超过设置时间检测不到则抛出异常。具体格式如下:
WebDriverWait(driver, timeout, poll_frequency=0.5, ignored_exceptions=None)
driver -WebDriver 的驱动程序(Ie, Firefox,Chrome 等)
timeout - 最长超时时间,默认以秒为单位
poll_frequency -休眠时间的间隔(步长)时间,默认为 0.5 秒
gnored_exceptions -超时后的异常信息,默认情况下抛 NoSuchElementException 异常
WebDriverWait() 一般由 until()(或 until_not())方法配合使用
Expected Conditions
在本例中,我们在使用 expected_conditions 类时对其时行了重命名,通过 as 关键字对其重命名为 EC,
并调用 presence_of_element_located()判断元素是否存在
expected_conditions 类提供一些预期条件的实现。
title_is 用于判断标题是否 xx。
title_contains 用于判断标题是否包含 xx 信息。
presence_of_element_located 元素是否存在。
visibility_of_element_located 元素是否可见。
visibility_of 是否可见
presence_of_all_elements_located 判断一组元素的是否存在
text_to_be_present_in_element 判断元素是否有 xx 文本信息
text_to_be_present_in_element_value 判断元素值是否有 xx 文本信息
frame_to_be_available_and_switch_to_it 表单是否可用,并切换到该表单。
invisibility_of_element_located 判断元素是否隐藏
element_to_be_clickable 判断元素是否点击,它处于可见和启动状态
staleness_of 等到一个元素不再是依附于 DOM。
element_to_be_selected 被选中的元素。
element_located_to_be_selected 一个期望的元素位于被选中。
element_selection_state_to_be 一个期望检查如果给定的元素被选中。
element_located_selection_state_to_be 期望找到一个元素并检查是否选择状态
alert_is_present 预期一个警告信息
隐式等待
隐式等待是通过一定的时长等待页面所有元素加载完成。哪果超出了设置的时长元素还没有被加载则抛出
NoSuchElementException 异常。
WebDriver 提供了 implicitly_wait()方法来实现隐式等待,默认设置为 0。
#coding=utf-8
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
driver = webdriver.Firefox()
driver.implicitly_wait(10)
driver.get("http://www.baidu.com")
input_ = driver.find_element_by_id("kw22")
input_.send_keys('selenium')
driver.quit()
在上面的例子中,显然百度输入框的定位 id=kw22 是有误的,那么在超出 10 秒后将抛出异常。
sleep 休眠方法
#coding=utf-8
from selenium import webdriver
from time import sleep
driver = webdriver.Firefox()
driver.get("http://www.baidu.com")
sleep(2)
driver.find_element_by_id("kw").send_keys("webdriver")
driver.find_element_by_id("su").click()
sleep(3)
driver.quit()
★正则表达式
在python正则表达式语法中,Python中字符串前面加上 r 表示原生字符串,
用\w表示匹配字母数字及下划线。re模块下findall方法返回的是一个匹配子字符串的列表。
# coding=utf-8
from selenium import webdriver
import re
driver = webdriver.Chrome()
driver.maximize_window()
driver.implicitly_wait(6)
driver.get("http://home.baidu.com/contact.html")
# 得到页面源代码
doc = driver.page_source
emails = re.findall(r'[\w]+@[\w\.-]+',doc) # 利用正则,找出 xxx@xxx.xxx 的字段,保存到emails列表
# 循环打印匹配的邮箱
for email in emails:
print (email)
1. 查看页面的源代码,在Selenium中有driver.page_source 这个方法得到
2. Python中利用正则,需要导入re模块
3. for email in emails :
print email
driver.refresh()刷新当前页面
打开一个新的tab
ctrl+ t
from selenium.webdriver.common.keys import Keys
。。。
driver.find_element_by_tag_name('body').send_keys(Keys.CONTROL + 't')
。。
?send_keys(Keys.CONTROL,'t')
定位一组元素
#coding=utf-8
from selenium import webdriver
import os
driver = webdriver.Firefox()
file_path = 'file:///' + os.path.abspath('checkbox.html')
driver.get(file_path)
# 选择页面上所有的tag name为input的元素
inputs = driver.find_elements_by_tag_name('input')
#然后从中过滤出tpye为checkbox的元素,单击勾选
for i in inputs:
if i.get_attribute('type') == 'checkbox':
i.click()
driver.quit()
因为通过浏览器打开的是一个本地的 html 文件,所以需要用到 Python 的 os 模块,
path.abspath()方法用于获取当前路径下的文件。
checkbox/radio复选框/单选框
find_elements是不能直接点击的,它是复数的,所以只能先获取到所有的checkbox对象,然后通过for循环去一个个点击操作
多表单切换
switch_to_frame() 方法
#coding=utf-8
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
driver = webdriver.Chrome()
driver.get("https://mail.qq.com/")
driver.switch_to_frame("login_frame")
a=driver.find_element_by_link_text("帐号密码登录")
ActionChains(driver).click(a).perform()
switch_to_frame()默认可以直接去表单的id或name属性进行切换,如果没有id/name,
可以通过xpath定位到iframe,再将定位对象传给switch_to_frame()方法
......
xf = driver.find_element_by_xpath('//*[@class="if"]')
driver.switch_to_frame(xf)
......
driver.switch_to_default_content()
可以通过 switch_to_default_content()方法返回上一层表单
该方法不用指定某个表单的返回,默认对应与它最近的 switch_to_frame()方法
嵌套frame的操作(switch_to.parent_frame())
html>
<iframe id="frame1">
<iframe id="frame2" / >
</iframe>
</html>
从主文档切到frame2,一层层切进去
driver.switch_to.frame("frame1")
driver.switch_to.frame("frame2")
从frame2再切回frame1 selenium给我们提供了一个方法能够从子frame切回到父frame,而不用我们切回主文档再切进来。
driver.switch_to.parent_frame() # 如果当前已是主文档,则无效果
所以只要善用以下三个方法,遇到frame分分钟搞定:
driver.switch_to.frame(reference)
driver.switch_to.parent_frame()
driver.switch_to.default_content()
多窗口切换
switch_to_window()
#coding=utf-8
from selenium import webdriver
driver = webdriver.Firefox()
driver.implicitly_wait(10)
driver.get("http://www.baidu.com")
#获得百度搜索窗口句柄
sreach_windows= driver.current_window_handle
driver.find_element_by_link_text(u'登录').click()
driver.find_element_by_link_text(u"立即注册").click() #获得当前所有打开的窗口的句柄
all_handles = driver.window_handles
#进入注册窗口
for handle in all_handles:
if handle != sreach_windows:
driver.switch_to_window(handle)
print 'now register window!'
driver.find_element_by_name("account").send_keys('username')
driver.find_element_by_name('password').send_keys('password')
#……
#进入搜索窗口
for handle in all_handles:
if handle == sreach_windows:
driver.switch_to_window(handle)
print 'now sreach window!'
driver.find_element_by_id('TANGRAM__PSP_2__closeBtn').click()
driver.find_element_by_id("kw").send_keys("selenium")
driver.find_element_by_id("su").click()
time.sleep(5)
driver.quit()
先打开百度首页,通过 current_window_handle 获得当前窗口的句柄,并给变量 sreach_handle。
接着打开登录弹窗,在登录窗口上点击“立即注册”从而打开新的注册窗口。通过 window_handles
获得当前打开的所窗口的句柄,赋值给变量 all_handles。
第一个循环遍历 all_handles,如果 handle 不等于 sreach_handle,那么一定是注册窗口,
因为脚本执行只打开的两个窗口。所以,通过 switch_to_window()切换到注册页进行注册操作。
第二个循环类似,不过这一次判断如果 handle 等于 sreach_handle,那么切换到百度搜索页,
关闭之前打开的登录弹窗,然后时行搜索操作。
current_window_handle 获得当前窗口句柄
window_handles 返回的所有窗口的句柄到当前会话
switch_to_window() 用于切换到相应的窗口,与上一节的 switch_to_frame() 是类似,
前者用于不同窗口的切换,后者用于不同表单之间的切换
警告框处理
switch_to_alert()
在 WebDriver 中处理 JavaScript 所生成的 alert、confirm 以及 prompt 是很简单的。
具体做法是使用 switch_to_alert()方法定位到 alert/confirm/prompt。
然后使用 text/accept/dismiss/send_keys 按需进行操做。
#coding=utf-8
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
driver = webdriver.Firefox()
driver.implicitly_wait(10)
driver.get('http://www.baidu.com')
#鼠标悬停相“设置”链接
link = driver.find_element_by_link_text(u'设置')
ActionChains(driver).move_to_element(link).perform()
#打开搜索设置
driver.find_element_by_class_name('setpref').click()
#保存设置
driver.find_element_by_css_selector('#gxszButton > a.prefpanelgo').click()
#接收弹窗
driver.switch_to_alert().accept()
driver.quit()
text 返回 alert/confirm/prompt 中的文字信息。
accept 点击确认按钮。
dismiss 点击取消按钮,如果有的话。
send_keys 输入值,这个 alert\confirm 没有对话框就不能用了,不然会报错。
通过 switch_to_alert()方法获取当前页上的警告框,accept()接受警告框
上传文件
send_keys实现上传
#coding=utf-8
from selenium import webdriver
import os
driver = webdriver.Firefox()
#打开上传功能页面
file_path = 'file:///' + os.path.abspath('upfile.html')
driver.get(file_path)
#定位上传按钮,添加本地文件
driver.find_element_by_name("file").send_keys('D:\\upload_file.txt')
driver.quit()
通过 Python 的 os 模块的 system()方法可以调用 exe 程序并执行。
AutoIt 实现上传
....
下载文件
#coding=utf-8
from selenium import webdriver
import os
fp = webdriver.FirefoxProfile()
fp.set_preference("browser.download.folderList",2)
fp.set_preference("browser.download.manager.showWhenStarting",False)
fp.set_preference("browser.download.dir", os.getcwd())
fp.set_preference("browser.helperApps.neverAsk.saveToDisk",
"application/octet-stream") #下载文件的类型
driver = webdriver.Firefox(firefox_profile=fp)
driver.get("http://pypi.Python.org/pypi/selenium")
driver.find_element_by_partial_link_text("selenium-2").click()
为了让 FireFox 让浏览器能实现文件的下载,我们需要通过 FirefoxProfile() 对其参数做一个设置。
browser.download.folderList
设置成 0 代表下载到浏览器默认下载路径;设置成 2 则可以保存到指定目录。
browser.download.manager.showWhenStarting
是否显示开始,Ture 为显示,Flase 为不显示。
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 进行设置
操作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 信息下面通过 get_cookies()来获取当前浏览器的 cookie 信息。
#coding=utf-8
from selenium import webdriver
import time
driver = webdriver.Firefox()
driver.get("http://www.youdao.com")
#向cookie的name 和value添加会话信息。
driver.add_cookie({'name':'key-aaaaaaa', 'value':'value-bbbbbb'})
#遍历cookies中的name 和value信息打印,当然还有上面添加的信息
for cookie in driver.get_cookies():
print "%s -> %s" % (cookie['name'], cookie['value'])
driver.quit()
delete_cookie() 和 delete_all_cookies() 的使用也很简单,
前者通过 name 值到一个特定的 cookie 将其删除,后者直接删除浏览器中的所有 cookies()信息。
操作浏览器上的滚动条
#coding=utf-8
from selenium import webdriver import time
#访问百度
driver=webdriver.Firefox()
driver.get("http://www.baidu.com")
#搜索
driver.find_element_by_id("kw").send_keys("selenium")
driver.find_element_by_id("su").click()
time.sleep(3)
#将页面滚动条拖到底部
js="var q=document.documentElement.scrollTop=10000"
driver.execute_script(js)
time.sleep(3)
#将滚动条移动到页面的顶部
js_="var q=document.documentElement.scrollTop=0"
driver.execute_script(js_)
time.sleep(3)
driver.quit()
JavaScript 代码控制滚动条在任意位置,需要改变的就是 scrollTop 的值。
通过 execute_script()方法来执行
窗口截图
get_screenshot_as_file()
#coding=utf-8
from selenium import webdriver
driver = webdriver.Chrome()
driver.get('http://www.baidu.com')
try:
driver.find_element_by_id('kw_error').send_key('selenium')
driver.find_element_by_id('su').click()
except :
driver.get_screenshot_as_file("D:\\baidu_error.jpg")
driver.quit()
在本例中用到了 Python 的异常处理,要本例中百度输入框的 id=kw_error 会定位不到元素,
那么 try 就会捕捉到这个异常,从而执行 except,在 except 中执行 get_screenshot_as_file()
对当前窗口进行截图,这里需要指定图片的保存路径及文件名,并且关闭当前驱动。
脚本运行完成打开 D 盘就可以找到 baidu_error.jpg 图片文件了
关闭窗口
close()
在前页的例子中我们一直在使用 quit()方法,其含义为退出相关的驱动程序和关闭所有窗口。
除此之外 WebDriver 还提供了 close()方法,用于关闭当前窗口。
当脚本在执行时打开了多个窗口,如本章的第 10 小节多窗口的处理,
这个时候只能关闭其中的某一个窗口,这个时候就需要使用 close()来关闭。
验证码的处理
1、去掉验证码
2、设置万能码
#coding=utf-8
import random
#生成一个1000到9999之间的随机整数
verify = random.randint(1000,9999)
print u"生成的随机数:%d " %verify
number = input(u"请输入随机数:")
print number
if number == verify:
print u"登录成功!!"
elif number == 132741:
print u"登录成功!!"
else:
print u"验证码输入有误!"
randint()用于生成随机数,设置随机数的范围为1000~9999之间
3、验证码识别技术
例如可以通过 Python-tesseract 来识别图片验证码,Python-tesseract 是光学字符识别
Tesseract OCR 引擎的 Python 封装类。能够读取任何常规的图片文件(JPG, GIF ,PNG , TIFF 等)。
不过,目前市面上的验证码形式繁多,目前任何一种验证码识别技术,识别率都不是100% 。
4、记录 cookie
模块化
对登录和退出进行模块的封装
#coding=utf-8
from selenium import webdriver
#登陆
def login():
driver.find_element_by_id("idInput").clear()
driver.find_element_by_id("idInput").send_keys("username")
driver.find_element_by_id("pwdInput").clear()
driver.find_element_by_id("pwdInput").send_keys("password")
driver.find_element_by_id("loginBtn").click()
#退出
def logout():
driver.find_element_by_link_text(u"退出").click()
driver.quit()
driver = webdriver.Firefox()
driver.implicitly_wait(10)
driver.get("http://www.126.com")
login() #调用登陆模块 #收信、写信、删除信件等操作
logout() #调用退出模块
将登录的操作步骤封装到login()函数中,把退出的操作封装到logout()函数中,
对于用例本身只用调用这两个函数即可
只是把步骤封装成函数并没简便太多,我们需要将其放到单独的文件中供其它用例调用。
#coding=utf-8
#登陆
def login(driver):
driver.find_element_by_id("idInput").clear()
driver.find_element_by_id("idInput").send_keys("username")
driver.find_element_by_id("pwdInput").clear()
driver.find_element_by_id("pwdInput").send_keys("password")
driver.find_element_by_id("loginBtn").click()
#退出
def logout(driver):
driver.find_element_by_link_text(u"退出").click()
driver.quit()
当函数被独立到单独的文件中时做了一点调整,主要在函数的传参上,
因为函数内部的操作需要使用driver,但是driver并没有在此文件中定义,
所以需要调用的用例传递driver给调用的函数。
#coding=utf-8
from selenium import webdriver import public
driver = webdriver.Firefox()
driver.implicitly_wait(10)
driver.get("http://www.126.com")
#调用登陆模块
public.login(driver)
#收信、写信、删除信件等操作
#调用退出模块
public.logout(driver)
首先,需要导入当前目录中的public.py,在需要的位置调用文件中的login()和和logout()函数。
这样对于每个用例来说就简便了许多,也更易于维护。
数据驱动实例
1.邮箱登录
#coding=utf-8
from selenium import webdriver
driver = webdriver.Firefox()
driver.implicitly_wait(10)
driver.get("http://www.126.com")
class Account(object):
"""docstring for Account"""
def __init__(self,username ='', password =''):
self.username = username
self.password = password
def do_login_as(user_info):
driver.find_element_by_id("idInput").clear()
driver.find_element_by_id("idInput").send_keys(user_info.username)
driver.find_element_by_id("pwdInput").clear()
driver.find_element_by_id("pwdInput").send_keys(user_info.password)
driver.find_element_by_id("loginBtn").click()
#实例化登陆信息
admin = Account(username='admin',password='123')
guset = Account(username='guset',password='321')
#调用登陆函数
do_login_as(admin)
do_login_as(guset)
首先创建表Account类,对用户名密码进行初始化设置,紧接着创建do_login_as()函数用于实现用户的
登录操作,它需要一个user_info参数用于接收用户的登录信息。取user_info中的username输入到
用户名输入框,取user_info中的password输入密码输入框。
紧接着下面的操作就是通过调用Account实例化用户admin和guset,进行个性化的参数设置。
最后分别调用do_login_as()函数来实现不同用户的登录。
2.百度搜索
创建info.txt文件,每一行写上需要搜索的“关键字”
【info.txt】
selenium
webdriver
Python
#coding=utf-8
from selenium import webdriver
file_info = open('info.txt','r')
values = file_info.readlines()
file_info.close()
for serch in values:
driver = webdriver.Firefox()
driver.implicitly_wait(10)
driver.get("http://www.baidu.com")
driver.find_element_by_id('kw').send_keys(serch)
driver.find_element_by_id('su').click()
driver.quit()
通过open()方法以读的方式打开info.txt文件
通过readlines()方法获取文件中所有行的数据,并赋值给变量
通过close()关闭文件
3.读取txt文件
read() 读取整个文件。
readline() 读取一行数据。
readlines() 读取所有行的数据。
user_info.txt
(zhangsan,123
lisi,456
wangwu,789)
#coding=utf-8
from selenium import webdriver
user_file = open('user_info.txt','r')
values = user_file.readlines()
user_file.close()
for serch in values:
username =serch.split(',')[0]
print username
password =serch.split(',')[1]
print password
使用split()进行拆分,它可将一个字符符串通过某一符号拆分成左右两部分,这里逗号(,)为分割点
用[0]可以取到左半部分的字符串,[1]可以取到右半部分的字符串
例子:
#coding=utf-8
from selenium import webdriver
a=open('aa.txt','r')
values=a.readlines()
a.close()
for b in values:
c=b.split(',')[0]
d=b.split(',')[1]
driver=webdriver.Chrome()
driver.get('http://192.168.10.80/common/login')
driver.find_element_by_id("loginName").send_keys(c)
driver.find_element_by_id("loginPwd").send_keys(d)
driver.find_element_by_id("loginCode").send_keys("CL31")
driver.find_element_by_id("loginBtn").click()
4.读取CSV文件
#coding=utf-8
import csv #导入 csv 包 excel(xlrd)
#读取本地 CSV 文件
my_file='info.csv'
date=csv.reader(file(my_file,'rb'))
#循环输出每一行信息
for user in date:
print user[1]
导入csv模块,通过reader()方法读取csv文件
5.读取xml文件
#coding=utf-8
import xml.dom.minidom
#打开xml文档
dom=xml.dom.minidom.parse('info.xml')
#得到文档元素对象
root=dom.documentElement
print root.nodeName
print root.nodeValue
print root.nodeType
print root.ELEMENT_NODE
xml.dom.minidom
xml.dom.minidom 模块被用来处理xml文件,所以要先引入。
parse()
xml.dom.minidom.parse() 用于打开一个xml文件,并将这个文件对象dom变量。
documentElement
documentElement 用于得到dom对象的文档元素,并把获得的对象给root
每一个结点都有它的nodeName,nodeValue,nodeType属性。
nodeName 为结点名字。
nodeValue 是结点的值,只对文本结点有效。
nodeType 是结点的类型。
Selenium IDE
Ctrl+Alt+S 打开窗口
Action 有两种形式:action和actionAndWait
action会立即执行,而actionAndWait会假设需要较长时间才能得到该action的相响,
而作出等待,open则是会自动处理等待时间。
Title ,获取页面的标题。
Value 获得元素的值。
Text 获得元素的文本信息。
Table 获得元素的标签。
ElementPresent 获得当前元素。
验证(verify)和断言(assert)
区别:
断言失败,脚本终止继续执行
验证失败,脚本还将继续执行
等待(waitFor)和变量(store)
Selenium IDE中提供了pause来设置固定的休眠时间,waitFor在一定时间内等待某一元素显示
waitFor如果Value为空,默认为60秒。
store用于定义变量
可把页面中获取到的标题、文本信息和元素定义成变理title、text和element
get_screenshot_as_file
窗口截图
driver.maximize_window
窗口最大化