Python,Selenium 查找带有类的元素并等待类更改

Ale*_*vić 6 python selenium css-selectors selenium-webdriver webdriverwait

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

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

我使用SeleniumFirefox webdriverUbuntu

这是我要监控的课程:

<div class="wheel spinning"></div>
Run Code Online (Sandbox Code Playgroud)

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

<div class="wheel"></div>
Run Code Online (Sandbox Code Playgroud)

任何人都可以找到解决方案来查找和监控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)
Run Code Online (Sandbox Code Playgroud)

但是如果元素在 10 秒内没有出现,那就是错误了,现在想办法一次又一次地重试,直到元素出现在页面上。

使用presence_of_element_located((By.XPATH))和使用上有区别吗find_element_by_xpath

Luc*_*ney 6

您可以等待类值更改。例如:

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'))
Run Code Online (Sandbox Code Playgroud)

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)
Run Code Online (Sandbox Code Playgroud)


Deb*_*anB 5

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

由于轮子是可见的,因此presence_of_element_located()您需要使用visibility_of_element_located()方法而不是方法。

节点:

<div class="wheel spinning"></div>
Run Code Online (Sandbox Code Playgroud)

无法通过包含单个类的XPath进行定位,即仅wheel如下所示:

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

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

  • 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'))
    
    Run Code Online (Sandbox Code Playgroud)
  • 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'))
    
    Run Code Online (Sandbox Code Playgroud)