python 如何在shadow-root中使用Selenium单击可单击的元素(已关闭)?

lbsnaicq  于 2023-11-16  发布在  Python
关注(0)|答案(3)|浏览(318)

一个“同意条款”按钮出现在https://www.sreality.cz/hledani/prodej/domy上,我试图使用Selenium和Python使用.click()来完成它。button元素是:

<button data-testid="button-agree" type="button" class="scmp-btn scmp-btn--default w-button--footer sm:scmp-ml-sm md:scmp-ml-md lg:scmp-ml-dialog">Souhlasím</button>

字符串
我的方法是:

driver = webdriver.Chrome()
driver.implicitly_wait(20)

driver.get("https://www.sreality.cz/hledani/prodej/domy")

button = driver.find_element_by_css_selector("button[data-testid='button-agree']")
button.click()


有什么想法改变它的工作吗?谢谢!:)

kyks70gy

kyks70gy1#

检查以下工作解决方案:

driver = webdriver.Chrome()
driver.implicitly_wait(10)
driver.get("https://www.sreality.cz/hledani/prodej/domy")
driver.maximize_window()

# Below line creates instance of ActionChains class 
action = ActionChains(driver)
# Below line locates and stores an element which is outside the shadow-root
element_outside_shadow = driver.find_element(By.XPATH, "//div[@class='szn-cmp-dialog-container']")
# Below 2 lines clicks on the browser at an offset of co-ordinates x=5 and y=5
action.move_to_element_with_offset(element_outside_shadow, 5, 5)
action.click()
# Below 2 lines presses TAB key 9 times so that pointer moves to "Souhlasím" button and presses ENTER key once
action.send_keys(Keys.TAB * 9).perform()
action.send_keys(Keys.ENTER).perform()

字符串
所需进口:

from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By

注:

1.这是一种解决方案,因为没有直接的 selenium 解决方案来处理它。

e5nszbig

e5nszbig2#

您的代码看起来是正确的,但问题可能与您要执行的单击的时间有关。页面可能需要更长的时间加载,并且您必须在准备好单击之后单击按钮。请尝试使用以下代码:

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium import webdriver

driver = webdriver.Chrome()
driver.implicitly_wait(20)

driver.get("https://www.sreality.cz/hledani/prodej/domy")

wait = WebDriverWait(driver, 10)
button = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button[data-testid='button-agree']")))
button.click()

字符串
我们使用WebDriverWait类等待按钮可点击后再点击。EC.element_to_be_clickable方法检查元素是否可见并启用,以确保可以点击。我们使用10秒的超时等待,但您可以调整它。
这个想法来自这个帖子:Wait for element to be clickable using python and Selenium

o7jaxewo

o7jaxewo3#

我知道这有点太晚了,但是如果shadow-root (closed)没有放在跨源iframe中(在你的例子中没有放置),它是可以访问的。
由于Selenium实现了CDP协议API,您可以覆盖Element类原型方法attachShadow,并在页面加载之前对新文档进行脚本评估。
因此,当shadow-root节点被附加到页面上下文中时,它将被自动创建,状态为open
但是,如果shadow-root (closed)被放置在iframe中,而资源不是你控制的,那么由于CORS的原因,覆盖iframeElement.contentWindow.Element将是不可能的。
How to override Element properties
How to executed script on load via CDP Protocol
解决方案不适用于您的案例:

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()
wait = WebDriverWait(driver, 10)

url = "https://www.sreality.cz/hledani/prodej/domy"

driver.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument', {'source': """
Element.prototype._attachShadow = Element.prototype.attachShadow;
Element.prototype.attachShadow = function () {
    return this._attachShadow( { mode: "open" } );
};
"""})
driver.get(url)

closed_shadow_host = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, '.szn-cmp-dialog-container')))
shadow_root = driver.execute_script('return arguments[0].shadowRoot', closed_shadow_host)

button = shadow_root.find_element(By.CSS_SELECTOR, "button[data-testid='button-agree']")
button.click()

字符串

相关问题