Skip to content Skip to sidebar Skip to footer

Pickling Selenium Webdriver Objects

I want to serialize and store a selenium webdriver object so then I could use it later elsewhere in my code. I'm trying to use pickle to do this. If there is another way to save th

Solution 1:

I was able to pickle a selenium.webdriver.Remote object. Neither dill or pickle worked for me to serialize a selenium.webdriver.Chrome object, in which python creates and runs the browser process. However, they both worked if I (1) ran the standalone java selenium2 webserver, (2) in one process, create a selenium.webdriver.Remote connection to that server and pickle/dill that to a file, (3) In another process, unserialize the Remote instance and use it.

This led to being able to close the python process and then re-connect to the existing webdriver browser and issue new commands (could be from a different python script). If I close the selenium web browser then a new instance needs to be created from scratch.

server.py:

import pickle
import selenium.webdriverEXECUTOR='http://127.0.0.1:4444/wd/hub'
FILENAME = '/tmp/pickle'

opt = selenium.webdriver.chrome.options.Options()
capabilities = opt.to_capabilities()
driver = selenium.webdriver.Remote(command_executor=EXECUTOR, desired_capabilities=capabilities)
fp = open(FILENAME, 'wb')
pickle.dump(driver, fp)

client.py:

import pickle

FILENAME = '/tmp/pickle'

driver = pickle.load(open(FILENAME, 'rb')
driver.get('http://www.google.com')
el = driver.find_element_by_id('lst-ib')
print(el)

Note (2020-08-08): Pickling selenium in this way stopped working in the latest selenium (4.x). Pickle fails to pickle an internal socket object. One option is to add a 'selenium=3.141.0' item to the install_requires component in setup.py which still works for me.

Solution 2:

As far as i know from using Protractor\C# architectures:

Basic usage can be deceiving, meaning when using ChromeDriver in C# you get a mask of all the fuss behind the scenes BUT declaring and initializing a webDriver creates and start a 'server' (in Protractor it's done manually). The webDriver uses some of this server's abilities and states.

I think of the webDriver not as an object but as an API. The representation of this API as an object is for the ease of use, so I beleave what you ask for is not possible.

Solution 3:

You don't need to pickle the webdriver object It is enough to save the executor_url and session_id (instead of pickle.dump()), create a new webdriver object and attache it to the existing session (instead of pickle.load())

defattach_to_session(executor_url, session_id):
    original_execute = WebDriver.execute

    defnew_command_execute(self, command, params=None):
        if command == "newSession":
            return {'success': 0, 'value': None, 'sessionId': session_id}
        else:
            return original_execute(self, command, params)

    WebDriver.execute = new_command_execute
    driver = webdriver.Remote(command_executor=executor_url)
    driver.session_id = session_id
    WebDriver.execute = original_execute
    return driver

Post a Comment for "Pickling Selenium Webdriver Objects"