我有一个动态加载内容的网页,在页面加载时,有旋转轮,我已经找到了抓取立即加载到页面上的内容的解决方案,但似乎我找不到抓取稍后在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
您可以等待班级值发生变化。例如:
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)
@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'))
我在搜索时找到了这个答案,我感谢每一个贡献者,但我找到了另一个解决方案,使用类的“陈旧性”,等待第一个“轮子旋转”类消失。就您而言,这可能会给出:
elSpinner = browser.find_element(By.CLASS_NAME, "轮子旋转") wtSpinner = WebDriverWait(浏览器,10).until(EC.staleness_of(elSpinner))
你肯定会让它变得更简单,但我就是这样工作的!