Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python, Selenium find element with class and wait for class change

I have a web page which loads content dynamically and while page loads, there is spinning wheel, I already found solution to grab content loaded immediately on page, but seems i can't find solution to grab content loaded later in dom.

What i can think of is to find element with specific class of that wheel spinning, and wait for it to change, once it's changed, than it means content is loaded in dom.

I am using Selenium with Firefox webdriver on Ubuntu.

Here is the class i am looking to monitor:

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

Once content is loaded, wheel stop spinning and class is changed to:

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

Anyone find solution to find and monitor class="wheel spinning" and once it's changed to class="wheel" to continue to grab data.

Edit:

The XPATH actually solved one part of solution, here's part of code

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)

But if element don't appear within 10 seconds it error's out, now to find a way to retry again and again until element is present on page.

Is there a difference in use presence_of_element_located((By.XPATH)) and find_element_by_xpath

like image 466
lonerunner Avatar asked Nov 10 '18 14:11

lonerunner


People also ask

How to find elements by class name in selenium?

The class also contains other alternative methods for locating elements. The Selenium WebDriver library for other programming languages has a similar method for locating elements. For example, the Python library finds elements by class name using the CLASS_NAME constant from its By class.

What are waits in selenium Python bindings?

Waits — Selenium Python Bindings 2 documentation 5. Waits ¶ These days, most of the web apps are using AJAX techniques. When a page is loaded by the browser, the elements within that page may load at different time intervals.

What is waiting in Selenium WebDriver?

Waiting provides some slack between actions performed – mostly locating an element or any other operation with the element. Selenium Webdriver provides two types of waits – An implicit wait tells WebDriver to poll the DOM for a certain amount of time when trying to find any element (or elements) not immediately available. The default setting is 0.

How long does selenium wait for an element to be found?

In the code above, Selenium will wait for a maximum of 10 seconds for an element matching the given criteria to be found. If no element is found in that time, a TimeoutException is thrown.


1 Answers

You can wait for the class value to change. For example:

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

The until method passes the driver to the method given, so you can make your own expected condition pretty easily. The above uses an anonymous lambda function but you could also use a closure or a anything callable that takes in an argument (the ExpectedConditions library is just a set of callable classes). Here is the same with a closure:

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)
like image 178
Lucas Tierney Avatar answered Nov 01 '22 06:11

Lucas Tierney