Python + Selenium: expected_conditions介绍

expected_conditions是Selenium的一个模块,selenium.webdriver.support.expected_conditions,可以对网页上元素是否存在,可点击等等进行判断,一般用于断言或与WebDriverWait配合使用。上一次介绍WebDriverWait的时候就曾经提过,WebDriverWait中的until()和until_not()中的方法,必须是可调用的方法,我们可以自己写一个类(正如上次介绍中的实例那样),也可以使用匿名函数,再就是可以使用expected_conditions。
下面是今天举例中使用的网页,请保存为test.html,放在与脚本相同的文件夹中。

<html>
    <head>
        <title>this is title</title>
        
        <script type='text/javascript' src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
        <script type='text/javascript'>
            function myFunction(){
                window.alert('this is alert')
            }

            $(document).ready(function(){
                $("#button3").click(function(){
                    $('#p2').hide();
                });
                $("#button4").click(function(){
                    $('#p1').remove();
                });
            });
        </script>
    </head>
    <body>
        <h1>head 1</h1>
        <p id='p1'>paragraph</p>
        <p id='p2'>paragraph2</p>
        <button type='button' onclick='myFunction()' id='button1' class='test'>this is button1</button>
        <button type='button' id='button2' disabled='disabled'>this is button2</button>
        <button type='button' id='button3'>this is button3</button>
        <button type='button' id='button4'>this is button4</button>
        <label><input type='checkbox' id='checkbox1'>checkbox</label>
        <br>
        <a href="https://www.baidu.com/" target='_blank' id='link'>baidu</a>
        <br>
        <iframe src="https://www.baidu.com/" width='750px' height='350px'></iframe>
    </body>
</html>

介绍说明

expected_conditions中包含了很多的类,我们今天讲解一部分,并附有详细脚本说明。

1. selenium.webdriver.support.expected_conditions.alert_is_present

判断alert是否存在,若存在则切换到alert,若不存在则返回false

# coding = utf-8
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import os

driver = webdriver.Chrome()
driver.implicitly_wait(5)
file = "file:///" + os.path.abspath("test.html")
driver.get("https://www.baidu.com")
alert = EC.alert_is_present()
if alert(driver):
    print(alert(driver).text) #若alert存在打印alert上text
    alert(driver).accept() #若存在点击alert上的【确认按钮】
else :
    print(alert(driver)) #若不存在,打印会显示False
    print('no alert') 
driver.quit()

2. selenium.webdriver.support.expected_conditions.element_selection_state_to_be(element, is_selected)

判断某元素的选中状态是否与预期相同,相同则返回True,不同则返回False

# coding = utf-8
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import os

driver = webdriver.Chrome()
driver.implicitly_wait(5)
file = "file:///" + os.path.abspath("test.html")
driver.get("https://www.baidu.com")
checkbox = driver.find_element_by_id('checkbox1')
for n in range(2): #循环2次
    checkbox.click() #第一次点击checkbox,checkbox为选中状态,第二次循环再点击则不在选中状态
    element = EC.element_selection_state_to_be(checkbox,True) #第一次返回结果True,第二次为False
    print(element(driver))
driver.quit()

3. selenium.webdriver.support.expected_conditions.element_located_to_be_selected(locator)

判断某元素是否被选中,locator为一个(by, path)元祖,这个(by, path)的by是Selenium的一个类(selenium.webdriver.common.by.By),包括CLASS_NAME,CSS_SELECTOR,ID,LINK_TEXT,NAME,PARTIAL_LINK_TEXT,TAG_NAME和XPATH,和我们元素定位中使用的方法相同

# coding = utf-8
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By #使用By需要导入包
import os

driver = webdriver.Chrome()
driver.implicitly_wait(5)
file = "file:///" + os.path.abspath("test.html")
driver.get(file)
locator = (By.ID, 'checkbox1') #使用ID来定义这个元祖
for n in range(2): #循环2次,和上面的element_selection_state_to_be(element, is_selected)相同
    driver.find_element_by_id('checkbox1').click()
    element = EC.element_located_to_be_selected(locator)
    print(element(driver))
driver.quit()

4. selenium.webdriver.support.expected_conditions.element_to_be_selected(element)

判断某元素是否被选中,这个与上面是重复的,只是使用的参数不同,不举例了

5. selenium.webdriver.support.expected_conditions.element_located_selection_state_to_be(locator, is_selected)

判断某元素是否与预期相同,相同则返回True,不同则返回False,locator为一个(by, path)元祖,这个就属于前面的结合了,也不举例了

6. selenium.webdriver.support.expected_conditions.element_to_be_clickable(locator)

判断某元素是否可访问并且可启用,比如能够点击,若可以则返回元素本身,否则返回False。locator为一个元祖(by, path)

# coding = utf-8
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
import os

driver = webdriver.Chrome()
driver.implicitly_wait(5)
file = "file:///" + os.path.abspath("test.html")
driver.get(file)
locator = (By.ID, 'button2') #button是一个不可点击的按钮
locator2 = (By.ID, 'p2') #一个普通的段落
element = EC.element_to_be_clickable(locator)
element2 = EC.element_to_be_clickable(locator2)
print('button2 result : ', element(driver)) #打印button2的结果为False
print('<p> result : ', element2(driver)) #打印<p>段落结果返回元素本身
driver.quit()

7. selenium.webdriver.support.expected_conditions.frame_to_be_available_and_switch_to_it(locator)

判断某个frame是否可以切换过去,若可以则切换到该frame,否则返回False ,locator为一个元祖(by, path)

# coding = utf-8
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
import os

driver = webdriver.Chrome()
driver.implicitly_wait(5)
file = "file:///" + os.path.abspath("test.html")
driver.get(file)
try :
    driver.find_element_by_id('kw').send_keys('test') #给内嵌iframe的百度网页搜索框中输入test
except Exception as msg:
    print('error is : ', msg) #由于没有切换到内嵌的iframe,会报错
finally:
    locator = (By.XPATH, 'html/body/iframe') #定义iframe的locator
    element = EC.frame_to_be_available_and_switch_to_it(locator) #判断是否能切换
    if element(driver):
        driver.find_element_by_id('kw').send_keys('test') #可以切换,再一次在百度输入test
        print('switch successed') #打印成功
    else :
        print(element(driver)) #若不能则返回False
    driver.quit()

8. selenium.webdriver.support.expected_conditions.invisibility_of_element_located(locator)

判断某个元素是不是不可访问或者不存在在DOM树中,不存在则返回True,存在则返回True,locator是一个元祖(by, path)

# coding = utf-8
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
import os

driver = webdriver.Chrome()
driver.implicitly_wait(5)
file = "file:///" + os.path.abspath("test.html")
driver.get(file)
locator = (By.ID, 'button4') #一个并不存在的元素
element = EC.invisibility_of_element_located(locator)
print(element(driver)) #会返回True
driver.quit()

9. selenium.webdriver.support.expected_conditions.new_window_is_opened(current_handles)

通过是否增加了句柄数量判断是否打开新窗口,有新窗口则返回True,没有新窗口返回False

# coding = utf-8
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import os

driver = webdriver.Chrome()
driver.implicitly_wait(5)
file = "file:///" + os.path.abspath("test.html")
driver.get(file)
current_handles = driver.window_handles #获得当前所有句柄数量
new_window = EC.new_window_is_opened(current_handles)
print('before click, is there new window? ', new_window(driver)) #没有新窗口,会打印False
driver.find_element_by_id('link').click() #点击一个链接
new_window_2 = EC.new_window_is_opened(current_handles) #再次获得当前所有句柄数量
print('after click, is there new window? ',new_window_2(driver)) #有新窗口,会打印True
driver.quit()

10. selenium.webdriver.support.expected_conditions.number_of_windows_to_be(num_windows)

判断窗口数量是否是特定数值,是该数值则返回True,否则返回False

# coding = utf-8
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
import os

driver = webdriver.Chrome()
driver.implicitly_wait(5)
file = "file:///" + os.path.abspath("test.html")
driver.get(file)
windows = EC.number_of_windows_to_be(2) #期望窗口我们设置2个
print('now there is 2 windows? ', windows(driver)) #初始化页面只有一个窗口,会返回False
driver.find_element_by_id('link').click() #点击一下页面内的链接
print('now there is 2 windows? ',windows(driver)) #页面点击后有2个窗口了,会返回True
driver.quit()
11. selenium.webdriver.support.expected_conditions.presence_of_all_elements_located(locator)

判断定位的元素范围内,至少有一个元素存在于页面当中,存在则以list形式返回元素本身,不存在则报错

# coding = utf-8
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
import os

driver = webdriver.Chrome()
driver.implicitly_wait(5)
file = "file:///" + os.path.abspath("test.html")
driver.get(file)
locator = (By.CLASS_NAME, 'test') #定位所有class='test'的元素
element = EC.presence_of_all_elements_located(locator)
print(element(driver))
driver.quit()

12. selenium.webdriver.support.expected_conditions.presence_of_element_located(locator)

判断一个元素存在于页面DOM树中,存在则返回元素本身,不存在则报错。这个和上面的基本一样,不举例了。

13. selenium.webdriver.support.expected_conditions.staleness_of(element)

判断某个元素是否不再附加于于DOM树中,不再附加的话返回True,依旧存在返回False

# coding = utf-8
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import os

driver = webdriver.Chrome()
driver.implicitly_wait(5)
file = "file:///" + os.path.abspath("inner.html")
driver.get(file)
element = EC.staleness_of(driver.find_element_by_id('p1'))
print(element(driver)) #第一个<p>存在于DOM树中,返回False
driver.find_element_by_id('button4').click() #点击按钮移除<p>
print(element(driver)) #返回True
driver.quit()

14. selenium.webdriver.support.expected_conditions.text_to_be_present_in_element(locator, text_)

判断给定文本是否出现在特定元素中,若存在则返回True,不存在返回False

# coding = utf-8
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
import os

driver = webdriver.Chrome()
driver.implicitly_wait(5)
file = "file:///" + os.path.abspath("test.html")
driver.get(file)
locator = (By.ID, 'p2')
element = EC.text_to_be_present_in_element(locator, 'para') #查看<p>文本中是否包含'para'
print(element(driver)) #返回True
driver.quit()

15. selenium.webdriver.support.expected_conditions.text_to_be_present_in_element_value(locator, text_)

判断某文本是否是存在于特定元素的value值中,存在则返回True,不存在则返回False,对于查看没有value值的元素,也会返回False

# coding = utf-8
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
import os

driver = webdriver.Chrome()
driver.implicitly_wait(5)
file = "file:///" + os.path.abspath("test.html")
driver.get(file)
locator = (By.ID, 'p2')
element = EC.text_to_be_present_in_element_value(locator, 'para') #查看<p>的value值中是否包含'para'
print(element(driver)) # <p>没有value值,所以会返回False
driver.quit()

16. selenium.webdriver.support.expected_conditions.title_contains(title)

判断网页title是否包含特定文本(英文区分大小写),若包含则返回True,不包含返回False

# coding = utf-8
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import os

driver = webdriver.Chrome()
driver.implicitly_wait(5)
file = "file:///" + os.path.abspath("test.html")
driver.get(file)
element = EC.title_contains('This') #查看网页title是否包含'This'
print(element(driver)) #网页的title是'this is title',由于区分大小写,所以返回False
driver.quit()

17. selenium.webdriver.support.expected_conditions.title_is(title)

判断网页title是否是特定文本(英文区分大小写),若完全相同则返回True,否则返回False

# coding = utf-8
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import os

driver = webdriver.Chrome()
driver.implicitly_wait(5)
file = "file:///" + os.path.abspath("test.html")
driver.get(file)
element = EC.title_is('this is title') #查看网页title是否是'this is title'
print(element(driver)) #完全匹配,返回True
driver.quit()

18. selenium.webdriver.support.expected_conditions.url_changes(url)

判断网页是否更改了,若更改了则返回True,若没有更改则返回False
本例中需要切换窗口才能获得新窗口的URL(driver需要你帮助它切换,不会打开新窗口就自动切换)

# coding = utf-8
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import os

driver = webdriver.Chrome()
driver.implicitly_wait(5)
file = "file:///" + os.path.abspath("test.html")
driver.get(file)
current_window = driver.current_window_handle #获取当前窗口句柄
driver.find_element_by_id('link').click() #点击link迁移到新窗口
all_windows = driver.window_handles # 获取所有窗口句柄
for w in all_windows: # 利用for循环,切换到新窗口
    if w != current_window:
        driver.switch_to_window(w)
element = EC.url_changes(file) #与初始网址对比查看新窗口网址是否变化
print(element(driver)) #网址变更,返回True
driver.quit() 

19. selenium.webdriver.support.expected_conditions.url_contains(url)

判断网址是否包含特定文本(区分大小写),包含则返回True,不包含则返回False

# coding = utf-8
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import os

driver = webdriver.Chrome()
driver.implicitly_wait(5)
file = "file:///" + os.path.abspath("test.html")
driver.get(file)
delement = EC.url_contains('Test') #查看网页是否包含'Test'
print(element(driver)) #区分大小写,所以返回False
driver.quit()

20. selenium.webdriver.support.expected_conditions.url_matches(pattern)

判断网址是否符合特定格式,符合则返回True,不符合则返回False

# coding = utf-8
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import os

driver = webdriver.Chrome()
driver.implicitly_wait(5)
file = "file:///" + os.path.abspath("test.html")
driver.get(file)
current_window = driver.current_window_handle
driver.find_element_by_id('link').click()
all_windows = driver.window_handles
for w in all_windows: # 利用for循环,切换到新窗口
    if w != current_window:
        driver.switch_to_window(w)
pattern = r'(https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&amp;:/~\+#]*[\w\-\@?^=%&amp;/~\+#])?' #使用正则表达式,规定网址格式(格使要求以https开头)
element = EC.url_matches(pattern) #查看是否以https开头
print(element(driver)) #符合则返回True
driver.quit()

21. selenium.webdriver.support.expected_conditions.url_to_be(url)

判断网页是否为特定网页(必须完全符合),是则返回True,否则返回False

# coding = utf-8
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import os

driver = webdriver.Chrome()
driver.implicitly_wait(5)
file = "file:///" + os.path.abspath("test.html")
driver.get(file)
current_window = driver.current_window_handle
driver.find_element_by_id('link').click()
all_windows = driver.window_handles
for w in all_windows: #切换到新窗口
    if w != current_window:
        driver.switch_to_window(w)
url = 'https://www.baidu.com' #查看的特定网址
element = EC.url_to_be(url) #判断是否符合
print(element(driver)) # 结果返回False
print(driver.current_url) #打印当前网址'https://www.baidu.com/',结尾有'/',与期待网址不完全相同
driver.quit()

22. selenium.webdriver.support.expected_conditions.visibility_of_element_located(locator)

判断特定元素是否存在于DOM树中并且可见,可见意为元素的高和宽都大于0,元素存在返回元素本身,否则返回False
这个类和presence_of_element_located(locator)有点像,但后者只强调元素存在于DOM树中,可见不可见无所谓,而前者要求必须高和宽必须都大于0,因此后者在性能上会稍微快一点点

# coding = utf-8
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
import os

driver = webdriver.Chrome()
driver.implicitly_wait(5)
file = "file:///" + os.path.abspath("test.html")
driver.get(file)
locator = (By.ID, 'p2') #定位第二个<p>
presence_element = EC.presence_of_element_located(locator) #persence寻找第二个<p>
visibility_element = EC.visibility_of_element_located(locator) #visibility寻找第二个<p>
driver.find_element_by_id('button3').click() #点击按钮,隐藏第二个<p>
print('presence result : ',presence_element(driver)) #打印presence结果,<p>存在于DOM树中,返回元素本身
print('visibility result : ', visibility_element(driver)) #打印visibility结果,元素隐藏,高和宽都为0,因此返回False
driver.quit()

23. selenium.webdriver.support.expected_conditions.visibility_of(element)

同上面一样,不过参数从locator的元组变为元素

# coding = utf-8
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
import os

driver = webdriver.Chrome()
driver.implicitly_wait(5)
file = "file:///" + os.path.abspath("test.html")
driver.get(file)
driver.find_element_by_id('button3').click()#点击按钮,隐藏第二个<p>
element = EC.visibility_of(driver.find_element_by_id('p2'))
print(element(driver)) #元素隐藏,所以返回False
driver.quit()

24. selenium.webdriver.support.expected_conditions.visibility_of_all_elements_located(locator)

判断locator定位的所有元素都存在于DOM树中并且可见,可见意为元素高和宽都大于0,存在则以list形式返回元素,否则返回False

# coding = utf-8
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
import os

driver = webdriver.Chrome()
driver.implicitly_wait(5)
file = "file:///" + os.path.abspath("test.html")
driver.get(file)
locator = (By.TAG_NAME, 'p')
element = EC.visibility_of_all_elements_located(locator) 
print(element(driver)) #以list形式返回所有<p>元素
driver.find_element_by_id('button3').click() 
print(element(driver)) #由于一个<p>元素隐藏了,返回False
driver.quit()

25. selenium.webdriver.support.expected_conditions.visibility_of_any_elements_located(locator)

判断locator定位的所有元素中,至少有一个存在于DOM树中并且可见,可见意为元素高和宽都大于0,list形式返回存在的元素,一个元素都不存在的情况下返回空list

# coding = utf-8
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
import os

driver = webdriver.Chrome()
driver.implicitly_wait(5)
file = "file:///" + os.path.abspath("test.html")
driver.get(file)
locator = (By.TAG_NAME, 'p')
driver.find_element_by_id('button3').click() #点击隐藏第二个<p>
element = EC.visibility_of_any_elements_located(locator)
print(element(driver)) #返回第一个<p>元素
driver.quit()

expected_conditions这就介绍完了,相关脚本代码可以去这里下载查看:源码下载。以前介绍过的其他API的sample代码会陆续上传。



欢迎订阅我的公众号:进击的小QA,第一时间收到文章推送哦

微信

  • 16
    点赞
  • 72
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值