How to open a new window or tab in webdriver (Python)?

后端 未结 4 2158
终归单人心
终归单人心 2021-01-06 11:49

I have tried various commands like

driver.switch_to_window(\"_blank\")

or

driver.switch_to_window(None)

b

4条回答
  •  醉梦人生
    2021-01-06 12:02

    I ran into the same issue, and I wasn't really satisfied with other solutions I found, so I made a context manager to do the handling. This allows:

    with link_in_new_window(driver, link_element):
        driver.foo()  # this is in the new window opened from the link
    driver.foo()  # this is back in the original window
    

    ..which I find to be very convenient.

    from contextlib import contextmanager
    from selenium.common import exceptions
    from selenium.webdriver.common.action_chains import ActionChains
    from selenium.webdriver.common.keys import Keys
    
    # Fundamentally, this shift-clicks to open a new window, and
    # hits ctrl-w to close it when done, using ActionChains.
    @contextmanager
    def link_in_new_window(driver, element):
        """Open a clickable element in a new window for this context
    
        This opens a clickable element in a new window, and switches
        `driver` to that window for the duration of the context.  
        The window is closed afterward, and the driver switched back
        to the original window.
    
        If the 'as' clause is used, the handle of the parent (original)
        window is provided as the value.
    
        Selenium doesn't provide a useful interface to firefox's tabs
        due to some technical complications, so we use new windows
        instead of new tabs. The memory hit isn't too significant.
    
        :type driver: selenium.webdriver.Firefox
        :type element: selenium.webdriver.remote.webelement.WebElement
        :returns: Parent's Window Handle
        """
    
        known_handles = set(driver.window_handles)
        original_handle = driver.current_window_handle
        action = ActionChains(driver)
        # Open link in new window (shift-click element)
        # Sometimes, shift would be ignored. move_to_element helped.
        action.move_to_element(element)
            .key_down(Keys.SHIFT)
            .click(element)
            .key_up(Keys.SHIFT)
            .perform()
    
        # Find the new window handle.  ..anyone know a better way?
        timeout = time.time() + 10
        new_handles = set(driver.window_handles) - known_handles
        while time.time() < timeout and not new_handles:
            new_handles = set(driver.window_handles) - known_handles
            time.sleep(0.5)
        if not new_handles or len(new_handles) != 1:
            msg = "Expected one handle, found {}"
            raise RuntimeError(msg.format(len(new_handles)), new_handles)
        new_handle = new_handles.pop()
        driver.switch_to.window(new_handle)
        try:
            # User code will be executed here
            yield original_handle
        finally:
            # close window, if it still exists (ctrl-w)
            try:
                driver.switch_to.window(new_handle)
                action = ActionChains(driver)
                action.key_down(Keys.CONTROL).send_keys('w').perform()
            except exceptions.NoSuchWindowException:
                pass
            # in any case, switch back to the original window
            driver.switch_to.window(original_handle)
    

提交回复
热议问题