pythonselenium-webdriver

Why does the driver open two tabs by one click?


I am trying to reach pages by hrefs nested to web elements. But the driver gives me two identical tabs when it click() on the href. It turns out that three tabs are open at the same time. Duplicate pages confuse further work with html. How can I get only one new tab by click?

Python 3.11, PyCharm

chrome_options = Options()
chrome_options.add_argument("--headless")
driver = webdriver.Chrome()
driver.get("https://upn.ru/kupit/kvartiry")
title = driver.title
print(title)

wait = WebDriverWait(driver, 5)
original_window = driver.current_window_handle
assert len(driver.window_handles) == 1

b_block = driver.find_element(By.CLASS_NAME, 'main-container-margins.width-100').click()
wait.until(EC.number_of_windows_to_be(3))
for window_handle in driver.window_handles:
        if window_handle != original_window:
            driver.switch_to.window(window_handle)
            break
title = driver.title
print(title)

enter image description here


Solution

  • The link is opened twice:
    • the normal <a> fires and Chrome opens a new tab
    • a JS listener on the same element calls window.open() and opens it again.
    WebDriver only replicates what the page tells the browser to do, so you have to avoid the click or neutralise the handler.

    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
    
    opt = webdriver.ChromeOptions()
    opt.add_argument('--headless')
    driver = webdriver.Chrome(options=opt)
    
    driver.get('https://upn.ru/kupit/kvartiry')
    
    w = WebDriverWait(driver, 5)
    link = w.until(EC.element_to_be_clickable(
            (By.CSS_SELECTOR, 'a.card-title')))      # pick the selector you need
    
    # simplest: open the URL yourself – no extra windows
    driver.get(link.get_attribute('href'))
    
    # --- or, if you really want to click ---
    # driver.execute_script(
    #     "arguments[0].removeAttribute('target'); arguments[0].click();", link)
    # wait until EC.number_of_windows_to_be(2)
    

    Only one new page is created, so further window-handle logic stays consistent.