I need help locating the Xpath or CSS Selector of the download JSON button on this page.
https://data.ntsb.gov/carol-main-public/query-builder?month=12&year=1962
I copied the selector via Chrome browser but it is not locating the button when I control find.
Xpath -> //*[@id="exportResultsButton"]
CSS -> #exportResultsButton
Your button is placed inside several shadow-root
s, to get internal shadow root structure, you should get it's host first and then get shadowRoot
property.
In your case you can write function that drills inside several shadow-roots.
app-container
query_builder
results
get_shadow_root
function gets shadow root from host, using JS executor.
drill_into_shadow_roots
goes inside every provided selector from array, makes it host and gets shadowRoot
property, so next iteration would start from new host.
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium import webdriver
timeout = 10
def get_shadow_root(element):
return driver.execute_script('return arguments[0].shadowRoot', element)
def drill_into_shadow_roots(selectors):
host = None
_wait = WebDriverWait(driver, timeout)
for by, selector in selectors:
host = _wait.until(EC.presence_of_element_located((by, selector)))
host = get_shadow_root(host)
_wait = WebDriverWait(host, timeout)
return host
driver.get("https://data.ntsb.gov/carol-main-public/query-builder?month=12&year=1962")
selectors = [(By.TAG_NAME, 'app-container'), (By.ID, 'query_builder'), (By.ID, 'results')]
results = drill_into_shadow_roots(selectors)
WebDriverWait(results, timeout).until(EC.visibility_of_element_located((By.ID, 'exportResultsButton'))).click()