【问题标题】:Python Selenium WebDriver. Writing my own expected conditionPython Selenium 网络驱动程序。写我自己的预期条件
【发布时间】:2013-10-23 00:48:57
【问题描述】:

我正在尝试编写自己的预期条件。我需要什么...我有一个 iframe。我也有一张图片。当图像的 scr 发生变化时,我想继续处理。我做了什么:

class url_changed_condition(object):
    '''
    Checks whether url in iframe has changed or not
    '''
    def __init__(self, urls):
        self._current_url, self._new_url = urls

    def __call__(self, ignored):
        return self._current_url != self._new_url  

后来在我的代码中:

def process_image(self, locator, current_url):
    try:
        WebDriverWait(self.driver, 10).until(ec.presence_of_element_located((By.TAG_NAME, u"iframe")))
        iframe = self.driver.find_element(*locator)
        if iframe:
            print "Iframe found!"
        self.driver.switch_to_frame(iframe)
        WebDriverWait(self.driver, 10).until(ec.presence_of_element_located((By.XPATH, u"//div")))

        # WebDriverWait(self.driver, 10).until(
            # url_changed_condition(
                # (current_url, self.driver.find_element(By.XPATH, u"//a/img").get_attribute(u"src"))))

        img_url = self.driver.find_element(By.XPATH, u"//a/img").get_attribute(u"src")
        print img_url
        self.search_dict[self._search_item].append(img_url)
        self.driver.switch_to_default_content()
    except NoSuchElementException as NSE:
        print "iframe not found! {0}".format(NSE.msg)
    except:
        print "something went wrong"
        import traceback
        import sys
        type_, value_, trace_ = sys.exc_info()
        print type_, value_
        print traceback.format_tb(trace_)
    finally:
        return current_url  

此代码有效,但多次返回相同的 url。问题是,当我取消注释 url_changed_condition 时,它与TimeoutException 一起出现在
(current_url, self.driver.find_element(By.XPATH, u"//a/img").get_attribute(u"src"))
它下面的行工作正常......我不明白。

【问题讨论】:

    标签: python xpath selenium


    【解决方案1】:

    此主题似乎缺少自定义预期条件的示例

    其实很简单。首先,什么是Expected Condition in Python selenium bindings

    有一大堆built-in expected condition classes

    让我们通过例子来工作。假设我们想要等到元素的文本以所需文本开头

    from selenium.webdriver.support import expected_conditions as EC
    
    class wait_for_text_to_start_with(object):
        def __init__(self, locator, text_):
            self.locator = locator
            self.text = text_
    
        def __call__(self, driver):
            try:
                element_text = EC._find_element(driver, self.locator).text
                return element_text.startswith(self.text)
            except StaleElementReferenceException:
                return False
    

    用法:

    WebDriverWait(driver, 10).until(wait_for_text_to_start_with((By.ID, 'myid'), "Hello, World!"))
    

    【讨论】:

    • 对于使用 Selenium 4 的人,将 EC._find_element ... 更改为: element_text = driver.find_element(*self.locator).text
    【解决方案2】:

    使用@alecxe 描述的技术,但稍作修改以应对接受元素而不是定位器的预期条件: (在这种情况下,由于没有selenium.webdriver.support.expected_conditions.invisibility_of(element),我正在等待is_displayed()方法发出False信号)

    class wait_for_element_to_be_invisible(object):
        def __init__(self, element):
            self.element = element
    
        def __call__(self, driver):
            return not(self.element.is_displayed())
    
    def test_collapsible_blocks_expand_or_collapse(self):
        self.browser.get(self.server_url+'/courses/1/')
        shadables = self.browser.find_elements_by_class_name('shade')
        for shadable in shadables:
            ## parent, then sibling element (*)
            shady_bit = shadable.find_element_by_xpath('../following-sibling::*')
            element = WebDriverWait(self.browser, 10).until(
                EC.visibility_of(shady_bit))
            shadable.click()
            element = WebDriverWait(self.browser, 10).until(
                self.wait_for_element_to_be_invisible(shady_bit))
    

    带有 DOM 相关位的 HTML 片段是:

    <h4 class="shadable"><span class="shade" title="Show/Hide">↓</span>
      <a href="/link/to/uri">Title of Section</a>
    </h4>
    <article class="abstract">
      <p>Descriptive part which is shadable
      </p>
    </article>`
    

    【讨论】:

      【解决方案3】:

      根据documentation

      WebDriverWait 默认每 500 次调用 ExpectedCondition 毫秒,直到它成功返回。 成功的回报是 ExpectedCondition 类型为 Boolean 返回 true 或非 null 返回值 对于所有其他 ExpectedCondition 类型。

      如果您注释掉自定义等待,您会多次获得相同的 URL,这一事实应该会给您一个提示。

      __call__() 中,您总是返回False,因为网址永远不会改变。由于您要返回 False,因此永远不会满足 ExpectedCondition,您会得到 TimeoutException

      所以要么重新定义 ExpectedCondition 逻辑,要么测试不同的情况。

      【讨论】:

      • 你告诉我的正是我所知道的。你的答案正是我在这里编码的。我需要每 500 毫秒调用一次self.driver.find_element(By.XPATH, u"//a/img").get_attribute(u"src"),以将它的返回值与我已经得到的值进行比较。当它们不相等时,我的__call__() 将返回True
      • 我只是在解释你为什么得到TimeoutException,因为在你的问题中你似乎不明白为什么。就像我说的那样,您的问题是您要么检查错误的元素(因为 URL 显然永远不会改变),要么超时时间太短。尝试将其增加到 10 秒以上。另一种选择是检查 iframe 中的另一种情况。我不熟悉您正在测试的网站,因此无法进一步帮助您。
      • 我来到这里是因为“ExpectedCondition 类型的成功返回是 Boolean 返回 true 或所有其他 ExpectedCondition 类型的返回值不是 null”写得很糟糕,完全没有意义......
      猜你喜欢
      • 1970-01-01
      • 2018-10-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多