社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

在SeleniumWeb驱动程序python中打开相同的会话[重复]

Noran Magdi • 6 年前 • 1726 次点击  

由于一些未知的原因,我的浏览器非常缓慢地打开远程服务器的测试页。所以我在想,退出脚本后是否可以重新连接到浏览器,但不执行 webdriver.quit() 这将使浏览器保持打开状态。它可能是一种钩子或WebDriver句柄。 我查找了Selenium API文档,但没有找到任何函数。 我使用的是Chrome62、X64、Windows7、Selenium 3.8.0。 这个问题能否解决,我将不胜感激。

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/39123
 
1726 次点击  
文章 [ 3 ]  |  最新文章 6 年前
Eugene S
Reply   •   1 楼
Eugene S    7 年前

如果不了解为什么你认为保持一个开放的浏览器窗口可以解决速度慢的问题,你就不需要真正的手柄来完成这个任务。继续运行测试而不关闭会话,换句话说,不调用 driver.quit() 正如你所提到的。这里的问题是,尽管框架本身也有运行程序?像黄瓜?

在任何情况下,都必须有一些“设置”和“清理”代码。因此,您需要做的是确保在“清理”阶段,浏览器回到其初始状态。这意味着:

  • 显示空白页
  • 会话的cookie将被删除
Todor Minakov
Reply   •   2 楼
Todor Minakov    6 年前

是的 这其实很容易做到。

Selenium<->WebDriver会话由连接URL和会话ID表示,您只需重新连接到现有会话即可。

免责声明 -方法是使用硒内部属性(“private”,在某种程度上),这可能会在新版本中发生变化;您最好不要将其用于生产代码;最好不要将其用于远程SE(您的集线器或BrowserStack/Sauce Labs等提供商),因为存在警告/资源排放解释最后是内德。

启动WebDriver实例时,需要获取前面提到的属性;示例:

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}')

有了这两个已知的属性,另一个实例就可以连接;诀窍是启动 Remote 司机,并提供 _url 因此,它将连接到运行硒工艺:

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'

当它运行时,您将看到一个新的浏览器窗口正在打开。
这是因为在启动驱动程序后,Selenium库会自动为它启动一个新的会话——现在您有了一个WebDriver进程和两个会话(浏览器实例)。

如果您导航到一个URL,您将看到它是在那个新的浏览器实例上执行的,而不是从上一次启动时开始的,这不是所需的行为。
此时,需要做两件事-a)关闭当前SE会话(“新会话”),b)将此实例切换到上一个会话:

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/')

也就是说,您现在已经连接到上一个/已经存在的会话,以及它的所有属性(cookie、localstorage等)。

顺便说一下,你不必提供 desired_capabilities 当启动新的远程驱动程序时-这些驱动程序是从您接管的现有会话中存储和继承的。


告诫 -运行SE过程会导致系统中的一些资源排放。

无论何时启动一个程序,然后又不关闭(就像在第一段代码中一样),它都会一直保持在那里,直到您手动杀死它。我的意思是-例如在Windows中-您将看到一个“chromedriver.exe”进程,一旦完成该进程,就必须手动终止它。对于远程Selenium进程,驱动程序无法关闭它。
原因-无论何时启动本地浏览器实例,然后调用 quit() 方法,它包含两个部分——第一个部分是从Selenium实例中删除会话(在上面的第二个代码片段中所做的),另一个部分是停止本地服务(chrome/geckoDriver)——这通常工作正常。

问题是,对于远程会话,第二个部分丢失了——您的本地计算机无法控制远程进程,这是该远程中心的工作。所以第二部分实际上是 pass python语句-a no-op.

如果您在一个远程集线器上启动了太多的Selenium服务,并且无法对其进行控制,这将导致该服务器的资源流失。像browserstack这样的云提供商采取了措施来应对这一情况——他们关闭的服务在过去60年代没有任何活动,等等——这是你不想做的事情。

至于本地的SE服务,不要忘记偶尔清理一下你忘记的孤立硒驱动程序的操作系统。

DebanjanB
Reply   •   3 楼
DebanjanB    7 年前

,无法重新连接到上一个 Web Browser 退出脚本后的会话。即使你能提取 Session ID , Cookies 以及上一个会话的其他属性 Browsing Session 但是,您仍然无法将这些属性作为钩子传递给 WebDriver .

一个更干净的方法是打电话 webdriver.quit() 然后跨越一个新的 浏览会话 .

历史记录:

以前有过一些讨论,并试图重新连接 Web驱动程序 到正在运行的现有浏览会话。您可以在以下QA中找到讨论: