1

I am trying to automatically load charts on www.investing.com. My main aim is to click the "load chart layout" button which can be found at https://www.investing.com/charts/live-charts (third button from the top right in the chart iframe, looks like a cloud). Being new to selenium, I learned about iframes and after some inspection I found that the button is located in an iframe which in in an iframe which is in an iframe. I am finally correctly switching to the iframe that contains the button but for some reason the find_element_by_xxx function always says not found whether I use class, id, xpath or whatever. My code is as follows

import time
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.common.exceptions import TimeoutException


def findFrames(driver):
    iframes = driver.find_elements_by_xpath('//iframe')
    i = 0
    index = 0
    for iframe in iframes:
        print(iframe.get_attribute('src'))

        string = iframe.get_attribute('src')
        if "tv" in string:
            index = i
            break
        i+=1
    print(index)
    return iframes, index

def main():
    chrome_options = Options()
    chrome_options.add_experimental_option("detach", True)
    #chrome_options.add_argument("/tmp/.com.google.Chrome.sBnz8G/Profile 1")
    driver = webdriver.Chrome(options=chrome_options)
    driver.get("http://www.investing.com")

    try:
        #time.sleep(10)
        driver.find_element_by_xpath("/html/body/div[5]/header/div[1]/div/div[4]/span[1]/div/a[1]").click()
        time.sleep(3)
    except:
        print("first block")

    try:
        WebDriverWait(driver, 20).until(EC.presence_of_element_located((By.ID, 'loginPopup')))
        print("found")
    except:
        print("not found")

    try:
        elem = driver.find_element_by_id("loginFormUser_email")
        elem.click()
        elem.send_keys("my-email")
        elem = driver.find_element_by_id("loginForm_password")
        elem.click()
        elem.send_keys("my-password")
        elem.send_keys(Keys.ENTER)
        time.sleep(3)
    except: 
        print("second block")


    driver.find_element_by_xpath('//*[@id="navMenu"]/ul/li[5]/a').click()
    print("charts clicked")
    time.sleep(3)
    driver.find_element_by_xpath("/html/body/div[5]/section/div[4]/div[1]/a").click()
    print("live charts clicked")
    time.sleep(20)
    iframes, index = findFrames(driver)
    driver.switch_to.frame(iframes[index])
    print("switch 1")
    iframes, index = findFrames(driver)
    driver.switch_to.frame(iframes[index])
    print("switch 2")
    iframes, index = findFrames(driver)
    driver.switch_to.frame(iframes[index])
    print("switch 3")

    driver.find_element_by_xpath('/html/body/div[1]/div[2]/div/div/div[1]/div[3]/div/span[1]/svg').click() #THIS IS WHERE I GET THE ERROR
    print("successfully clicked load")
    time.sleep(1.5)


if __name__ == "__main__":
    main()

Can someone find out why it says not found even though I switch to the correct frame?

1 Answer 1

1

The load chart layout is present inside nested iframes.

To handle dynamic element Induce WebDriverWait() and frame_to_be_available_and_switch_to_it() following cssselector

Induce WebDriverWait() and wait for element_to_be_clickable() and following cssselector

driver.find_element_by_xpath("/html/body/div[5]/section/div[4]/div[1]/a").click()
print("live charts clicked")
WebDriverWait(driver,10).until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR,"iframe[id^='tvc_frame']")))
WebDriverWait(driver,10).until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR,"iframe[src$='GB']")))
WebDriverWait(driver,10).until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR,"iframe[id^='tradingview']")))
WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.CSS_SELECTOR,"div.save-load-buttons>span.load"))).click()
print("successfully clicked load")

You need to import following libraries

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
Sign up to request clarification or add additional context in comments.

3 Comments

Hey I understand that. The iframes and everything load and I successfully switch to them too but still the final element is not found.
The code executed successfully on my machine.did you copy my entire code and executed.
I tried it and it's working! Not sure what was wrong with my code but this helped a lot! Thank you!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.