0
点赞
收藏
分享

微信扫一扫

隐式等待

凯约 2024-05-13 阅读 20

隐式等待是通过一定的时长等待页面所元素加载完成。哪果超出了设置的时长元素还没有被加载测抛

NoSuchElementException 异常。WebDriver 提供了 implicitly_wait()方法来实现隐式等待,默认设置为 0。它

的用法相对来说要简单的多。

baidu.py

#coding=utf-8

from selenium import webdriver

from selenium.webdriver.support.ui import WebDriverWait

driver = webdriver.Firefox()

driver.implicitly_wait(10)

input_ = driver.find_element_by_id("kw22")

input_.send_keys('selenium')

driver.quit()

implicitly_wait()默认参数的单位为秒,本例中设置等待时长为 10 秒,首先这 10 秒并非一个固定的等

待时间,它并不影响脚本的执行速度。其次,它并不真对页面上的某一元素进行等待,当脚本执行到某个

元素定位时,如果元素可定位那么继续执行,如果元素定位不到,那么它将以轮询的方式不断的判断元素

是否被定位到,假设在第 6 秒钟定位到元素则继续执行。直接超出设置时长(10 秒)还没定位到元素则抛

出异常。

在上面的例子中,显然百度输入框的定位 id=kw22 是有误的,那么在超出 10 秒后将抛出异常。

Python Shell

>>> ================================ RESTART ================================

>>>

Traceback (most recent call last):

File "C:\Users\fnngj\Desktop\aaa.py", line 19, in <module>

bb = driver.find_element_by_id("kw22")

File "C:\Python27\lib\site-packages\selenium\webdriver\remote\webdriver.py",

line 206, in find_element_by_id

return self.find_element(by=By.ID, value=id_)

File "C:\Python27\lib\site-packages\selenium\webdriver\remote\webdriver.py",

line 662, in find_element

{'using': by, 'value': value})['value']

File "C:\Python27\lib\site-packages\selenium\webdriver\remote\webdriver.py",

line 173, in execute

self.error_handler.check_response(response)

File

"C:\Python27\lib\site-packages\selenium\webdriver\remote\errorhandler.py",

line 166, in check_response

raise exception_class(message, screen, stacktrace)

NoSuchElementException: Message: Unable to locate element:

{"method":"id","selector":"kw22"}

sleep 休眠方法

有时间我们希望脚本执行到某一位置时做固定时间的休眠,尤其是在脚本调试的过程中。那么可以使用 sleep()方法,需要说明的是 sleep()由 Python 的 time 模块提供。

baidu.py

#coding=utf-8

from selenium import webdriver

from time import sleep

driver = webdriver.Firefox()

sleep(2)

driver.find_element_by_id("kw").send_keys("webdriver")

driver.find_element_by_id("su").click()

sleep(3)

driver.quit()

当执行到 sleep()方法时会固定的休眠所设置的时长,然后再继续执行。sleep()方法默认参数以秒为单

位,如果设置时长小于 1 秒,可以用小数点表示,如:sleep(0.5)

定位一组元素

在本章的第一节我们已经学习了 8 种定位方法,那 8 种定位方法是真对单元素定位的,WebDriver 还

提供了与之对应的 8 种定位方法用于定位一组元素。

find_elements_by_id()

find_elements_by_name()

find_elements_by_class_name()

find_elements_by_tag_name()

find_elements_by_link_text()

find_elements_by_partial_link_text()

find_elements_by_xpath()

find_elements_by_css_selector()

定位一组对象的方法与定位单个对象的方法类似,唯一的区别是在单词 element 后面多了一个 s 表示

复数。定位一组对象一般用于以下场景:

 批量操作对象,比如将页面上所有的复选框都被勾选。

先获取一组对象,再在这组对象中过滤出需要具体定位的一些对象。比如定位出页面上所有的

checkbox,然后选择最后一个。

checkbox.html

<html>

<head>

<meta http-equiv="content-type" content="text/html;charset=utf-8" />

<title>Checkbox</title>

</head>

<body>

<h3>checkbox</h3>

<div class="well">

<form class="form-horizontal">

<div class="control-group">

<label class="control-label" for="c1">checkbox1</label>

<div class="controls">

<input type="checkbox" id="c1" />

</div>

</div>

<div class="control-group">

<label class="control-label" for="c2">checkbox2</label>

<div class="controls">

<input type="checkbox" id="c2" />

</div>

</div>

<div class="control-group">

<label class="control-label" for="c3">checkbox3</label>

<div class="controls">

<input type="checkbox" id="c3" />

</div>

</div>

</form>

</div>

</body>

</html>

这里手动创建一个 checkbox.html 的页面,通过浏览器打开,效果如图。

为了使页面更美观,在代码中添加了 bootstrap 在线样式的引用。下面就通过例子来操作页面上的这一

组复选框。

checkbox.py

#coding=utf-8

from selenium import webdriver

import os

driver = webdriver.Firefox()

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()

前面在提到通过 tag name 的定位方式很难定位到单个元素,因为元素标签名重复的概率很高。那么在

定位一组元素时,这种方式就派上了用场。上面的例子中先通过 find_elements_by_tag_name()找到一组标

签名为 input 的元素。然后通过 for 循环进行遍历。在遍历的过程中通过 get_attribute()方法获取元素的 type

属性,判断是否为“chcckbox”,如果为“chcckbox”那么这个元素就是一个复选框。对其进行 click()勾

选操作。

在本例中,因为通过浏览器打开的是一个本地的 html 文件,所以需要用到 Python 的 os 模块,

path.abspath()方法用于获取当前路径下的文件。

除此之外,我们也可以使用 XPath 或 CSS 来判断属性值,从而进行点击操作。

checkbox.py

#coding=utf-8

from selenium import webdriver

import os

driver = webdriver.Firefox()

driver.get(file_path)

#通过 XPath 找到 type=checkbox 的元素

#checkboxes = driver.find_elements_by_xpath("//input[@type='checkbox']")

#通过 CSS 找到 type=checkbox 的元素

checkboxes = driver.find_elements_by_css_selector('input[type=checkbox]')

for checkbox in checkboxes:

checkbox.click()

# 打印当前页面上 type 为 checkbox 的个数

print len(checkboxes)

# 把页面上最后 1 个 checkbox 的勾给去掉

driver.find_elements_by_css_selector('input[type=checkbox]').pop().click()

driver.quit()

通过 XPath 或 CSS 来查找一组元素,少去判断步骤,因为它本身已经做了判断,只需要循环对每一

个元素进行 click()勾选即可。

除此之外例子中还用到了 Python 所提供的两个有趣的方法。len()可获取元素的个数,通过 print 打印

会得到一个 3 的结果。pop() 函数用于获取列表中的一个元素(默认为最后一个元素),并且返回该元素

的值。因为前的循环已经所有复选框都勾选上了,再对这一组元素执行 pop().lick() 其实是对后一个元素取

消勾选。如果只想勾选一组元素中的某一个呢。

pop()或 pop(-1) 默认获取一组元素中的最后一个。

pop(0) 默认获取一组元素中的第一个。

pop(1) 默认获取一组元素中的第二个。

……

这样就可以操作这一组元素中的元素了,只用数一数操作的元素是这一组中的第几个。

举报

相关推荐

0 条评论