Web自动化之Selenium API(四)

1 多标签

当我们从一个网站上点击一个链接之后,可能会弹出一个新的窗口,我们手动测试可以直接选中弹出的窗口进行操作,但是计算机不可以,计算机需要在多个标签之间进行切换,接下来我们就学习下如何实现

1.获取所有的标签句柄列表

driver.window_handles

2.切换到指定标签

driver.switch_to_window(driver.window_handles[1])

3.switch_to(更为推荐的方法)

driver.switch_to.window(driver.window_handles[n])

练习案例

from selenium import webdriver

import time

driver = webdriver.Firefox()

url = 'http://bj.58.com'

driver.get(url)

# 打印点击之前的窗口句柄列表

print('点击之前的窗口句柄:',driver.window_handles)

print('当前的url:',driver.current_url,'当前的标题:',driver.title)

# 定位到房屋出租,点击

el = driver.find_element_by_link_text('房屋出租')

el.click()

print('-------------------------------------------------------------')

# 获取到所有的窗口

handles = driver.window_handles

print('点击之后的窗口句柄:',handles)

print('当前的url:',driver.current_url,'当前的标题:',driver.title)

# 切换到新开窗口

driver.switch_to.window(handles[1])

print('切换之后的窗口句柄:',handles)

print('当前的url:',driver.current_url,'当前的标题:',driver.title)

try:

    # 定位一个再新窗口页面上的元素,如果能够定位到,则表明当前在新窗口上,如果失败则表明现在不在新窗口上

    el = driver.find_element_by_css_selector('.listUl > li:nth-child(1) > div:nth-child(2) > h2:nth-child(1) > a:nth-child(1)')

    print (el.text)

    print('driver在新页面')

except:

    print('没有在新页面')

try:

    # 定位一个在就窗口上的元素,如果能够定位到,则表明现在在就窗口上

    el = driver.find_element_by_css_selector('div.col3:nth-child(2) > em:nth-child(1) > a:nth-child(1)')

    print (el.text)

    print('driver在旧页面')

except:

    print('没有在旧页面')

2 多表单切换

在Web应用中经常会遇到frame/iframe表单嵌套页面的应用,WebDriver只能在一个页面上对元素识别与定位,对于frame/iframe表单内嵌页面上的元素无法直接定位。这时就需要通过switch_to.frame()方法将当前定位的主体切换为frame/iframe表单的内嵌页面中。

1.switch_to.frame() 默认可以直接取表单的id 或name属性。如果iframe没有可用的id和name属性,则可以通过下面的方式进行定位。

from selenium import webdriver

import time

url = 'http://www.126.com/'

driver = webdriver.Firefox()

# 访问126邮箱

driver.get(url)

time.sleep(5)

# 直接通过id进入

driver.switch_to.frame('x-URS-iframe')

# 先定位到元素再进入

el_frame = driver.find_element_by_id('x-URS-iframe')

driver.switch_to.frame(el_frame)

try:

    # 定位并输入账号

    el_user = driver.find_element_by_name('email')

    el_user.send_keys('itcast_soft_test')

    # 定位并输入密码

    el_pwd = driver.find_element_by_name('password')

    el_pwd.send_keys('1qaz2wsx#EDC')

    # 定位并点击登录

    el_sub = driver.find_element_by_id('dologin')

    el_sub.click()

    time.sleep(5)

except:

    print ('页面上没有账号密码输入框')

driver.quit()

2.driver.switch_to.default_content()

 跳回最外层的页面。

3.driver.switch_to.parent_frame()

 跳回上层的页面。

案例(此案例需配合文件运行):

from selenium import webdriver

import os

import time

file_path = 'file:///' + os.path.abspath('example_frame.html')

print (file_path)

driver = webdriver.Firefox()

# 加载本地html文件

driver.get(file_path)

# 进入到第一层表单,通过id值

driver.switch_to.frame('itcast_frame1')

time.sleep(5)

# 进入到第二层表单,通过元素定位

driver.switch_to.frame('itcast_frame2')

time.sleep(5)

# 定位到搜索栏标签

el_input = driver.find_element_by_id('sb_form_q')

el_input.send_keys('selenium')

el_sub = driver.find_element_by_id('sb_form_go')

el_sub.submit()

time.sleep(5)

driver.switch_to.parent_frame()

try:

    el_input = driver.find_element_by_id('sb_form_q')

except:

    print('已经退出到上级表单')

3 鼠标&键盘操作

当我们进行手动测试的时候,有的时候我们可能会实现双击,拖动等操作,在 WebDriver 中, 将这些关于鼠标操作的方法封装在 ActionChains 类提供。

1.鼠标操作

导入类

from selenium.webdriver import ActionChains        # 导入类

ActionChains(driver)                            # 调用 ActionChains()类, 将浏览器驱动 driver 作为参数传入。

perform() 执行所有 ActionChains 中存储的行为(接在ActionChains类之后)

右击 context_click()

from selenium import webdriver

# 导入动作链

from selenium.webdriver import ActionChains

import time

url = 'http://www.baidu.com'

driver = webdriver.Firefox()

driver.get(url)

# 创建动作池对象

acobj = ActionChains(driver)

# 定位到百度的logo图片

el_lg = driver.find_element_by_id('lg')

# 添加邮件点击动作并执行

acobj.context_click(el_lg).perform()

# print (dir(acobj))

time.sleep(5)

driver.close()

双击 double_click()

from selenium import webdriver

# 导入动作链

from selenium.webdriver import ActionChains

import time

url = 'http://www.baidu.com'

driver = webdriver.Firefox()

driver.get(url)

# 创建动作对象

acobj = ActionChains(driver)

# 定位到视频元素

el = driver.find_element_by_css_selector('a.mnav:nth-child(1)')

# 执行双击操作

acobj.double_click(el).perform()

time.sleep(5)

driver.quit()

鼠标悬停 move_to_element()

from selenium  import webdriver

from selenium.webdriver import ActionChains

import time

url = 'https://www.jd.com/'

driver = webdriver.Firefox()

driver.get(url)

#获取左侧种类元素列表

mylist = driver.find_elements_by_css_selector('li.cate_menu_item')

# print (mylist)

# 创建动作动作对象

acobj = ActionChains(driver)

for el in mylist:

    acobj.move_to_element(el).perform()

    time.sleep(3)

driver.close()

2.键盘事件

Keys()类提供了键盘上几乎所有按键的方法。 前面了解到, send_keys()方法可以用来模拟键盘输入, 除此 之外, 我们还可以用它来输入键盘上的按键, 甚至是组合键, 如 Ctrl+A、 Ctrl+C 等。

from selenium import  webdriver

from selenium.webdriver.common.keys import Keys

import time

# print (dir(Keys))

url = 'https://cn.bing.com/'

driver = webdriver.Firefox()

driver.get(url)

el = driver.find_element_by_id('sb_form_q')

el.send_keys('selenium')

# 全选并删除

el.send_keys(Keys.CONTROL,'a')

time.sleep(3)

el.send_keys(Keys.CONTROL,'x')

# 退格并回车

el.send_keys('seleniumm')

time.sleep(3)

el.send_keys(Keys.BACK_SPACE)

time.sleep(3)

el.send_keys(Keys.ENTER)

time.sleep(5)

driver.quit()

以下为常用的键盘操作:

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

4 弹出框(警告框)

在WebDriver中处理JavaScript所生成的alert、confirm以及prompt十分简单,具体做法是使用 switch_to.alert 方法定位到 alert/confirm/prompt,然后使用text/accept/dismiss/ send_keys等方法进行操作

进入到警告框中

driver.switch_to.alert             #当出现弹出框的时候,可以使用条语句进入到警告框中

text:返回 alert/confirm/prompt 中的文字信息。

accept():接受现有警告框。

dismiss():解散现有警告框。

send_keys(keysToSend):发送文本至警告框。keysToSend:将文本发送至警告框。

from selenium import webdriver

from selenium.webdriver import ActionChains

import time

url = 'http://www.baidu.com'

# 创建浏览器对象

driver = webdriver.Firefox()

# 访问百度

driver.get(url)

# 点击设置

el_set = driver.find_element_by_link_text('设置')

el_set.click()

# 点击搜索设置

el_sset = driver.find_element_by_link_text('搜索设置')

el_sset.click()

# 定位到保存按钮

el_save = driver.find_element_by_css_selector('.prefpanelgo')

el_save.click()

# 进入到弹出框,执行接受

time.sleep(3)

# driver.switch_to.alert.accept()

driver.switch_to.alert.dismiss()

time.sleep(5)

driver.quit()

5 下拉框

有时我们手动测试的时候会碰到下拉框,WebDriver提供了Select类来处理下拉框

from selenium import webdriver

from selenium.webdriver.support.select import Select

import time

url = 'http://www.baidu.com'

driver = webdriver.Firefox()

driver.get(url)

# 定位搜索按钮

el_so = driver.find_element_by_css_selector('a.pf:nth-child(8)')

el_so.click()

# 定位搜索设置按钮,并点击

el_set = driver.find_element_by_css_selector('.setpref')

el_set.click()

# 定位下拉框对象

sel = driver.find_element_by_id('nr')

# 构建选择对象

selobj = Select(sel)

# print(selobj)

# print(dir(selobj))

# 显示所有已经选择的选项

print (selobj.all_selected_options)

# 显示第一个已经选择的选项

print (selobj.first_selected_option)

# 显示所有选项

print (selobj.options)

# 使用索引选择

selobj.select_by_index(0)

time.sleep(5)

selobj.select_by_index(1)

time.sleep(5)

selobj.select_by_index(2)

# 通过值进行选择

selobj.select_by_value("20")

time.sleep(2)

selobj.select_by_value("50")

# 通过可见文本

selobj.select_by_visible_text('每页显示50条')

time.sleep(2)

selobj.select_by_visible_text('每页显示20条')

time.sleep(5)

driver.close()

Select类用于定位select标签。 select_by_value() 方法用于定位下接选项中的value值。

6 调用JavaScript代码

虽然WebDriver提供了操作浏览器的前进和后退方法,但对于浏览器滚动条并没有提供相应的操作方法。在这种情况下,就可以借助JavaScript来控制浏览器的滚动条。WebDriver提供了execute_script()方法来执行JavaScript代码。

用于调整浏览器滚动条位置的JavaScript代码如下:

window.scrollTo(0,450); window.scrollTo()方法用于设置浏览器窗口滚动条的水平和垂直位置。方法的第一个参数表示水平的左间距,第二个参数表示垂直的上边距。其代码如下:

from selenium import webdriver

import time

url = 'https://www.hao123.com/'

driver = webdriver.Firefox()

driver.get(url)

for i in range(100):

    # 滚动到固定位置

    js = 'window.scrollTo(0,%s)'%(100*i)

    # 滚动到距离顶部指定长度

    # js = "var q=document.documentElement.scrollTop=%s"%(100*i)

    driver.execute_script(js)

    time.sleep(0.1)

time.sleep(5)

driver.quit()

通过浏览器打开百度进行搜索,然后通过execute_script()方法执行JavaScripts代码来移动滚动条的位置。

7 等待

现在的网页越来越多采用了 Ajax 技术,这样程序便不能确定何时某个元素完全加载出来了。如果实际页面等待时间过长导致某个dom元素还没出来,但是你的代码直接使用了这个WebElement,那么就会抛出NullPointer的异常。

为了避免这种元素定位困难而且会提高产生 ElementNotVisibleException 的概率。所以 Selenium 提供了两种等待方式,一种是隐式等待,一种是显式等待。

隐式等待是等待特定的时间,显式等待是指定某一条件直到这个条件成立时继续执行。

1.显式等待

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

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

url = 'http://www.baidu.com'

driver = webdriver.Firefox()

driver.get(url)

# 设置显示等待

el = WebDriverWait(driver, 60, 0.5).until(EC.presence_of_element_located((By.CSS_SELECTOR,'#lh > a:nth-child(3)')))

print (el.text)

driver.close()

WebDriverWait类是由WebDirver 提供的等待方法。在设置时间内,默认每隔一段时间检测一次当前页面元素是否存在,如果超过设置时间检测不到则抛出异常。具体格式如下:

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

driver :浏览器驱动。

timeout :最长超时时间,默认以秒为单位。

poll_frequency :检测的间隔(步长)时间,默认为0.5S。

ignored_exceptions :超时后的异常信息,默认情况下抛NoSuchElementException异常。

WebDriverWait()一般由until()或until_not()方法配合使用,下面是until()和until_not()方法的说明。 until(method, message=‘’) 调用该方法提供的驱动程序作为一个参数,直到返回值为True。 until_not(method, message=‘’) 调用该方法提供的驱动程序作为一个参数,直到返回值为False。

在本例中,通过as关键字将expected_conditions 重命名为EC,并调用presence_of_element_located()方法判断元素是否存在。

2.隐式等待

WebDriver提供了implicitly_wait()方法来实现隐式等待,默认设置为0。如果不设置隐式等待的值,那么当我们进行元素定位的时候,一旦定位不到将会直接报错出来,而如果我们设置了隐式等待的值,当定位不到元素的时候,程序将在隐式等待设定时间内多次尝试定位元素,当时间超过设定的隐式等待时间,将会报错出来,它的用法相对来说要简单得多

from selenium import webdriver

import time

url = 'https://www.amazon.cn/'

driver = webdriver.Firefox()

driver.get(url)

# 设置隐式等待

driver.implicitly_wait(10)

driver.quit()

implicitly_wait()默认参数的单位为秒,本例中设置等待时长为10秒。首先这10秒并非一个固定的等待时间,它并不影响脚本的执行速度。其次,它并不针对页面上的某一元素进行等待。当脚本执行到某个元素定位时,如果元素可以定位,则继续执行;如果元素定位不到,则它将以轮询的方式不断地判断元素是否被定位到。假设在第6秒定位到了元素则继续执行,若直到超出设置时长(10秒)还没有定位到元素,则抛出异常。

8 cookies

有时候我们需要验证浏览器中cookie是否正确,因为基于真实cookie的测试是无法通过白盒和集成测试进行的。WebDriver提供了操作Cookie的相关方法,可以读取、添加和删除cookie信息。

WebDriver操作cookie的方法:

get_cookies(): 获得所有cookie信息。

get_cookie(name): 返回字典的key为“name”的cookie信息。

add_cookie(cookie_dict) : 添加cookie。“cookie_dict”指字典对象,必须有name 和value 值。

delete_cookie(name,optionsString):删除cookie信息。“name”是要删除的cookie的名称,“optionsString”是该cookie的选项,目前支持的选项包括“路径”,“域”。

delete_all_cookies(): 删除所有cookie信息。

下面通过get_cookies()来获取当前浏览器的cookie信息。

from selenium import webdriver

driver = webdriver.Firefox()

driver.get("http://www.youdao.com")

# 获得cookie信息

cookie= driver.get_cookies()

# 将获得cookie的信息打印

print(cookie)

driver.quit()

从执行结果可以看出,cookie数据是以字典的形式进行存放的。知道了cookie的存放形式,接下来我们就可以按照这种形式向浏览器中写入cookie信息。

from selenium import webdriver

driver = webdriver.Firefox()

driver.get("http://www.youdao.com")

# 向cookie的name 和value中添加会话信息

driver.add_cookie({'name': 'itcast', 'value': 'itheima'})

# 遍历cookies中的name 和value信息并打印,当然还有上面添加的信息

for cookie in driver.get_cookies():

    print("%s -> %s" % (cookie['name'], cookie['value']))

driver.quit()

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值