Can Selenium interact with an existing browser session?

后端 未结 11 1053
野性不改
野性不改 2020-11-22 08:47

Does anybody know if Selenium (WebDriver preferably) is able to communicate with and act through a browser that is already running before launching a Selenium Client?

11条回答
  •  佛祖请我去吃肉
    2020-11-22 09:01

    Inspired by Eric's answer, here is my solution to this problem for selenium 3.7.0. Compared with the solution at http://tarunlalwani.com/post/reusing-existing-browser-session-selenium/, the advantage is that there won't be a blank browser window each time I connect to the existing session.

    import warnings
    
    from selenium.common.exceptions import WebDriverException
    from selenium.webdriver.remote.errorhandler import ErrorHandler
    from selenium.webdriver.remote.file_detector import LocalFileDetector
    from selenium.webdriver.remote.mobile import Mobile
    from selenium.webdriver.remote.remote_connection import RemoteConnection
    from selenium.webdriver.remote.switch_to import SwitchTo
    from selenium.webdriver.remote.webdriver import WebDriver
    
    
    # This webdriver can directly attach to an existing session.
    class AttachableWebDriver(WebDriver):
        def __init__(self, command_executor='http://127.0.0.1:4444/wd/hub',
                     desired_capabilities=None, browser_profile=None, proxy=None,
                     keep_alive=False, file_detector=None, session_id=None):
            """
            Create a new driver that will issue commands using the wire protocol.
    
            :Args:
             - command_executor - Either a string representing URL of the remote server or a custom
                 remote_connection.RemoteConnection object. Defaults to 'http://127.0.0.1:4444/wd/hub'.
             - desired_capabilities - A dictionary of capabilities to request when
                 starting the browser session. Required parameter.
             - browser_profile - A selenium.webdriver.firefox.firefox_profile.FirefoxProfile object.
                 Only used if Firefox is requested. Optional.
             - proxy - A selenium.webdriver.common.proxy.Proxy object. The browser session will
                 be started with given proxy settings, if possible. Optional.
             - keep_alive - Whether to configure remote_connection.RemoteConnection to use
                 HTTP keep-alive. Defaults to False.
             - file_detector - Pass custom file detector object during instantiation. If None,
                 then default LocalFileDetector() will be used.
            """
            if desired_capabilities is None:
                raise WebDriverException("Desired Capabilities can't be None")
            if not isinstance(desired_capabilities, dict):
                raise WebDriverException("Desired Capabilities must be a dictionary")
            if proxy is not None:
                warnings.warn("Please use FirefoxOptions to set proxy",
                              DeprecationWarning)
                proxy.add_to_capabilities(desired_capabilities)
            self.command_executor = command_executor
            if type(self.command_executor) is bytes or isinstance(self.command_executor, str):
                self.command_executor = RemoteConnection(command_executor, keep_alive=keep_alive)
    
            self.command_executor._commands['GET_SESSION'] = ('GET', '/session/$sessionId')  # added
    
            self._is_remote = True
            self.session_id = session_id  # added
            self.capabilities = {}
            self.error_handler = ErrorHandler()
            self.start_client()
            if browser_profile is not None:
                warnings.warn("Please use FirefoxOptions to set browser profile",
                              DeprecationWarning)
    
            if session_id:
                self.connect_to_session(desired_capabilities)  # added
            else:
                self.start_session(desired_capabilities, browser_profile)
    
            self._switch_to = SwitchTo(self)
            self._mobile = Mobile(self)
            self.file_detector = file_detector or LocalFileDetector()
    
            self.w3c = True  # added hardcoded
    
        def connect_to_session(self, desired_capabilities):
            response = self.execute('GET_SESSION', {
                'desiredCapabilities': desired_capabilities,
                'sessionId': self.session_id,
            })
            # self.session_id = response['sessionId']
            self.capabilities = response['value']
    

    To use it:

    if use_existing_session:
        browser = AttachableWebDriver(command_executor=('http://%s:4444/wd/hub' % ip),
                                      desired_capabilities=(DesiredCapabilities.INTERNETEXPLORER),
                                      session_id=session_id)
        self.logger.info("Using existing browser with session id {}".format(session_id))
    else:
        browser = AttachableWebDriver(command_executor=('http://%s:4444/wd/hub' % ip),
                                      desired_capabilities=(DesiredCapabilities.INTERNETEXPLORER))
        self.logger.info('New session_id  : {}'.format(browser.session_id))
    

提交回复
热议问题