Python selenium经验总结

目录

Selenium2+python自动化47-判断弹出框存在(alert_is_present)

Python selenium 显示等待WebDriverWait与条件判断expected_conditions举例

Custom Wait Conditions 自定义等待条件

Selenium元素定位不到、出错原因汇总

1.CSS选择器不规范

2.元素在iframe中,需切换

3.className不允许使用复合类名做参数



Selenium2+python自动化47-判断弹出框存在(alert_is_present)

Selenium2+python自动化47-判断弹出框存在(alert_is_present)

来源:https://www.cnblogs.com/yoyoketang/

扫描二维码关注公众号,回复: 3330034 查看本文章

前言

系统弹窗这个是很常见的场景,有时候它不弹出来去操作的话,会抛异常。那么又不知道它啥时候会出来,那么久需要去判断弹窗是否弹出了。

本篇接着Selenium2+python自动化42-判断元素(expected_conditions)讲expected_conditions这个模块

一、判断alert源码分析

class alert_is_present(object):
    """ Expect an alert to be present."""

    """判断当前页面的alert弹窗"""
    def __init__(self):
        pass

    def __call__(self, driver):
        try:
            alert = driver.switch_to.alert
            alert.text
            return alert
        except NoAlertPresentException:
            return False

1.这个类比较简单,初始化里面无内容

2.__call__里面就是判断如果正常获取到弹出窗的text内容就返回alert这个对象(注意这里不是返回Ture),没有获取到就返回False

二、实例操作

1.前面的操作步骤优化了下,为了提高脚本的稳定性,确保元素出现后操作,

这里结合WebDriverWait里的方法:Selenium2+python自动化38-显式等待(WebDriverWait)

2.实现步骤如下,这里判断的结果返回有两种:没找到就返回False;找到就返回alert对象

3.先判断alert是否弹出,如果弹出就点确定按钮accept()

三、参考代码

# coding:utf-8
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.support.select import Select
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Firefox()
url = "https://www.baidu.com"
driver.get(url)
mouse = WebDriverWait(driver, 10).until(lambda x: x.find_element("link text", "设置"))
ActionChains(driver).move_to_element(mouse).perform()
WebDriverWait(driver, 10).until(lambda x: x.find_element("link text", "搜索设置")).click()
# 选择设置项
s = WebDriverWait(driver, 10).until(lambda x: x.find_element("id", "nr"))
Select(s).select_by_visible_text("每页显示50条")
# 点保存按钮
js = 'document.getElementsByClassName("prefpanelgo")[0].click();'
driver.execute_script(js)
# 判断弹窗结果 
result = EC.alert_is_present()(driver)
if result:
    print result.text
    result.accept()
else:
    print "alert 未弹出!"

Python selenium 显示等待WebDriverWait与条件判断expected_conditions举例

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

base_url = "http://www.baidu.com"
driver = webdriver.Firefox()
driver.implicitly_wait(5)
'''隐式等待和显示等待都存在时,超时时间取二者中较大的'''
locator = (By.ID,'kw')
driver.get(base_url)

WebDriverWait(driver,10).until(EC.title_is(u"百度一下,你就知道"))
'''判断title,返回布尔值'''

WebDriverWait(driver,10).until(EC.title_contains(u"百度一下"))
'''判断title,返回布尔值'''

WebDriverWait(driver,10).until(EC.presence_of_element_located((By.ID,'kw')))
'''判断某个元素是否被加到了dom树里,并不代表该元素一定可见,如果定位到就返回WebElement'''

WebDriverWait(driver,10).until(EC.visibility_of_element_located((By.ID,'su')))
'''判断某个元素是否被添加到了dom里并且可见,可见代表元素可显示且宽和高都大于0'''

WebDriverWait(driver,10).until(EC.visibility_of(driver.find_element(by=By.ID,value='kw')))
'''判断元素是否可见,如果可见就返回这个元素'''

WebDriverWait(driver,10).until(EC.presence_of_all_elements_located((By.CSS_SELECTOR,'.mnav')))
'''判断是否至少有1个元素存在于dom树中,如果定位到就返回列表'''

WebDriverWait(driver,10).until(EC.visibility_of_any_elements_located((By.CSS_SELECTOR,'.mnav')))
'''判断是否至少有一个元素在页面中可见,如果定位到就返回列表'''

WebDriverWait(driver,10).until(EC.text_to_be_present_in_element((By.XPATH,"//*[@id='u1']/a[8]"),u'设置'))
'''判断指定的元素中是否包含了预期的字符串,返回布尔值'''

WebDriverWait(driver,10).until(EC.text_to_be_present_in_element_value((By.CSS_SELECTOR,'#su'),u'百度一下'))
'''判断指定元素的属性值中是否包含了预期的字符串,返回布尔值'''

#WebDriverWait(driver,10).until(EC.frame_to_be_available_and_switch_to_it(locator))
'''判断该frame是否可以switch进去,如果可以的话,返回True并且switch进去,否则返回False'''
#注意这里并没有一个frame可以切换进去

WebDriverWait(driver,10).until(EC.invisibility_of_element_located((By.CSS_SELECTOR,'#swfEveryCookieWrap')))
'''判断某个元素在是否存在于dom或不可见,如果可见返回False,不可见返回这个元素'''
#注意#swfEveryCookieWrap在此页面中是一个隐藏的元素

WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.XPATH,"//*[@id='u1']/a[8]"))).click()
'''判断某个元素中是否可见并且是enable的,代表可点击'''
driver.find_element_by_xpath("//*[@id='wrapper']/div[6]/a[1]").click()
#WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.XPATH,"//*[@id='wrapper']/div[6]/a[1]"))).click()

#WebDriverWait(driver,10).until(EC.staleness_of(driver.find_element(By.ID,'su')))
'''等待某个元素从dom树中移除'''
#这里没有找到合适的例子

WebDriverWait(driver,10).until(EC.element_to_be_selected(driver.find_element(By.XPATH,"//*[@id='nr']/option[1]")))
'''判断某个元素是否被选中了,一般用在下拉列表'''

WebDriverWait(driver,10).until(EC.element_selection_state_to_be(driver.find_element(By.XPATH,"//*[@id='nr']/option[1]"),True))
'''判断某个元素的选中状态是否符合预期'''

WebDriverWait(driver,10).until(EC.element_located_selection_state_to_be((By.XPATH,"//*[@id='nr']/option[1]"),True))
'''判断某个元素的选中状态是否符合预期'''
driver.find_element_by_xpath(".//*[@id='gxszButton']/a[1]").click()

instance = WebDriverWait(driver,10).until(EC.alert_is_present())
'''判断页面上是否存在alert,如果有就切换到alert并返回alert的内容'''
print instance.text
instance.accept()

driver.close()

Custom Wait Conditions 自定义等待条件

官方示例:

您也可以创建自定义的等待条件,而之前的便利方法都不符合您的要求。自定义的等待条件可以使用一个类来创建,该类在条件不匹配时返回false。

"""在Python\Python36\Lib\site-packages\selenium\webdriver\support\expected_conditions.py文件中加入如下代码:"""
class element_has_css_class(object):
  """An expectation for checking that an element has a particular css class.

  locator - used to find the element
  returns the WebElement once it has the particular css class
  """
  def __init__(self, locator, css_class):
    self.locator = locator
    self.css_class = css_class

  def __call__(self, driver):
    element = driver.find_element(*self.locator)   # Finding the referenced element
    if self.css_class in element.get_attribute("class"):
        return element
    else:
        return False


# Wait until an element with id='myNewInput' has class 'myCSSClass'
wait = WebDriverWait(driver, 10)
element = wait.until(element_has_css_class((By.ID, 'myNewInput'), "myCSSClass"))

Selenim判断一个字符串的长度:

"""在Python\Python36\Lib\site-packages\selenium\webdriver\support\expected_conditions.py文件中加入如下代码:"""
class text_len_to_be(object):

  def __init__(self, locator, _len):
    self.locator = locator
    self._len = _len

  def __call__(self, driver):
    element = driver.find_element(*self.locator)   # Finding the referenced element
    if len(element.get_attribute("value")) == self._len:
        return element
    else:
        return False

#实例:
#如果填入的验证码的长度是4就返回这个元素
yzm_len = WebDriverWait(browser, 60, 1).until(
        EC.text_len_to_be((By.CSS_SELECTOR, '#verify'), 4)
    )

Selenium元素定位不到、出错原因汇总

1.CSS选择器不规范

InvalidSelectorException: Message: invalid selector: An invalid or illegal selector was specified

有答友提供线索,貌似用By.CSS_Selector来定位组件时,#后面的id、class不能是数字、标点开头的,否则会报错

填入正确的css即可

2.元素在iframe中,需切换

在网页用QQ登录的时候,蓝色方框中的元素在name="ptlogin_iframe"的iframe中

需要切入才能操作:

browser.switch_to.frame(browser.find_element_by_id('ptlogin_iframe')) #切入
choice = wait.until(
        EC.element_to_be_clickable((By.CSS_SELECTOR, 'XXXXXXX XXX'))
)
choice.click()
browser.switch_to_default_content() #切出

3.className不允许使用复合类名做参数

当使用class定位元素时发现报错:

技术分享

错误信息:selenium.common.exceptions.InvalidSelectorException: Message: Compound class names not permitted(复合类的名称不允许)

网上查询资料得知:

className不允许使用复合类名做参数【原文】

真实环境中元素往往使用复合类名(即多个class用空格分隔),使用className定位时要注意了,className的参数只能是一个class。

例如图中显示的className名称为:btn btn-primary btn-md btn-block loginbutton log,我们要使用className定位这个元素。

如果取class全称则会报上面图中的错误,如果取一个class名driver.find_element_by_class_name("log").click(),则不会报错。

猜你喜欢

转载自blog.csdn.net/qq_38316655/article/details/81989232