我试图在 python selenium 会话中单击接受 cookies 按钮,但它位于影子 DOM 内。这是我的代码的概要:
# Python version 3.10.9
# selenium version 3.141.0
from selenium import webdriver
from selenium.webdriver.common.by import By
from time import sleep
url = "https://www.cottages.com/search?adult=2&child=0&infant=0&pets=0&range=3&nights=7&accommodationType=cottages&start=29-12-2023&page=1&sort=priceasc®ionId=21996®ionName=South+West+England"
driver = webdriver.Chrome(executable_path=r"C:/xxx/chromedriver-win64/chromedriver.exe")
driver.get(url)
sleep(5)
driver.implicitly_wait(5)
host = driver.find_element(By.XPATH, "/html/body/div[7]")
root = driver.execute_script("return arguments[0].shadowRoot", host)
root.find_element(By.CLASS_NAME , 'sc-dcJsrY jLOXfK').click()
这返回了一个 AttributeError,即 dict 没有属性“find_element”。
我在这里的其他地方看到了这种方法(例如 如何从 Selenium 处理 Shadow DOM 中的元素),这就是我尝试它的原因。
当我打印
root
时,我看到它只是以下字典:
{'shadow-6066-11e4-a52e-4f735466cecf': '92E369CF463093341CE4281E8449D891_element_93'}
关于如何访问此元素以单击它有什么想法吗?
你至少应该等待
shadow host
的出现。
不知道为什么您会收到错误 AttributeError
- 我收到错误,您的代码中未找到带有定位器 sc-dcJsrY jLOXfK
的元素。
但是,这是一般同意元素,可以通过以下代码接受:
from selenium import webdriver
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()
timeout = 10
wait = WebDriverWait(driver, timeout)
def get_shadow_root(element):
return driver.execute_script('return arguments[0].shadowRoot', element)
driver.get("https://www.cottages.com/search?adult=2&child=0&infant=0&pets=0&range=3&nights=7&accommodationType=cottages&start=29-12-2023&page=1&sort=priceasc®ionId=21996®ionName=South+West+England")
driver.maximize_window()
shadow_host = wait.until(EC.presence_of_element_located((By.ID, 'usercentrics-root')))
shadow_container = get_shadow_root(shadow_host).find_element(By.CSS_SELECTOR, '[data-testid=uc-app-container]')
WebDriverWait(shadow_container, timeout).until(EC.visibility_of_element_located((By.CSS_SELECTOR, '[data-testid=uc-accept-all-button]'))).click()
wait.until(EC.invisibility_of_element_located((By.ID, 'usercentrics-root')))