Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does selenium return an empty text field?

I'm trying to get the value of the element "total-price" from this page.

My html looks like this:

<div class="data">
<div class="data-first">Ydelse pr. måned</div>
<div class="data-last">
<span class="total-price">[3.551 Kr][1].</span>
</div>
</div>

My code is as follows:

monthlyCost = driver.find_element_by_xpath("//span[@class='total-price']")
print monthlyCost.text

The strange thing is the property is present in the webelement.

enter image description here

However, if I try and print it or assign it to an object it comes out empty. Why?

like image 916
Frank Avatar asked Aug 02 '15 20:08

Frank


People also ask

What is xOffset and yOffset in Selenium?

Both xOffset and yOffset represent the relative pixel distance (integer) with which to scroll. For xOffset , positive value means to scroll right, and negative value means to scroll left. For yOffset , positive value means to scroll downward, and negative value means to scroll upward.

How do you empty a field in Selenium?

We can enter text on any field in Selenium. After entering the text, we may need to remove or clear the text we entered in that field. This interaction with the web elements can be achieved with the help of clear() method. Thus a clear() method is used to clear or reset an input field belonging to a form/ edit box.

What is return in Selenium?

We can get the return value of Javascript code with Selenium webdriver. Selenium can run Javascript commands with the help of executeScript method. The Javascript command to be executed is passed as an argument to the method. We shall be returning the value from the Javascript code with the help of the keyword return.


1 Answers

When you debug it, you're actually adding a pause and unintentionally wait for the page to load.

Plus, the price is loaded dynamically with an additional XHR request and has an intermediate "xxx" value which is substituted with a real value later in the load process. Things are becoming more complicated since there are multiple elements with total-price class and only one of them is becoming visible.

I'd approach it with a custom Expected Condition:

from selenium.common.exceptions import StaleElementReferenceException
from selenium.webdriver.support import expected_conditions as EC

class wait_for_visible_element_text_to_contain(object):
    def __init__(self, locator, text):
        self.locator = locator
        self.text = text

    def __call__(self, driver):
        try:
            elements = EC._find_elements(driver, self.locator)
            for element in elements:
                if self.text in element.text and element.is_displayed():
                    return element
        except StaleElementReferenceException:
            return False

The working code:

from selenium.webdriver.common.by import By
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait

driver = webdriver.Chrome()
driver.maximize_window()
driver.get('http://www.leasingcar.dk/privatleasing/Citro%C3%ABn-Berlingo/eHDi-90-Seduction-E6G')

# wait for visible price to have "Kr." text
wait = WebDriverWait(driver, 10)
price = wait.until(wait_for_visible_element_text_to_contain((By.CSS_SELECTOR, "span.total-price"), "Kr."))
print price.text

Prints:

3.551 Kr.
like image 194
alecxe Avatar answered Oct 13 '22 19:10

alecxe