首页 > 解决方案 > 如何等待元素中元素和特定文本的存在?

问题描述

我需要等待其中包含特定文本的元素的存在。我想在元素存在并包含文本的那一刻从该元素获取信息。我在提交表格后的某个时间出现,并且通常稍后会填写信息。我目前的解决方案如下所示:

wait = WebDriverWait(self.driver, MAXIMUM_LOAD_TIME)
    try:
        wait.until(ec.presence_of_element_located((By.ID,"IdOfElement")))
        wait.until(ec.text_to_be_present_in_element((By.ID, "IdOfElement"), "theText"))
        data = self._extract_data()
    except TimeoutException:
        raise WebsiteTimeoutError(MAXIMUM_LOAD_TIME)

这在超过 99% 的情况下都能完美运行,但现在碰巧我在ec.text_to_be_present_in_element.

错误是:

  File "my/Path", line 436, in  _scrape_quote
    wait.until(ec.text_to_be_present_in_element((By.ID, "IdOfElement"), "theText"))
  File "C:\Program Files (x86)\Python38-32\lib\site-packages\selenium\webdriver\support\wait.py", line 71, in until
    value = method(self._driver)
  File "C:\Program Files (x86)\Python38-32\lib\site-packages\selenium\webdriver\support\expected_conditions.py", line 210, in __call__
    return self.text in element_text
TypeError: argument of type 'NoneType' is not iterable

显然元素又消失了。我的假设对吗?解决此问题的最佳方法是什么?

标签: pythonseleniumweb-scraping

解决方案


如果您看一下text_to_be_present_in_element实现,它会假定该值永远不会是 None。

    def __call__(self, driver):
        try:
            element_text = _find_element(driver, self.locator).text
            return self.text in element_text
        except StaleElementReferenceException:
            return False

如果值为element_textNone (可能是某个时间),它会抛出一个异常

TypeError: argument of type 'NoneType' is not iterable

现在您的代码有点麻烦,因为您需要先确保元素存在,然后检索相同的元素以找到正确的值。EC 模块中没有同时提供两者的课程。那么如何实现你的类。

您可以实现一个确保它存在的类,同时修复问题以处理文本返回中 None 的情况。

class FindPresenceOfTextInElement(object):
    def __init__(self, locator, text):
        self.locator = locator
        self.text = text

    def __call__(self, driver):
        try:
            text = driver.find_element(*self.locator).text
            return self.text in text
        except (NoSuchElementException, StaleElementReferenceException, TypeError):
            return False

然后你的代码变成:

wait = WebDriverWait(self.driver, MAXIMUM_LOAD_TIME)
    try:
        wait.until(FindPresenceOfTextInElement((By.ID,"IdOfElement")))
        data = self._extract_data()
    except TimeoutException:
        raise WebsiteTimeoutError(MAXIMUM_LOAD_TIME)

您将需要以下导入:

from selenium.common.exceptions import NoSuchElementException, StaleElementReferenceException

更新

由于以上是最好的方法,我相信,您可以通过在等待 obj 中添加异常处理程序来解决它,如下所示:

wait = WebDriverWait(driver, 30, ignored_exceptions=(TypeError, ))

如果您也添加了NoSuchElementException,您基本上添加了以确保元素也存在。


推荐阅读