I am trying to find an element by Id but it is not working. After looking up the problem I also added wait but it did not have any impact on the result.
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Chrome()
driver.get("https://www.powerlanguage.co.uk/wordle/")
search = driver.find_element_by_xpath("//html")
search.click()
search.send_keys("brand")
search.send_keys(Keys.RETURN)
wait = WebDriverWait(driver, 15)
wait.until(EC.invisibility_of_element_located((By.ID, "game")))
board = driver.find_element_by_id("game")
driver.quit()
The exact Error :
line 17, in <module>
board = driver.find_element_by_id("game")
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"css selector","selector":"[id="game"]"}
CodePudding user response:
I saw the website and it has the Shadow DOM implementation, which implies that your regular selenium would not work. In order to access the elements wrapped under shadowRoot, you have to first open the shadowRoot and then access the elements under it. Something of this kind would work.
driver.execute_script("return document.querySelector('game-app').shadowRoot.querySelector('div')")
I assigned this to a variable and printed it and it showed the element:
<selenium.webdriver.remote.webelement.WebElement (session="e64c343467edb720adc5f74f438ddca3", element="fcf210fa-8b17-4f7e-93d0-0d5d1ce412e7")>
But I am really not sure what are going to perform after this, so stopping here and letting you explore on your own, but I think you got the concept. Using execute_script you have to first open the shadowRoot and then access the elements under it.
CodePudding user response:
The element with id="game" is in shadow root.
Using selenium 4:
shadow_root = driver.find_element(By.CSS_SELECTOR, 'game-app').shadow_root
game = shadow_root.find_element(By.CSS_SELECTOR, '#game')
