Oladuwek
Oladuwek

Reputation: 43

Python, Selenium, how can i exit from while loop after an element disappears?

I have an element with changing text.

<small class="cell progress-name text-center ng-star-inserted">*some changing text*</small>

After the text in this element disappears, the element also disappears. I need to find a way out of while loop after an element has disappeared.

previous_value = None
while True:
    current_value = browser.find_element_by_xpath('//*[@class="cell progress-name text-center ng-star-inserted"]')
    if previous_value:
        if current_value.text != previous_value:
            print(current_value.text)
            previous_value = current_value.text

    else:
        print(current_value)
        previous_value = current_value.text

    time.sleep(1)

Now I get no such element: Unable to locate element error message and any help would be appreciated.

Upvotes: 3

Views: 1211

Answers (2)

sguridirt
sguridirt

Reputation: 83

You can use the error itself to know if the element has disappeared. You just need to handle it and break the loop:

    previous_value = None
    while True:
        try:
            current_value = browser.find_element_by_xpath('//*[@class="cell progress-name text-center ng-star-inserted"]')
        except NoSuchElementException: # the element wasn't found
            break # exit from the loop

        if previous_value:
            if current_value.text != previous_value:
                print(current_value.text)
                previous_value = current_value.text

        else:
            print(current_value)
            previous_value = current_value.text

        time.sleep(1)

Remember to import the exception from selenium.common.exceptions import NoSuchElementException.


There is another way to handle this. You can use find_elements_by_xpath(with an "s" in "elements"). This function will return an empty list instead of throwing and error if nothing is found.

You can then check is the list is empty and break if True.

previous_value = None
    while True:
        current_value = browser.find_elements_by_xpath('//*[@class="cell progress-name text-center ng-star-inserted"]')
        if not current_value:
            break # the list is empty

        if previous_value:
            if current_value.text != previous_value:
                print(current_value.text)
                previous_value = current_value.text

        else:
            print(current_value)
            previous_value = current_value.text

        time.sleep(1)

I think the best option is the first one I gave you, it's cleaner and uses a Python principle from the Glossary:

Easier to ask for forgiveness than permission. This common Python coding style assumes the existence of valid keys or attributes and catches exceptions if the assumption proves false. This clean and fast style is characterized by the presence of many try and except statements.

Upvotes: 3

Naveen
Naveen

Reputation: 788

we should get an element from a separate function and handle it with string comparison. For e.g

def getElementText(XPATH):
    try:
        element = browser.find_element_by_xpath(XPATH)
        return element.text
    except:
        print(XPATH + ' : not found')
        return ''

and we can get the element text and see if its empty and decide to get out of the while loop.

previous_value = None
current_value = getElementText('//*[@class="cell progress-name text-center ng-star-inserted"]')
while current_value != '':
    if previous_value:
        if current_value != previous_value:
            print(current_value)
            previous_value = current_value
    else:
        print(current_value)
        previous_value = current_value
    time.sleep(1)
    current_value = getElementText('//*[@class="cell progress-name text-center ng-star-inserted"]')

Upvotes: 0

Related Questions