硒,是否存在多种元素之一?

Liq*_*ius 4 python selenium web-scraping expected-condition

构建如何使用 Selenium for Python 等待页面加载?我正在尝试创建一种方法,允许使用预期条件轮询多个元素是否存在。

我收到错误“bool”对象在包含 wait.until(any(expectations)) 的行上不可调用。

思考过程是允许多个 Xpath 按预期条件传递,然后使用any(),以与此基于 java 的答案类似的方式,尝试使用 selenium xpath 等待页面中的两个元素之一,检查是否任何一个条件都存在。

在这种情况下使用any()的正确方法是什么?或者更好的是,需要做什么才能使该方法发挥作用?

假设 Selenium .get('url') 已在调用此方法之前立即执行。

def wait_with_xpath_expectation(self, search_elements, timeout=6, max_attempts=3):
    """
    Selenium wait for an element(s) designated by Xpath to become available in the DOM. Useful for javascript AJAXy
    loading pages where content may be be rendered dynamically on the client side after page load appears complete.
    search_elements may be one Xpath as a string or many as a list. This allows for any of multiple elements on a
    page or pages to be determined to have loaded based on expectations.
    :param search_elements: string or list (strings converted to lists), Xpath(s)
    :param timeout: int, seconds
    :param max_attempts: int, time to wait before giving up on page loading
    :return: Boolean, True if page has loaded, False if all attempts have failed
    """

    # Page is not loaded yet
    loaded = False

    # Initialize attempt count
    attempt = 0

    # If only one element has been passed, ensure it is encapsulated by a list
    if type(search_elements) is str:
        search_elements = [search_elements]

    # Begin the polling loop
    while attempt < max_attempts:

        try:

            while loaded is False:
                # Create a list of expected elements using list comprehension
                expectations = [EC.presence_of_element_located((By.XPATH, element)) for element in search_elements]

                # Define wait
                wait = WebDriverWait(self.browser, timeout)

                # Execute
                wait.until(any(expectations))

                # Acknowledge load
                loaded = True

                print("Success: Page loaded based on expectations")

                # Exit returning True for load
                return loaded

        except TimeoutException as e:

            # Increment attempts
            attempt += 1

            # Check again if max attempts has not been exceeded
            while attempt < max_attempts:

                # Increase timeout by 20%
                timeout *= .2

                # Try again 
                continue

            # Print an error if max attempts is exceeded
            print("Error: Max load with expectations attempts exceeded,", e)

            # Exit returning False for load
            return loaded
Run Code Online (Sandbox Code Playgroud)

小智 8

您可以使用预期条件类来等待预期条件的组合。这是一个例子。

class wait_for_all(object):
    def __init__(self, methods):
        self.methods = methods

    def __call__(self, driver):
        try:
            for method in self.methods:
                if not method(driver):
                    return False
            return True
        except StaleElementReferenceException:
            return False
Run Code Online (Sandbox Code Playgroud)

然后,通过构建预期条件的数组并在同一等待中检查所有条件来使用它。(为了清楚起见,示例行被分开。)

methods = []
methods.append(EC.visibility_of_element_located(BY.ID, "idElem1"))
methods.append(EC.visibility_of_element_located(BY.ID, "idElem2"))
method = wait_for_all(methods)
WebDriverWait(driver, 5).until(method)
Run Code Online (Sandbox Code Playgroud)

这将在检查两个不同元素的可见性时执行五秒的等待。

我已在此处的博客文章中进一步记录了这一点。