Задать вопрос
  • Как с помощью Selenium на Python найти элемент html страницы, который расположен в #shadow-root (open)?

    @DenisProk Автор вопроса
    У меня, к сожалению, не работает :( Что-то с джава скриптом, при условии, что я правильно проставил отступы при переносе кода:

    raise exception_class(message, screen, stacktrace)
    selenium.common.exceptions.JavascriptException: Message: javascript error: Cannot read properties of null (reading 'querySelector')

    from selenium import webdriver
    from webdriver_manager.chrome import ChromeDriverManager
    from selenium.webdriver.chrome.service import Service
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    from time import sleep
    
    # 1. Настройки и запуск браузера
    chrome_options = webdriver.ChromeOptions()
    chrome_options.add_argument("--window-size=1000,900")
    service = Service(ChromeDriverManager().install())
    driver = webdriver.Chrome(service=service, options=chrome_options)
    wait = WebDriverWait(driver, 15)
    
    # 2. Открываем сайт
    driver.get("https://eaist.mos.ru/login.html?redirect=https://eaist.mos.ru/panel.html")
    
    # 3. Кнопка "Войти в систему"
    login_button = wait.until(EC.element_to_be_clickable(
        (By.XPATH, "/html/body/div[1]/div/button")
    ))
    login_button.click()
    
    # 4. Функция для доступа к элементу внутри вложенных Shadow DOM
    def get_shadow_element(driver, selectors):
        script = '''
    let el = document;
    for (let sel of arguments[0]) {
    el = el.querySelector(sel);
    if (el && el.shadowRoot) {
    el = el.shadowRoot;
    }
    }
    return el;
    '''
        return driver.execute_script(script, selectors)
    
    # 5. Ждём загрузки Shadow DOM
    sleep(2)
    
    # 6. Путь до нужного элемента внутри Shadow DOM
    selectors = [
        'eaist-app',  # Первый Shadow Host
        'eaist-panel-view',  # Вложенный Shadow Host
        'cookie-notification'  # Ещё один Shadow Host
    ]
    
    # 7. Получаем нужный элемент и кликаем по кнопке
    shadow = get_shadow_element(driver, selectors)
    button = shadow.find_element(By.CSS_SELECTOR, 'button')  # Возможно, нужно уточнить селектор!
    button.click()
    
    # 8. Закрываем браузер
    sleep(3)
    driver.quit()
    Написано
  • Как с помощью Selenium на Python найти элемент html страницы, который расположен в #shadow-root (open)?

    @DenisProk Автор вопроса
    Благодарю за ответ, как буду за компом, посмотрю
    Написано
  • Как с помощью Selenium на Python найти элемент html страницы, который расположен в #shadow-root (open)?

    @DenisProk Автор вопроса
    Мне удалось дотянуться до кнопки о принятии куки, но нажать на нее не получается, выдает ошибку (закопировал в конец кода). Якобы нужно на span нажимать или я что-то не так понимаю?

    67efd3008f91e318791739.png

    from selenium import webdriver
    from webdriver_manager.chrome import ChromeDriverManager
    from selenium.webdriver.chrome.service import Service
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    from time import sleep
    
    chrome_options = webdriver.ChromeOptions()
    chrome_options.add_argument("--window-size=1920,1040")
    service = Service(executable_path=ChromeDriverManager().install())
    driver = webdriver.Chrome(service=service, options=chrome_options)
    wait = WebDriverWait(driver, 15, poll_frequency=1)
    
    driver.get("https://eaist.mos.ru/login.html?redirect=https://eaist.mos.ru/panel.html")
    
    # Кнопка: "Войти в систему"
    LOGIN = ("xpath", "/html/body/div[1]/div/button")
    # Нажимаю на кнопку "Войти в систему"
    wait.until(EC.element_to_be_clickable(LOGIN)).click()
    
    def get_shadow_root(element):
        return driver.execute_script('return arguments[0].shadowRoot', element)
    
    # Получаю дерево 1-го хоста
    shadow_host_1 = driver.find_element(
        "css selector",
        '[version="1"]'
    )
    # Получаю дерево 2-го хоста, который внутри 1-го
    shadow_host_2 = get_shadow_root(shadow_host_1).find_element(
        'css selector',
        '[data-test-id="Модальное окно согласия на обработку ПД"]'
    )
    # Получаю дерево 3-го хоста, который внутри 2-го
    shadow_host_3 = shadow_host_2.find_element(
        'css selector',
        '[data-test-id="Понятно"]'
    )
    # Нахожу кнопку внутри дерева 3-го хоста
    button = get_shadow_root(shadow_host_3).find_element(
        'css selector',
        '[class="container"]'
    )
    
    # Дожидаюсь кликабельности кнопки и нажимаю на нее
    wait.until(EC.element_to_be_clickable(button)).click()
    
    sleep(10)
    driver.close()
    
    # Получаю вот такую ошибку:
    
    # selenium.common.exceptions.ElementClickInterceptedException: 
    # Message: element click intercepted: Element <button class="container" type="positive" size="large">...</button> is not clickable 
    # at point (1153, 448). Other element would receive the click: <span>...</span>
    Написано
  • Как с помощью Selenium на Python найти элемент html страницы, который расположен в #shadow-root (open)?

    @DenisProk Автор вопроса
    Спасибо за ответ! Завтра буду продолжать пробовать дальше. Если что-то получится, обязательно отпишусь
    Написано
  • Как с помощью Selenium на Python найти элемент html страницы, который расположен в #shadow-root (open)?

    @DenisProk Автор вопроса
    Дополняю, вот похожий случай, но добиться рабочего решения для моего случая на основе данного ответа у меня не вышло(

    https://stackoverflow.com/questions/77105233/how-d...
    Написано