Home > OS >  Can't find a <div> tag with selenium, why?
Can't find a <div> tag with selenium, why?

Time:12-06

For some reason I am unable to find the that I'm searching for. I'm trying to get the value of a certain stock with selenium-python. If anyone can explain why I can't get the with id = "stock-quote-tablet-phone" I would be very grateful.

Python-code:

class SeleniumDriver:
    def __init__(self):
        self.webdriver = webdriver.Chrome("chromedriver", options=options)
        self.webdriver.get("https://www.avanza.se/min-ekonomi/innehav.html")

        time.sleep(30)  # The user gets one minute to log into their account
        self.webdriver.get(AZELIO)
        print("Checkpoint")

        time.sleep(5)
        self.anchor = (
            self.webdriver.find_element(By.TAG_NAME, "aza-app")
            .find_element(By.TAG_NAME, "aza-shell")
            .find_element(By.TAG_NAME, "div")
            .find_element(By.TAG_NAME, "main")
            .find_element(By.TAG_NAME, "div")
            .find_element(By.TAG_NAME, "aza-stock")
            .find_element(By.TAG_NAME, "aza-subpage")
            .find_element(By.TAG_NAME, "div")
        )

    def getPrice(self):
        self.tmp = (
            self.anchor.find_element(By.TAG_NAME, "div")
            .find_element(By.TAG_NAME, "aza-pull-to-refresh")
            .find_elements(By.TAG_NAME, "div")[0]
            .find_element(By.TAG_NAME, "div")
            .find_element(By.TAG_NAME, "aza-page-container")
            .find_element(By.TAG_NAME, "aza-page-container-inset")
            .find_element(By.TAG_NAME, "section")
            .find_element(By.TAG_NAME, "div")
            .find_elements(By.TAG_NAME, "div")[0]
            .find_element(By.TAG_NAME, "aza-instrument-chart")
            .find_element(By.TAG_NAME, "div")
            .find_element(By.TAG_NAME, "div")
        )

        WebDriverWait(self.webdriver, 10).until(
            EC.presence_of_element_located((By.ID, "stock-quote-tablet-phone"))
        )

        self.price = self.tmp.find_element(
            By.CLASS_NAME, "ng-tns-c425-30 ng-star-inserted"
        )
        print(self.price.get_attribute("innerHTML"))

        print(self.tmp.get_attribute("innerHTML"))


testDriver = SeleniumDriver()
testDriver.getPrice()

HTML-code: Image of HTML-code

I have tried every sort of tmp.get_element() and tmp.get_elements() that I can think of. I expected to get the that I described, but for some reason I can't seem to find it.

CodePudding user response:

The problem is not defining the proper path to the element. Instead of using the get By.ID use XPath which gives a more accurate path to the element. To define XPath properly use can use SelectorHub chrome extension easliy.

Hoping the required element not in a iframe or frame or Shadow-DOM. If the element in the above behaviors it should be deal in another way.


To Deal with shadow DOM

There are some bits of Shadow DOM terminology to be aware of:

  • Shadow host: The regular DOM node to which the Shadow DOM is attached.
  • Shadow tree: The DOM tree inside the Shadow DOM.
  • Shadow boundary: The place where the Shadow DOM ends and the regular DOM begins.
  • Shadow root: The root node of the Shadow tree.

Finding Shadow DOM elements using Selenium WebDriver:

When we try to find the Shadow DOM elements using Selenium locators, we get NoSuchElementException as it is not directly accessible to the DOM.

We would use the following strategy to access the Shadow DOM locators:

  • Using JavaScriptExecutor.
  • Using Selenium WebDriver’s getShadowDom() method.

According to the Selenium Version (3,4), the job is different about shadow DOM. See this article about retrieving shadow DOM in Selenium v3,4.

  • Related