How can I reconnect to the browser opened by webdriver with selenium?

Yes, that’s actually quite easy to do.

A selenium <-> webdriver session is represented by a connection url and session_id, you just reconnect to an existing one.

Disclaimer – the approach is using selenium internal properties (“private”, in a way), which may change in new releases; you’d better not use it for production code; it’s better not to be used against remote SE (yours hub, or provider like BrowserStack/Sauce Labs), because of a caveat/resource drainage explained at the end.

When a webdriver instance is initiated, you need to get the before-mentioned properties; sample:

from selenium import webdriver

driver = webdriver.Chrome()
driver.get('https://www.google.com/')

# now Google is opened, the browser is fully functional; print the two properties
# command_executor._url (it's "private", not for a direct usage), and session_id

print(f'driver.command_executor._url: {driver.command_executor._url}')
print(f'driver.session_id: {driver.session_id}')

With those two properties now known, another instance can connect; the “trick” is to initiate a Remote driver, and provide the _url above – thus it will connect to that running selenium process:

driver2 = webdriver.Remote(command_executor=the_known_url)  
# when the started selenium is a local one, the url is in the form 'http://127.0.0.1:62526'

When that is ran, you’ll see a new browser window being opened.
That’s because upon initiating the driver, the selenium library automatically starts a new session for it – and now you have 1 webdriver process with 2 sessions (browsers instances).

If you navigate to an url, you’ll see it is executed on that new browser instance, not the one that’s left from the previous start – which is not the desired behavior.
At this point, two things need to be done – a) close the current SE session (“the new one”), and b) switch this instance to the previous session:

if driver2.session_id != the_known_session_id:   # this is pretty much guaranteed to be the case
    driver2.close()   # this closes the session's window - it is currently the only one, thus the session itself will be auto-killed, yet:
    driver2.quit()    # for remote connections (like ours), this deletes the session, but does not stop the SE server

# take the session that's already running
driver2.session_id = the_known_session_id

# do something with the now hijacked session:
driver.get('https://www.bing.com/')

And, that is it – you’re now connected to the previous/already existing session, with all its properties (cookies, LocalStorage, etc).

By the way, you do not have to provide desired_capabilities when initiating the new remote driver – those are stored and inherited from the existing session you took over.


Caveat – having a SE process running can lead to some resource drainage in the system.

Whenever one is started and then not closed – like in the first piece of the code – it will stay there until you manually kill it. By this I mean – in Windows for example – you’ll see a “chromedriver.exe” process, that you have to terminate manually once you are done with it. It cannot be closed by a driver that has connected to it as to a remote selenium process.
The reason – whenever you initiate a local browser instance, and then call its quit() method, it has 2 parts in it – the first one is to delete the session from the Selenium instance (what’s done in the second code piece up there), and the other is to stop the local service (the chrome/geckodriver) – which generally works ok.

The thing is, for Remote sessions the second piece is missing – your local machine cannot control a remote process, that’s the work of that remote’s hub. So that 2nd part is literally a pass python statement – a no-op.

If you start too many selenium services on a remote hub, and don’t have a control over it – that’ll lead to resource drainage from that server. Cloud providers like BrowserStack take measures against this – they are closing services with no activity for the last 60s, etc, yet – this is something you don’t want to do.

And as for local SE services – just don’t forget to occasionally clean up the OS from orphaned selenium drivers you forgot about 🙂

Leave a Comment

tech