Python,Selenium用类查找元素并等待类更改

时间:2018-11-10 14:57:02

标签: python selenium selenium-webdriver css-selectors webdriverwait

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

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

我将Selenium上的Firefox webdriverUbuntu一起使用。

这是我要监控的课程:

<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的用法是否有所不同

2 个答案:

答案 0 :(得分:3)

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

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方法passes the driver to the method given,因此您可以轻松实现自己的预期条件。上面使用了匿名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)

答案 1 :(得分:2)

@LucasTierney的答案(+1)几乎是完美的,但我仍然认为可以按以下方式优化解决方案:

由于可见方向盘,因此您需要使用 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']")))

相反,您可以使用Locator Strategies中的任何一个:

  • 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'))