DAVIDBALAS1
DAVIDBALAS1

Reputation: 484

python selenium visibility of element raises TimeoutException

my brother asked for my lame python skills in order to build a program that monitors stocks data from nasdaq, for example - the apple stock

I want to get the value of today's high/low(currently $ 141.3893 / $ 139.76) by XPATH, therefore, I use this code:

el = WebDriverWait(driver1, 10).until(
        EC.visibility_of_element_located((By.XPATH, "//tr[contains(lower-case(text()), 'Today's High /Low')]")))

My logic - find a tr tag that contains the text 'Today's High /Low' and then I want to print the text of the second td, I think this pattern is on every stock on this site.

However, it raises TimeoutException error:

Traceback (most recent call last):
  File "C:/Users/Guy Balas/PycharmProjects/stockmarket/main.py", line 49, in <module>
    main('http://www.nasdaq.com/symbol/aapl')
  File "C:/Users/Guy Balas/PycharmProjects/stockmarket/main.py", line 42, in main
    s = get_data()
  File "C:/Users/Guy Balas/PycharmProjects/stockmarket/main.py", line 33, in get_data
    EC.visibility_of_element_located((By.XPATH, "//td[contains(lower-case(text()), 'Today's High /Low')]"))).text
  File "C:\Users\Guy Balas\AppData\Local\Programs\Python\Python36-32\lib\site-packages\selenium\webdriver\support\wait.py", line 80, in until
    raise TimeoutException(message, screen, stacktrace)
selenium.common.exceptions.TimeoutException: Message: 

Any other ways to achieve this/any mistake I made?

Thanks.

Upvotes: 0

Views: 332

Answers (2)

JeffC
JeffC

Reputation: 25746

I know you accepted an answer but there's an easier way to do this. If you look at the HTML of the page, you will see this

<tr>
    <td>
        <a class="tt show-link" id="todays_high_low" onmouseover="showDelayedToolTip('todays_high_low')" onmouseout="hideToolTip('todays_high_low')" href="javascript:void(0)">
            Today's High /Low
            <span class="tooltipLG">...snip...</span>
        </a>
    </td>
    <td align="right" nowrap="">
        <label id="Label3">$&nbsp;141.3893</label>&nbsp;/&nbsp;
        <label id="Label1">$&nbsp;139.76</label>
    </td>
</tr>

From the HTML, you can see that the high and low each have an ID, "Label3" (high) and "Label1" (low). With that info, you can just use

high = WebDriverWait(driver1, 10).until(EC.visibility_of_element_located((By.ID, "Label3"))).text
// you don't need to wait again here since the wait should guarantee the element is accessible
low = driver1.find_element_by_id("Label1").text

With this method you can separate out the low from the high, which I'm assuming you are going to want to do anyway. This way avoids string processing the combined string...

Upvotes: 1

Andersson
Andersson

Reputation: 52685

You can do it as below:

el = WebDriverWait(driver1, 10).until(
    EC.visibility_of_element_located((By.LINK_TEXT, "Today's High /Low")))
print(el.find_element_by_xpath('./following::td').text)

Output $ 141.3893 / $ 139.76

Upvotes: 1

Related Questions