Why does this work on this, but not on this? [Selenium] [Python]

Viewed 58

I'm making a stock checker and I have a bit of a problem when I go to Amazon (AMZN) in finance.yahoo.com. My code works perfectly, but when I try for example Tesla (TSLA) it doesn't work. Here is part of my code.

getperstock = driver.find_element_by_xpath('//*[@class="Trsdu(0.3s) Fw(b) Fz(36px) Mb(-4px) D(ib)"]').text #Works
print(str(getperstock))
#"Trsdu(0.3s) Fw(500) Pstart(10px) Fz(24px) C($negativeColor)"
getstockratio = driver.find_element_by_xpath('//*[@class="Trsdu(0.3s) Fw(500) Pstart(10px) Fz(24px) C($positiveColor)"]').text #Doesnt
print(str(getstockratio))
1 Answers

Here's the minimal HTML

<div class="D(ib) Mend(20px)" data-reactid="31">
    <span class="Trsdu(0.3s) Fw(b) Fz(36px) Mb(-4px) D(ib)"
        data-reactid="32">670.97</span>
    <span class="Trsdu(0.3s) Fw(500) Pstart(10px) Fz(24px) C($negativeColor)"
        data-reactid="33">-20.65 (-2.99%)</span>
    <div id="quote-market-notice" class="C($tertiaryColor) D(b) Fz(12px) Fw(n) Mstart(0)--mobpsm Mt(6px)--mobpsm"
        data-reactid="34">
        <span data-reactid="35">At close: 4:00PM EDT</span>
    </div>
</div>

Your first xpath to get the first span is OK. But the second span will include negative or positive so if the stock is going negatively/positively, it will fail to locate the element. I see that in your comment you said it worked, but I'm sure that once it goes the opposite way, it will fail.

Better way to do it:

# get parent of both `span`
parent = driver.find_element_by_xpath('//div[@class="D(ib) Mend(20px)"]')
# get the `span` insides
span_elems = parent.find_elements_by_tag_name("span")

# first one is the stock price
price = span_elems[0].text
# second span is the %
ratio = span_elems[1].text
# third one is the "at close..." but you dont need it

By the way, don't use find_elements... to find the parent node. Use explicit wait will make the code do the waiting part efficiently for you: https://selenium-python.readthedocs.io/waits.html

Related