Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Reusing Existing Browser Sessions in Selenium WebDriver

Tech May 10 4

When WebDriver instantiates a new browser, it always creates a fresh browser session. However, there are scenarios where reusing an existing session becomes necessary. For web scraping tasks, you might want the browser to remain idle after script completion so the next run continues from where it left off. In test automation, after performing numerous setup operations, you wouldn't want to repeat them if the program crashes and restarts.

While this functionality proves quite practical, the official Selenium API doesn't provide built-in support for it.

How Browser Sessions Work

Starting a browser session through WebDriver involves three distinct phases:

  1. Launching the browser driver proxy (ChromeDriver, GeckoDriver, etc.)
  2. Creating a command executor to send operational commands to the proxy
  3. Establishing a new browser session through the proxy, which communicates with the browser using a sessionId to identify the session

To reuse an existing session, you need only two components: the executor from phase 2 and the sessionId from phase 3.

Capturing Session Information

from selenium import webdriver

browser = webdriver.Chrome()
remote_url = browser.command_executor._url
session_id = browser.session_id

print(session_id)
print(remote_url)
browser.get("http://example.com")

Running this script opens Chrome. Since quit() was never called, the browser remains active. However, the browser object has been destroyed in Python, making this a zombie browser that can only be controlled manually.

The output displays something like:

abc123def456
http://127.0.0.1:52869

Attempting Direct Reconnection

Stack Overflow suggests a straightforward approacch:

from selenium import webdriver

browser = webdriver.Chrome()
remote_url = browser.command_executor._url
session_id = browser.session_id
browser.get("http://example.com")

print(session_id)
print(remote_url)

browser2 = webdriver.Remote(command_executor=remote_url, desired_capabilities={})
browser2.session_id = session_id
print(browser2.current_url)

This method connects to the previous session but simultaneously opens a new blank tab. The Remote class automatically calls start_session during instantiation, wich creates a fresh session regardless of the session_id assignment.

Creating a Custom Remote Class

The solution requires subclassing Remote and overriding start_session to prevent automatic session creation:

from selenium.webdriver import Remote
from selenium.webdriver.chrome import options
from selenium.common.exceptions import InvalidArgumentException

class ReusableBrowser(Remote):

    def __init__(self, command_executor, session_id):
        self.stored_session_id = session_id
        Remote.__init__(self, command_executor=command_executor, desired_capabilities={})

    def start_session(self, capabilities, browser_profile=None):
        """
        Override start_session to use existing session instead of creating a new one
        """
        if not isinstance(capabilities, dict):
            raise InvalidArgumentException("Capabilities must be a dictionary")
        
        if browser_profile:
            if "moz:firefoxOptions" in capabilities:
                capabilities["moz:firefoxOptions"]["profile"] = browser_profile.encoded
            else:
                capabilities.update({'firefox_profile': browser_profile.encoded})

        self.capabilities = options.Options().to_capabilities()
        self.session_id = self.stored_session_id
        self.w3c = False

Complete Reconnection Example

from selenium import webdriver

# First run: create new browser session
browser = webdriver.Chrome()

# Store connection details for later reuse
remote_url = browser.command_executor._url
session_id = browser.session_id

# Navigate to a site
browser.get("http://example.com")

print(session_id)
print(remote_url)

# Simulate the browser object being destroyed
del browser

# Reconnect using the custom class
browser2 = ReusableBrowser(command_executor=remote_url, session_id=session_id)

# Verify reconnection succeeded by checking current URL
print(browser2.current_url)

# Continue using the existing session
browser2.get("http://another-site.com")

This approach successfully reconnects to the previously opened browser session without launching a new instance, allowing you to pick up exactly where you left off.

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.