【问题标题】:Selenium WebDriver WebDriverWait. how to wait for a set of identical elements?Selenium WebDriver WebDriverWait。如何等待一组相同的元素?
【发布时间】:2021-04-01 07:49:44
【问题描述】:

我正在解析一些带有<div class="classname" ...> tgs 列表的网上商店页面。例如,每页 24 个。 但是有些元素及时加载,有些没有。 WebDriver(Chrome) find 需要 4-6 个元素,通常像这样加载:

<div class="classname">
   <div class="abcd">...</div>
</div>

和 18-20 喜欢 &lt;div class="classname" ...&gt;&lt;!-- --&gt;&lt;/div&gt; - 未加载

所以我使用driver.find_elements_by_class("abcd"),它只有 4-6 个元素。

如何等待使用WebDriverWait.until 或implicity_wait 加载的总列表? (没有任何其他元素,可以等待。页面的所有其他部分完全正确加载。) 或者如何在没有条件的情况下简单地延迟几秒钟并在 WebDriver 对象中获取页面的完成版本? (driver.iImplicity_wait(10)) - 如我所见,延迟,但 webdriver 对象中的数据也不完整。)

更新: 这对我来说很奇怪,但是使用 webdriver.wait、time.sleep()、drver.refresh() 不会更新页面的 drive.page_source。那仍然停留在未正确加载的语句中... 代码:

    self.driver.get(url_)
    time.sleep(15)
    number_of_elements = len(self.driver.find_elements_by_class_name("product-cards-layout__item")) # len -24 

    while True:
        xpath = "//div[@class=\"product-card--mobile\"]"
        condition = EC.presence_of_all_elements_located((By.XPATH, xpath))

        try:
            wait = WebDriverWait(self.driver, 10).until(condition) # len - 6 
        except Exception:
            pass

        print(len(wait)) #6
        if len(wait) == number_of_elements:
            break
        else:
            self.driver.refresh()

    exit_ = self.driver.page_source

所以。 driver.page_sorce 中的 html 代码如下:

<div class="product-cards-layout__item"><div class="product-card--mobile__info"</div></div>
<div class="product-cards-layout__item"><div class="product-card--mobile__info"</div></div>
<div class="product-cards-layout__item"><div class="product-card--mobile__info"</div></div>
... (6 times)

<div class="product-cards-layout__item"><!-- --></div>
<div class="product-cards-layout__item"><!-- --></div>
<div class="product-cards-layout__item"><!-- --></div>
... (20 times)
Total 24 TAGS

但在 Chrome 打开的窗口中,我看到了所有需要的信息(24 个完整的标签,在构造中

.refresh() 一样-它是静态的,与浏览器中的数据不对应。而且它对于数百个循环仍然是静态的)))

【问题讨论】:

  • 具有这种行为的网站会有所帮助。页面上可能存在帮助器,例如要检查的加载微调器,直到它不存在为止。

标签: python selenium parsing selenium-webdriver webdriverwait


【解决方案1】:

如果您知道每页的元素数量,您可以使用此函数等待所有预期元素:

from selenium.common.exceptions import TimeoutException, StaleElementReferenceException

def wait_until_all_expected_elements(func, number_of_elements, timeout=30):

endtime = time.time() + timeout
while True:
    try:
        if time.time() > endtime:
            raise TimeoutException("The function doesn't return a sufficient number of elements")
        elements = func()
        if len(elements) == number_of_elements:
            return elements
    except StaleElementReferenceException:
        pass

其中 number_of_elements 代表页面包含的元素数量。然后,通过 WebdriverWait.until 获取元素

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as ec

def get_elements(driver):
    wait = WebDriverWait(driver, 10)
    return wait.until(ec.presence_of_all_elements_located((By.XPATH, path_to_element))

并将函数传递给wait_until_all_expected_elements,如下所示:

elements = wait_until_all_expected_elements(lambda: get_elements(driver), number_of_elements)

【讨论】:

  • 此方法必须有效,但在我的站点中不起作用(((哪里不更新 driver.page_source。我看对了,Chrome 窗口中的整页,但 page_source 被裁剪了)作为第一次加载。不是 WebDriverWait 作为您在 While True Cycle 中的示例,不是任何 time.sleep(),不是任何 drver.refresh() 或 .get(url) 都没有帮助。
【解决方案2】:

我在网络抓取方面遇到了同样的问题。尝试使用 python 内置的 time 库。您只需输入 time.sleep(number_of_seconds),网站就会有时间加载,然后您就可以查找所需的内容了。

import time

driver.get(your_website_here)

time.sleep(5)  # Wait 5 seconds for page to fully load

driver.find_elements_by_class("abcd")

【讨论】:

    【解决方案3】:

    我的问题是:当网站不在浏览器中时,它不会加载块。 Desision 是 - 滚动到您需要的所有 div:

             self.driver.get(url_)
             product_elements = self.driver.find_elements_by_class_name("product-cards")
     
             for elm in product_elements:
                 elm.location_once_scrolled_into_view
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-08-06
      • 2019-12-02
      • 2012-03-26
      • 2016-12-25
      • 1970-01-01
      • 2023-03-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多