2025, Nov 01 18:47

Дублирующиеся вкладки в Selenium и Chrome: причины и два безопасных решения

Python 3.11 + Selenium: клик по ссылке в Chrome открывает две вкладки. Объясняем причину и даем два решения: перейти по href или кликнуть без открытия новой.

Когда вы автоматизируете навигацию по сайту, неожиданный запуск нескольких вкладок от одного клика — это не просто раздражение. Он ломает логику работы с идентификаторами окон, сбивает последовательность проверок и тратит время. В связке Python 3.11 + Selenium + Chrome клик по ссылке на странице списка приводил к трём вкладкам: исходной и двум дубликатам. Цель проста: на каждое действие должен приходиться всего один переход и устойчивое управление окнами.

Как воспроизвести проблему

Фрагмент ниже открывает нужную страницу, кликает по элементу и ждёт появления трёх окон. Ровно в этом и суть: клик порождает дублирующиеся вкладки, после чего усложняется любая дальнейшая работа с HTML и фокусом окна.

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
from selenium.webdriver.chrome.options import Options
opts = Options()
opts.add_argument("--headless")
browser = webdriver.Chrome()  # опции намеренно не передаются здесь
browser.get("https://upn.ru/kupit/kvartiry")
page_heading = browser.title
print(page_heading)
pause = WebDriverWait(browser, 5)
base_window = browser.current_window_handle
assert len(browser.window_handles) == 1
_ = browser.find_element(By.CLASS_NAME, 'main-container-margins.width-100').click()
pause.until(EC.number_of_windows_to_be(3))
for handle in browser.window_handles:
    if handle != base_window:
        browser.switch_to.window(handle)
        break
page_heading = browser.title
print(page_heading)

Что происходит на самом деле

Страница реагирует на взаимодействие дважды. Сначала срабатывает обычное поведение ссылки, и Chrome открывает новую вкладку. Затем слушатель JavaScript, повешенный на тот же элемент, вызывает window.open(), создавая второй дубль. WebDriver лишь управляет браузером: если страница велит открыть цель дважды, вы увидите две новые вкладки.

Два безопасных варианта действий

Надёжное решение — прекратить запускать дублирующее поведение. Можно либо перейти по URL напрямую, вообще не кликая, либо обезвредить лишний обработчик и выполнить один клик.

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
cfg = webdriver.ChromeOptions()
cfg.add_argument('--headless')
drv = webdriver.Chrome(options=cfg)
drv.get('https://upn.ru/kupit/kvartiry')
waiter = WebDriverWait(drv, 5)
anchor = waiter.until(EC.element_to_be_clickable(
    (By.CSS_SELECTOR, 'a.card-title')  # при необходимости скорректируйте селектор под ваш элемент
))
# Подход 1: пропустите клик и откройте адрес напрямую
href_value = anchor.get_attribute('href')
drv.get(href_value)
# --- Либо, если вам всё-таки нужно «кликнуть» ---
# drv.execute_script(
#     "arguments[0].removeAttribute('target'); arguments[0].click();", anchor)
# waiter.until(EC.number_of_windows_to_be(2))

В первом варианте вы извлекаете href и переходите по нему напрямую. Неожиданно новые вкладки не создаются, браузер остаётся в одном окне. Во втором вы всё же кликаете, но предварительно удаляете атрибут target и ждёте ровно два окна — так число вкладок остаётся предсказуемым.

Почему это важно

Стабильное управление окнами критично для надёжной автоматизации. Когда каждое действие детерминированно приводит к одному переходу, переключение дескрипторов, проверки и запросы к DOM остаются согласованными. Устранив случайные дубликаты, вы не допускаете расхождения потока теста и сохраняете код простым.

Практические замечания

Точность селекторов имеет значение. Как только вы находите нужный элемент корректным CSS‑селектором, прямой переход по href работает чисто. Если селектор промахивается, можно получить сообщения вроде InvalidArgumentException: 'url' must be a string. Убедитесь, что выбираете правильную ссылку и передаёте её href в driver.get — это избавит от проблемы.

Итоги

Дублирующиеся вкладки обычно возникают из‑за того, что страница одновременно запускает два маршрута навигации. Устраняйте первопричину: либо вовсе не кликайте и переходите по href, либо нейтрализуйте лишний обработчик перед кликом. Держите поток в рамках одного предсказуемого открытия страницы — так логика работы с окнами остаётся последовательной и понятной.

Статья основана на вопросе на StackOverflow от Burtsev и ответе от Dmitry543.