如何让硒等待多个元素加载

时间:2019-10-03 18:11:30

标签: python selenium

在执行屏幕抓取操作之前,我正在使用以下代码等待所有4个元素加载;但是,代码没有等待所有4个代码,也没有抛出超时错误-它只是继续执行,并且在尚未加载的元素上出现错误。

我缺少什么让Selenium等到所有四个元素都存在之后才能继续?

        CSSSelector1_toWaitOn = "#div1 table tbody tr td"
        CSSSelector2_toWaitOn = "#div2 table tbody tr:nth-child(5) td"
        CSSSelector3_toWaitOn = "#div3 table tbody tr:nth-child(5) td"
        CSSSelector4_toWaitOn = "#div4 table tbody tr td"


        browser.get(url)
        browser_delay = 15  # seconds
        try:
            WebDriverWait(browser, browser_delay).until(expected_conditions and (
                expected_conditions.presence_of_element_located((By.CSS_SELECTOR, CSSSelector1_toWaitOn)) and
                expected_conditions.presence_of_element_located((By.CSS_SELECTOR, CSSSelector2_toWaitOn)) and
                expected_conditions.presence_of_element_located((By.CSS_SELECTOR, CSSSelector3_toWaitOn)) and
                expected_conditions.presence_of_element_located((By.CSS_SELECTOR, CSSSelector4_toWaitOn))))
        except TimeoutException:
            print("Selenium timeout")```

3 个答案:

答案 0 :(得分:1)

WebDriverWait.until需要可调用对象。这是其来源的实际摘录:

while True:
    try:
        value = method(self._driver)
        if value:
            return value

所有expected_contidition是可调用对象。因此,在这种情况下,您需要编写它们,类似以下的内容应该起作用。

class composed_expected_conditions:
    def __init__(self, expected_conditions):
        self.expected_conditions = expected_conditions

    def __call__(self, driver):
        for expected_condition in self.expected_conditions:
            if not expected_condition(driver):
                return False

            return True

并将其传递给until

conditions = [
    expected_conditions.presence_of_element_located((By.CSS_SELECTOR, CSSSelector1_toWaitOn)), 
    expected_conditions.presence_of_element_located((By.CSS_SELECTOR, CSSSelector2_toWaitOn)),
    expected_conditions.presence_of_element_located((By.CSS_SELECTOR, CSSSelector3_toWaitOn)),
    expected_conditions.presence_of_element_located((By.CSS_SELECTOR, CSSSelector4_toWaitOn)),
]

WebDriverWait(browser, browser_delay).until(composed_expected_conditions(conditions))

答案 1 :(得分:0)

方法presence_of_element_located(locator)仅检查DOM中是否存在该元素。这并不意味着可以与该元素进行交互。此外,搜索过程会找到给定locator的所有元素并返回第一个。

请检查该元素是否有效,可用且特定。如果列表中有多个元素,请确保您的定位器足够具体以找到单个元素。

答案 2 :(得分:-1)

您可以为每个请求分别设置一个等待,而不是尝试将它们全部合并为一个等待。

...

try:
    wait = WebDriverWait(browser, browser_delay)
    wait.until(expected_conditions.visibility_of_element_located((By.CSS_SELECTOR, CSSSelector1_toWaitOn))
    wait.until(expected_conditions.visibility_of_element_located((By.CSS_SELECTOR, CSSSelector2_toWaitOn))
    wait.until(expected_conditions.visibility_of_element_located((By.CSS_SELECTOR, CSSSelector3_toWaitOn))
    wait.until(expected_conditions.visibility_of_element_located((By.CSS_SELECTOR, CSSSelector4_toWaitOn))))
except TimeoutException:
    print("Selenium timeout")

请注意,硒中元素的交互作用分为3个级别:

  1. present-元素在DOM中。如果您尝试单击当前元素(但不是可见元素)或从中获取文本,则会抛出ElementNotInteractable异常。
  2. 可见-元素在DOM中且可见(例如,不可见,显示:无,等等)
  3. clickable-元素可见并启用。对于大多数案例,这只是...可见吗?特殊情况是诸如INPUT按钮之类的元素被标记为禁用。使用CSS样式设置为已禁用(灰色)的元素不被视为已禁用。