首页 > 解决方案 > 无法存储 Selenium Web 驱动程序对象以通过 Django 视图恢复它

问题描述

经过几天的研究,我无法正确存储 Selenium Web 驱动程序对象以通过不同的 Django 视图恢复它。事实上,我的项目只有一个视图,我所需要的只是在每次调用该视图时恢复 Web 驱动程序对象的同一个实例。我的应用程序所做的只是向视图发出 AJAX 发布请求并更新前端和 Web 驱动程序窗口中的一些数据。
将驱动程序初始化为
driver = webdriver.Chrome(executable_path=driverpath, desired_capabilities=caps)
这些都是我尝试过的所有事情:

1) 将对象存储在 request.session 数组中。当然这是行不通的,一个 web 驱动对象被 JSON 序列化是很复杂的。 TypeError: Object of type WebDriver is not JSON serializable

2)Pickle 序列化:没用。
类似的代码 pickle.dumps(driver, open( "driver.p", "wb" ))会引发此错误AttributeError: Can't pickle local object '_createenviron.<locals>.encode'

3) 创建一个新的驱动程序并将之前的 Web 驱动程序 session_id 值分配给它的 session_id 属性。没用。这是方法:

   request.session['driver_id'] = driver.session_id
   #And then on another view call:
   chrome_options = Options()
   chrome_options.add_argument("--headless") #to prevent opening a new window
   new_driver = webdriver.Chrome(options=chrome_options)
   new_driver.session_id = request.session['driver_id'] 

4) 使用 Ctypes:这是有时唯一有效的解决方案,因此是唯一让我使用我的项目的解决方案。正如Slipstream在This Question上回答的那样,这将是方法:

import ctypes
request.session['id_my_obj'] = id(driver)
id_my_obj = request.session.get('id_my_obj')
obj = ctypes.cast(id_my_obj, ctypes.py_object).value

正如Martijn Pieters在那个答案中所说,

“这是一个非常糟糕的主意。如果您在多进程或多机设置中托管 Django,或者让 my_obj 被垃圾收集,这不仅不起作用,而且会导致内存损坏。”

我很确定这就是为什么它有时会失败甚至崩溃 django 的原因。但遗憾的是,这是唯一的解决方法。

我的问题是,是否有适当的方法来序列化 Selenium Web 驱动程序对象,或者至少将其存储在文件中或以后可以恢复的任何方式?
由于 ctypes 解决方案是唯一有效的解决方案,有没有办法改进它以使其每次都能正常工作?我不介意安全隐患,因为这仅供本地使用。

Python 版本:3.8.5
Django 版本:3.1.1
Selenium 版本:4.0.0a1

谢谢你。

标签: pythondjangoseleniumsessionstore

解决方案


推荐阅读