Python, Selenium 查找具有 class 的元素并等待 class 更改
Python, Selenium find element with class and wait for class change
我有一个动态加载内容的网页,当页面加载时,有一个旋转轮,我已经找到了抓取内容立即加载到页面上的解决方案,但似乎我找不到抓取稍后加载的内容的解决方案dom.
我能想到的是找到那个轮子旋转的特定class的元素,然后等待它改变,一旦改变,就意味着内容加载到dom。
我在 Ubuntu
上使用 Selenium
和 Firefox
webdriver
。
这是我要监视的class:
<div class="wheel spinning"></div>
加载内容后,轮子停止旋转,class 更改为:
<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
在使用上有区别吗
您可以等待 class 值更改。例如:
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 库只是一组可调用 classes)。这里有一个闭包:
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 可见,因此您需要使用 visibility_of_element_located()
方法而不是 presence_of_element_located()
方法。
节点:
<div class="wheel spinning"></div>
无法通过包含单个 class 的 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'))
我有一个动态加载内容的网页,当页面加载时,有一个旋转轮,我已经找到了抓取内容立即加载到页面上的解决方案,但似乎我找不到抓取稍后加载的内容的解决方案dom.
我能想到的是找到那个轮子旋转的特定class的元素,然后等待它改变,一旦改变,就意味着内容加载到dom。
我在 Ubuntu
上使用 Selenium
和 Firefox
webdriver
。
这是我要监视的class:
<div class="wheel spinning"></div>
加载内容后,轮子停止旋转,class 更改为:
<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
您可以等待 class 值更改。例如:
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 库只是一组可调用 classes)。这里有一个闭包:
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 可见,因此您需要使用 visibility_of_element_located()
方法而不是 presence_of_element_located()
方法。
节点:
<div class="wheel spinning"></div>
无法通过包含单个 class 的 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'))