Selenium WebDriver WebDriverWait。如何等待一组相同的元素?
Selenium WebDriver WebDriverWait. how to wait for a set of identical elements?
我正在使用 <div class="classname" ...>
tgs 列表解析一些网上商店页面。例如,每页 24。
但是有些元素会及时加载,有些则不会。 WebDriver(Chrome) 查找需要 4-6 个元素,通常像这样加载:
<div class="classname">
<div class="abcd">...</div>
</div>
18-20 喜欢
<div class="classname" ...><!-- --></div>
- 未加载
所以我使用 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 打开 window 我看到了所有需要的信息(24 个完整的标签,在构建中
.refresh() 完全相同 - 它是静态的,并且与浏览器中的数据不对应。而且它对于 hundrets 循环仍然是静态的 )))
我在网络抓取方面遇到了同样的问题。尝试使用 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")
如果您知道每页的元素数量,您可以使用此函数等待所有预期元素:
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)
我的问题是:网站在浏览器中未处于焦点时不会加载块。
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
我正在使用 <div class="classname" ...>
tgs 列表解析一些网上商店页面。例如,每页 24。
但是有些元素会及时加载,有些则不会。 WebDriver(Chrome) 查找需要 4-6 个元素,通常像这样加载:
<div class="classname">
<div class="abcd">...</div>
</div>
18-20 喜欢
<div class="classname" ...><!-- --></div>
- 未加载
所以我使用 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 打开 window 我看到了所有需要的信息(24 个完整的标签,在构建中
我在网络抓取方面遇到了同样的问题。尝试使用 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")
如果您知道每页的元素数量,您可以使用此函数等待所有预期元素:
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)
我的问题是:网站在浏览器中未处于焦点时不会加载块。 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