python+webdriver学习笔记

控制浏览器

设置浏览器大小:像素点

set_window_size(width,height)

maximize_window() 浏览器全屏显示,不带参数

控制浏览器前进、后退:

driver.forward()

driver.back()

模拟浏览器刷新:

driver.refresh()

实例:

 

from selenium import webdriver

driver = webdriver.Firefox()
driver.get(r"http://www.baidu.com/")

#参数是像素点宽,高
driver.set_window_size(800,800)
print("浏览器大小是800px,800px")

driver.find_element_by_link_text("新闻").click()
driver.back()     #返回前一个页面
driver.forward()  #前进前一个页面
driver.refresh()  #刷新当前页面
driver.find_element_by_css_selector("#ww").send_keys("python3")
driver.find_element_by_xpath("//*[@class='btn']").click()
driver.refresh()  #刷新当前页面
driver.quit()

clear()清除文本

send_keys("....") 模拟按键输入

click() 单击元素,前提是它是可以被单击的对象。另外click()方法不仅可以用于单击一个按钮,它还能可以单击任何可以单击的文字、图片、checkbox、radio、select下拉框等。

submit() 用于提交表单,同样可以用于提交一个按钮。

WebElement接口常用方法

submit() 用于提交表单,同样可以用于提交一个按钮。

先看例子:

 

from selenium import webdriver

driver = webdriver.Firefox()
driver.get(r"http://www.baidu.com/")
size = driver.find_element_by_name("wd").size
print(size)      #size属性,返回元素的尺寸,表单输入框之类的width、height等

text = driver.find_element_by_id("jgwab").text
print(text)      #text属性,获取元素的文本,可以用力判断打开的页面是否是预期的。

attribute = driver.find_element_by_xpath(".//input[@id='kw']").get_attribute('maxlength')
print(attribute) #get_attribute()方法可以获取属性值

result = driver.find_element_by_partial_link_text("京公网安备").is_displayed()
print(result)   #is_displayed() 元素是否设置可见,可见返回true则false

driver.quit()

 

 

 

size属性返回元素尺寸

text属性返回元素文本

get_attribute()方法获取属性值

is_displayed()方法返回该元素是否设置可见

鼠标事件

对鼠标的操作:右击、双击、悬停、鼠标拖动等功能,webdriver中对鼠标的操作的方法封装在ActionChains类中。

使用前要先导入ActionChains类:

from selenium.webdriver.common.action_chains import ActionChains

ActionChains类提供的鼠标操作常用方法:

 

  • context_click()               右击
  • click()                     单击 (鼠标左键单击)
  • double_click()                双击
  • drag_and_drop()          拖动
  • move_to_element()     鼠标悬停
  • perform()                        执行所有ActionChains类中存储的行为,可以理解为对整个操作的提交动作

 

鼠标左键单击

ActionChains(driver).click(driver.find_element(By.ID,'ID')).perform()    #使用perform()才能执行action

首先需要了解ActionChains的执行原理,当你调用ActionChains的方法时,不会立即执行,而是会将所有的操作按顺序存放在一个队列里,当你调用perform()方法时,队列中的时间会依次执行。

 

    def createLectureTopic(self,topicname):
        self.wait_element(*self.createTopicButton_loc).click()
        nowHandle = self.driver.current_window_handle
        self.wait_element(*self.lectureTopic_loc).click()
        allHandles = self.driver.window_handles
        for i in allHandles:
            if i != nowHandle:
                self.driver.switch_to.window(i)
                # 课程主题
                text = str(topicname)+str(time.time())
                # js = "var sum=document.get_element_by_id('topic-title-edit');sum.value='" + text + "';"
                # self.execute_js(src=js)
                self.wait_element(*self.topicName_loc).send_keys(text)
                # 开始时间,鼠标左键单击操作
                time.sleep(1)
                ActionChains(self.driver).click(self.wait_element(*self.startTime_loc)).perform()
                # 处理弹窗,当弹窗可见后,执行选择时间操作
                while self.wait_element(*self.timeControlWindow_loc).is_displayed():
                    time.sleep(1)
                    self.wait_element(*self.ensureStartTime_loc).click()
                    time.sleep(1)
                    break
                # 下一步
                return self.wait_element(*self.nextStep_loc).click()

 

 

 

 

 

鼠标右键操作

 

from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains  #导入ActionChains类

driver = webdriver.Firefox()
driver.get(r"https://yunpan.360.cn/")
driver.maximize_window ()
driver.find_element_by_xpath("//*[@name='account']").clear()
driver.find_element_by_xpath("//*[@name='account']").send_keys("username.com")
driver.find_element_by_name("password").clear()
driver.find_element_by_name("password").send_keys("pwd")
driver.find_element_by_xpath("//*[@id='login']/div/div[2]/form/p[4]/label/input").click()
driver.find_element_by_xpath("//*[@id='login']/div/div[2]/form/p[5]/input").click()

#定位到需要右击的元素
right_click = driver.find_element_by_link_text("jemeter")

#对定位到的元素执行鼠标邮件操作,调用ActionChains类,将浏览器驱动driver作为参数传入,context_click()需要指定元素位置
ActionChains(driver).context_click(right_click).perform() 

 

鼠标双击操作

double_click()方法模拟鼠标双击操作

 

(单击查看详情,双击弹出修改页面就用这个方法模拟)

 

from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains

driver = webdriver.Firefox()
driver.get(r"http://www.baidu.com/")

....
#定位需要双击的元素
double_click = driver.find_element_by_xpath("")
#对定位到的元素进行双击操作
ActionChains(driver).double_click(double_click).perform()

a = driver.find_element_by_class_name("")
ActionChains(driver).double_click(a).perform()

 

鼠标悬停

move_to_element()方法模拟鼠标悬停

 

 

from selenium import webdriver
import time
from selenium.webdriver.common.action_chains import ActionChains

driver = webdriver.Firefox()
driver.get(r"http://www.baidu.com/")
driver.set_window_size(1000,1000)
#定位到悬停的元素
attrible = driver.find_element_by_link_text("设置")
#对定位到的元素进行悬停操作
ActionChains(driver).move_to_element(attrible).perform()
time.sleep(5)
driver.refresh()

以上3中鼠标操作用法相同!

 

 

鼠标拖放操作

drag_and_drop(source,target) 在源元素上按住鼠标左键,然后移动到目标元素上释放。

 

 

  • source 鼠标拖动的源元素
  • target鼠标释放的目标元素

 

 

from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains

driver = webdriver.Firefox()
driver.get("http://www.baidu.com/")
#定位元素的初始位置
source = driver.find_element_by_css_selector("")
#定位元素的要移动到的位置
target = driver.find_element_by_name("")
#执行元素的拖放操作
ActionChains(driver).drag_and_drop(source,target).perform()

 

键盘事件

Keys()类提供了键盘上按键的方法,send_keys()方法可以用来模拟键盘输入,还可以用来输入键盘上的按键、组合键。

 

在使用键盘按键方法前需要先导入keys类:

from selenium.webdriver.common.keys import  Keys
实例:

 

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time

driver = webdriver.Firefox()
driver.get(r"http://www.baidu.com/")
driver.maximize_window()
driver.find_element_by_name("wd").send_keys("pythonm")
#删除多输入的m
time.sleep(2)                       #删除键
driver.find_element_by_name('wd').send_keys(Keys.BACK_SPACE)


#输入空格键在输入“selenium”       #空格键
driver.find_element_by_name("wd").send_keys(Keys.SPACE)
time.sleep(2)
driver.find_element_by_name("wd").send_keys("selenium")
time.sleep(2)

#ctrl+a全选输入框内容               #Ctrl+a全选
driver.find_element_by_name("wd").send_keys(Keys.CONTROL,'a')
time.sleep(2)

#Ctrl+x剪切选中的内容               #Ctrl+x剪切
driver.find_element_by_name("wd").send_keys(Keys.CONTROL,'x')
time.sleep(2)

#Ctrl+v粘贴选中的内容               #Ctrl+v粘贴
driver.find_element_by_name('wd').send_keys(Keys.CONTROL,'v')

#通过输入enter键替代clic()单击      #enter回车键
driver.find_element_by_name('wd').send_keys(Keys.ENTER)
driver.quit()

获取验证信息

在自动化用例执行之后,我们可以在页面上获取一些信息来证明,用例执行成功还是失败。

通常用到的验证信息分别是:text、title、URL

 

  • text:获取标签对之间的文本信息;
  • title:获取当前页面的标题;
  • current_url:获取当前页面的URL

 

它们是webdriver的属性!!!

实例:

 

from selenium import webdriver
from time import sleep

driver = webdriver.Firefox()
driver.get(r"http://yunpan.360.cn")

print("登录之前:")

#打印打钱页面的title
title = driver.title
print(title)

#打印当前页面的URL
now_url = driver.current_url
print(now_url)

#获取“欢迎使用360云盘!”的文本
text = driver.find_element_by_tag_name("h1").text
print(text)

#登录邮箱
driver.find_element_by_name("account").clear() #name定位
driver.find_element_by_name("account").send_keys("xxxqq.com")
driver.find_element_by_xpath("//*[@name='password']").clear() #xpath元素属性定位
driver.find_element_by_xpath("//*[@name='password']").send_keys("yxxx36")
#xpath元素属性和层级结合定位
driver.find_element_by_xpath("//div[@id='login']/div/div[2]/form/p[4]/label/input").click()
driver.find_element_by_xpath("//*[@id='login']/div/div[2]/form/p[5]/input").click()
sleep(5)

print("登录邮箱之后:")

#再次打印title
title = driver.title
print(title)

#打印当前的URL
now_url = driver.current_url
print(now_url)

#获取登录后的文本
text = driver.find_element_by_xpath(".//*[@id='crumb']/div/span").text
print(text)

python+webdriver学习笔记_第1张图片

 

 

 

可以把登录之后的信息存放起来,作为验证登录是否成功。加断言就可可以。

设置元素等待

web应用程序采用AJAX技术时,页面上的元素不会同时被加载完成,防止定位元素会出现ElementNotVisibleException的错误,可以通过设置元素等待防止这种问题出现。

显式等待

显式等待使WebDriver等待某个条件成立时继续执行,否则在达到最大时长抛出超时异常(TimeException)。

显式等待用到WebDriverWait()类和expected_conditions()类中的方法,使用前需要先导入:

from selenium.webdriver.support.ui import WebDriverWait

from selenium.webdriver.support import expected_conditions as EC

显式等待相当于:在定位某个元素之前检查该元素是否被加载出来了,until到当前元素被加载到DOM树中

实例:

 

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(r"http://www.baidu.com//")

#显式等待
#定位第一个元素
element = WebDriverWait(driver,5,0.5,ignored_exceptions=None).until(
    EC.presence_of_element_located((By.ID,"kw"))
    )
element.send_keys("ptyh")
#定位第二个元素
element = WebDriverWait(driver,5,0.5,ignored_exceptions=None).until(
    EC.presence_of_element_located((By.ID,"su"))
    )
element.click()
driver.quit()

 

WebDriverWait(driver,timeout,poll_frequency=0.5,ignored_exceptions=None)

 

  • driver:浏览器驱动
  • timeout:最长超时时间,默认单位是秒
  • poll_frequency:检测的间隔时间,默认是0.5秒
  • ignored_exceptions:超时后的异常信息,默认抛出NoSuchElementException异常。

 

WebDriverWait()一般由until()或until_not()方法一起使用:

until(method,message = 'xxx')
until_not(method,message = ‘XXX’)

例子中until()的method是EC.presence_of_element_located((By.Id,"kw")) 

expected_conditions()类所提供的预期条件判断方法还很多!!P97

使用匿名函数:

 

from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait

driver = webdriver.Chrome()
driver.get(r'http://www.baidu.com')
driver.maximize_window()
WebDriverWait(driver,5,0.5,ignored_exceptions=None).until(lambda driver : driver.find_element_by_xpath("//*[@id='kw']")).send_keys('lambda')
WebDriverWait(driver,5).until(lambda driver : driver.find_element_by_id('su')).click()
driver.quit()

lambda是一个匿名函数,冒号前是入参,冒号后面是return的返回值,相当于:

 

def test(driver):
    return driver.find_element_by_id('su').click()

 

 

除了预期类提供的判断外还可以用is_displayed()方法判断元素是否可见:

 

#利用is_displayed()方法判断元素是否可见
'''
for循环10次每次循环判断元素的is_diaplayed()状态
是否是true,若为true,则break跳出循环;否则sleep(1)
后继续循环判断,知道10次循环结束后,打印“time_out”信息。
'''
from selenium import webdriver
from time import sleep,ctime

driver = webdriver.Firefox()
driver.get(r"http://www.baidu.com/")

print(ctime())
for i in range(10):
    try:
        element = driver.find_element_by_id("kw33")
        if element.is_displayed():
            break
    except:pass
    sleep(1)
else:
    print("time_out!")
driver.close()
print(ctime())
    

隐式等待

隐式等待是通过一定的时长等待页面上某元素加载完成。如果超出了设置的时长元素还没有加载,会抛出NoSuchElementException异常。

webdriver的implicitly_wait()方法来实现隐式等待,默认设置为0。

这个等待函数是针对整个driver的,只需要设置一个函数就行。也就是说,使用driver去获取一个元素或对象,当找不到这个元素时,它就会自动根据设置的时间去等待,超过设置的时长才会抛出错误。

隐式等待使用到抛出异常,NoSuchElementException异常需要先导入:

from selenium .common.exceptions import NoSuchElementException

implicitly_wait()方法由webdriver提供。

实例:

 

from selenium import webdriver
#from selenium.common.exceptions import NoSuchElementException
from time import ctime

driver = webdriver.Firefox()

#设置隐式等待是10s
driver.implicitly_wait(10)
driver.get("http://www.baidu.com/")
try:
    print(ctime())
    driver.find_element_by_id("kw22").send_keys("python")
except NoSuchElementException as e:
    print(e)
finally:
    print(ctime())
    driver.quit()

 

  • implicitly_wait()默认参数单位是秒,这里的5秒并不是一个固定的等待时间,它不影响脚本的执行速度。
  • implicitly_wait()并不针对页面上的某一元素进行等待,当脚本执行到某个元素定位时,若元素可以定位,则继续执行;若元素定位不到,则它将以轮询的方式不断判断元素是否被定位到,直到超出设置时长还没有定位到元素,则抛出异常。

 

sleep休眠方法

希望脚本执行到某个位置做固定休眠,可以使用sleep()方法。sleep()方法由python的time提供:

from time import sleep

实例:(结合隐式等待、键盘事件)

隐式等待利用语句:try...except...else...finally...

先对定位元素进行判断,若在设置的时间内定位元素失败就执行except语句抛出NoSuchElementException,定位到元素执行else语句代码继续执行。

 

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from time import sleep,ctime
from selenium.common.exceptions import NoSuchElementException

driver = webdriver.Firefox()
print(ctime())

#设置隐式等待
driver.implicitly_wait(10)

#先执行try定位元素位置
try:
    driver.get(r"http://www.baidu.com/")
    driver.maximize_window () #全屏显示
    sleep(2)
    el = driver.find_element_by_name("wd")
    sleep(3) #休眠3秒

#找不到元素位置就执行except    
except NoSuchElementException as e:
    print(e)

#找到元素位置执行else语句
else:
    el.send_keys("pythonm")

    #删除多输入的m
    driver.find_element_by_name("wd").send_keys(Keys.BACK_SPACE)
    sleep(3)
    #输入空格+“自动化测试”
    driver.find_element_by_name("wd").send_keys(Keys.SPACE)
    sleep(3)
    driver.find_element_by_name("wd").send_keys("自动化测试")
    sleep(3)
    #输入enter键百度一下
    driver.find_element_by_id("su").send_keys("Keys.ENTER")
    sleep(3)

#定不定位到元素都会执行finally语句
finally:
    print(ctime())
    driver.quit()

 

 

 

若在设置时间内定位不到元素位置,抛出异常:

 

 

 

python+webdriver学习笔记_第2张图片

定位一组元素

webdriver提供了定位一组元素的方法:

 

  • find_elements_by_id()
  • find_elements_by_name()
  • find_elements_by_class_name()
  • find_elements_by_tag_name()
  • find_elements_by_xpath()
  • find_elements_by_css_selector()
  • find_elements_by_link_text()
  • find_elements_by_partial_link_text()

 

原来定位一组元素和定位一个元素基本一样,唯一不同的是elements复数。

定位一组元素用于:

 

  • 批量操作元素,如勾选复选框checkbox、单选框radio。
  • 先获取一组元素,再从这组元素对象中过滤出需要操作的元素,如定位页面所有的复选框,然后选择其中一个进行其他操作。

 

如操作下面一段代码:checkbox.html

 



 
  
  checkbox test~
  
 
 
   

选择你喜欢的食物:

你是男士还是女士:

把checkbox复选框全部选择:

 

find_elements_by_tag_name()定位,需要判断是否是checkbox

 

from selenium import webdriver
import time

driver = webdriver.Firefox()

driver.get(r"http://192.168.225.137/html5/checkbox.html")

#选择页面上所有tag_name是input的元素
inputs = driver.find_elements_by_tag_name("input")

#然后过滤出type为checkbox的元素
for i in inputs:  #用tag_name定位需要判断是否是checkbox,如下:
    if i.get_attribute("type") == "checkbox":
        i.click()
        time.sleep(1)
inputs.pop().click()
inputs.pop().click(2) 

 

通过find_elements_by_xpath()和find_elements_by_css_selector()直接定位到checkbox:

 

不需要判断了,选择所有的复选框后取消第二个和最后一个:

 

from selenium import webdriver
from time import sleep

driver = webdriver.Firefox()
driver.get(r"http://192.168.225.137/html5/checkbox.html")
driver.set_window_size(1000,1000)

#通过css定位
checkboxs = driver.find_elements_by_css_selector("[type='checkbox']")
#通过xpath定位
inputs = driver.find_elements_by_xpath("//*[@type='checkbox']")
#通过以上两种方式定位就不需要判断定位的标签是否是复选框的了
for i in checkboxs:
    i.click()
    sleep(1)
    
#打印当前页面上input="checkbox" 的个数
print(len(inputs))

#把页面上第二个checkbox取到勾选
inputs.pop(1).click()
sleep(2)
driver.find_elements_by_xpath("//*[@type='checkbox']").pop(-1).click()
#前面已经把所有checkbox勾上了,通过pop().click()对某个checkbox再勾选,即是取消勾选。

 

 

  • len()方法可以计算定位到的元素个数;
  • pop()方法获取列表中某个元素,pop().click()定位到某个checkbox后取消勾选;
  • pop()\pop(-1)都表示最后一个checkbox;
  • pop(0)第一个checkbox;

 

多表单切换

webdriver只能在一个页面上定位和识别元素,对于iframe或frame不能直接定位。

通过switch_to.frame()方法将当前的主体切换为frame或iframe表单的内嵌页面中。

myframe.html

 



  
   myframe test!!!
   
   
  
  
   

myframe

python+webdriver学习笔记_第3张图片

 

如上内联框架,定位里面的百度页面元素时,先要使用switch_to.frame()找到