Python、Selenium 查找具有类的元素并等待类更改

问题描述 投票:0回答:3

我有一个动态加载内容的网页,在页面加载时,有旋转轮,我已经找到了抓取立即加载到页面上的内容的解决方案,但似乎我找不到抓取稍后在dom中加载的内容的解决方案。

我能想到的是找到具有该轮子旋转的特定类的元素,并等待它发生变化,一旦发生变化,就意味着内容已加载到dom中。

我在

Selenium
上使用
Firefox
webdriver
Ubuntu

这是我要监视的课程:

<div class="wheel spinning"></div>

内容加载后,轮子停止旋转,类别更改为:

<div class="wheel"></div>

任何人找到解决方案来查找和监控

class="wheel spinning"
,一旦更改为
class="wheel"
即可继续抓取数据。

编辑:

XPATH实际上解决了一部分解决方案,这是部分代码

try:
    element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.XPATH, "//*[@class='wheel']))
)
title = driver.find_element_by_xpath('/html/body/div[1]/div[1]/div[3]')
print(title.text)

但是,如果元素在 10 秒内没有出现,则会出错,现在要找到一种方法来一次又一次重试,直到元素出现在页面上。

使用上有区别吗

presence_of_element_located((By.XPATH))
find_element_by_xpath

python selenium selenium-webdriver css-selectors webdriverwait
3个回答
8
投票

您可以等待班级值发生变化。例如:

from selenium.webdriver.support.ui import WebDriverWait

# Wait longer than 10 seconds since you're getting occasional timeout
el = WebDriverWait(driver, 30).until(EC.presence_of_element_located((By.XPATH, "//*[@class='wheel']")))


wait = WebDriverWait(driver, 10)
wait.until(lambda d: 'spinning' not in el.get_attribute('class'))

until
方法将驱动程序传递给给定的方法,因此您可以非常轻松地制定自己的预期条件。上面使用了匿名 lambda 函数,但您也可以使用闭包或任何接受参数的可调用对象(ExpectedConditions 库只是一组可调用类)。这与闭包相同:

from selenium.webdriver.support.ui import WebDriverWait


# Wait longer than 10 seconds since you're getting occasional timeout
el = WebDriverWait(driver, 30).until(EC.presence_of_element_located((By.XPATH, "//*[@class='wheel']")))

def wait_not_spinning(driver):
    return 'spinning' not in el.get_attribute('class')

wait = WebDriverWait(driver, 10)
wait.until(wait_not_spinning)

6
投票

@LucasTierney 的答案是正确的。不过我仍然觉得解决方案可以优化如下:

由于 wheel 可见,因此您需要使用

presence_of_element_located()
 方法,而不是 
visibility_of_element_located()
方法。

节点:

<div class="wheel spinning"></div>

无法通过包含单个类的 XPath 进行定位,即仅包含

wheel
,如下所示:

el = WebDriverWait(driver, 30).until(EC.presence_of_element_located((By.XPATH, "//*[@class='wheel']")))

您可以使用任一定位器策略

  • cssSelector
    :

    el = WebDriverWait(driver, 30).until(EC.visibility_of_element_located((By.CSS_SELECTOR, "div.wheel.spinning")))
    WebDriverWait(driver, 10).until(lambda d: 'spinning' not in el.get_attribute('class'))
    
  • xpath
    :

    el = WebDriverWait(driver, 30).until(EC.visibility_of_element_located((By.XPATH, "//div[@class='wheel spinning']")))
    WebDriverWait(driver, 10).until(lambda d: 'spinning' not in el.get_attribute('class'))
    

0
投票

我在搜索时找到了这个答案,我感谢每一个贡献者,但我找到了另一个解决方案,使用类的“陈旧性”,等待第一个“轮子旋转”类消失。就您而言,这可能会给出:

elSpinner = browser.find_element(By.CLASS_NAME, "轮子旋转") wtSpinner = WebDriverWait(浏览器,10).until(EC.staleness_of(elSpinner))

你肯定会让它变得更简单,但我就是这样工作的!

© www.soinside.com 2019 - 2024. All rights reserved.