3

I am trying to scrape the data table from nasdaq: https://www.nasdaq.com/symbol/msft/interactive-chart?timeframe=5d

What I do is using python and selenium webdriver to click the table button(on top of the chart, with a little table logo) and then scrape.

submit = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, '#dataTableBtn')))
submit.click()

But it does not work.

Button html here:

<div id="dataTableBtn" class="btn hideSmallIR stx-collapsible" onclick="dataTableLoader()"><span>Data Table</span></div>

EC and By

from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
1
  • 1
    Its inside <iframe>, you need to switch to it first. Commented Aug 7, 2019 at 8:52

3 Answers 3

1

The chart and the associated elements are within an <iframe> so you have to:

  • Induce WebDriverWait for the desired frame to be available and switch to it.
  • Induce WebDriverWait for the desired element to be clickable.
  • You can use either of the following Locator Strategies:

    • Using CSS_SELECTOR:

      driver.get("https://www.nasdaq.com/symbol/msft/interactive-chart?timeframe=5d")
      WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR,"iframe[src*='edgar-chartiq']")))
      WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "div.hideSmallIR#dataTableBtn>span"))).click()
      
    • Using XPATH:

      driver.get("https://www.nasdaq.com/symbol/msft/interactive-chart?timeframe=5d")
      WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH,"//iframe[contains(@src, 'edgar-chartiq')]")))
      WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//div[@class='btn hideSmallIR stx-collapsible' and @id='dataTableBtn']/span[text()='Data Table']"))).click()
      
    • Note : You have to add the following imports :

      from selenium.webdriver.support.ui import WebDriverWait
      from selenium.webdriver.common.by import By
      from selenium.webdriver.support import expected_conditions as EC
      
  • Browser Snapshot:

nasdaq_datatable

Here you can find a relevant discussion on Ways to deal with #document under iframe

Sign up to request clarification or add additional context in comments.

4 Comments

Why don't you use '#chartholder > iframe' as the CSS SELECTOR?
@MosheSlavin From a generic approach, the search for a direct iframe tag will be much more faster. However '#chartholder > iframe' would also work.
Yes it works! I am new to web scraping so I am not familiar with iframe. Thanks so much for your help!
@DebanjanB Your locator to find the IFRAME vs MosheSlavin's will be negligible in speed difference. Where are you getting, the search for a direct iframe tag will be much more faster?
1

The table is in an iframe, so just switch to it!

frame = driver.find_element_by_css_selector('#chartholder > iframe')
driver.switch_to.frame(frame)

You can use WebDriverWait with EC like this:

frame = driver.find_element_by_css_selector('#chartholder > iframe')
wait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it(frame))

Comments

-1

The button you're looking for belongs to an iframe so you will have to switch to it prior to attempting to find the button.

Both iframe and the button can be located using XPath contains() function

driver.switch_to.frame(driver.find_element_by_xpath("//iframe[contains(@src,'edgar-chartiq')]"))

Once you're in the iframe you should be able to locate and click the button:

driver.find_element_by_xpath("//*[contains(text(),'Data Table')]").click()

1 Comment

Why use XPath and contains() when you can use CSS?

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.