Pickling Selenium Webdriver Objects
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"