如何重新连接Web Driver使用Selenium打开的浏览器?
由于某些未知原因,我的浏览器非常缓慢地打开远程服务器的测试页面。因此,我想在退出脚本后是否可以重新连接到浏览器,但不要执行webdriver.quit()
这将使浏览器打开。它可能是挂钩或网络驱动器的手柄。 我已经查找了Selenium API文档,但没有找到任何功能。 我正在使用Chrome 62、 X64,Windows 7,Selenium 3.8.0。 是否可以解决这个问题,我将不胜感激。
For some unknown reasons, my browser open test pages of my remote server very slowly. So I am thinking if I can reconnect to the browser after quitting the script but don't execute webdriver.quit()
this will leave the browser opened. It is probably kind of HOOK or webdriver handle.
I have looked up the selenium API doc but didn't find any function.
I'm using Chrome 62, x64, windows 7, selenium 3.8.0.
I'll be very appreciated whether the question can be solved or not.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
是,这实际上很容易做到。
硒< - > WebDriver会话由连接URL和Session_ID表示,您只需重新连接与现有的连接。
免责声明 - 该方法是使用硒内部属性(某种程度上的“私人”),这可能会改变新版本;您最好不要将其用于生产代码;最好不要与远程SE(您的轮毂或Browserstack/Sauce Labs这样的提供商)使用,因为在末尾解释了警告/资源引流。
启动WebDriver实例时,您需要获取之前提到的属性;示例:
随着现在已知的这两个属性,另一个实例可以连接。 “技巧”是启动
远程
驱动程序,并提供上面的_url
- 因此,它将连接到运行的硒过程:当运行时,您会看到打开一个新的浏览器窗口。
这是因为在启动驱动程序后,Selenium库会自动为其启动一个新的会话 - 现在您有1个带有2个会话的Web驱动程序进程(浏览器实例)。
如果导航到URL,您会发现它是在新的浏览器实例上执行的,而不是上一个开始剩下的一个 - 这不是所需的行为。
在这一点上,需要完成两件事 - a)关闭当前的SE会话(“新的”),b)将此实例切换到上一个会话:
这就是您现在已连接到以前/已经存在的会话,及其所有属性(cookie,localstorage等)。
顺便说一句,您不必在启动新远程驱动程序时提供
desired_capabilities
- 这些远程驱动程序是从您接管的现有会话中存储和继承的。警告 - 运行SE过程会导致系统中的某些资源引流。
每当一个启动然后不关闭时 - 就像在代码的第一部分一样 - 它将一直留在那里,直到您手动杀死它。我的意思是 - 例如,在Windows中 - 您会看到一个“ chromedriver.exe”过程,一旦完成后,您就必须手动终止。它不能由已连接到远程硒过程的驾驶员关闭。
原因 - 每当您启动本地浏览器实例,然后调用其
quit()
方法,它中有2个部分 - 第一个是从Selenium实例中删除会话(在那里的第二个代码),另一个是停止本地服务(Chrome/Geckodriver) - 通常可以正常工作。问题是,对于远程会话,第二部分丢失了 - 您的本地计算机无法控制远程过程,这就是该遥控器的工作。因此,第二部分实际上是
PASS
Python语句 - no -op。如果您在远程集线器上启动了太多的硒服务,并且对此没有控制 - 这将导致该服务器的资源引流。像Browserstack这样的云提供商对此采取了措施 - 他们正在关闭服务,而过去60年代没有活动等,这是您不想做的。
至于本地SE服务 - 只是不要忘记偶尔从您忘记的孤儿硒驱动器中清理操作系统:)
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:
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: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:
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 :)
no ,退出脚本后,您无法重新连接到上一个 Web浏览会话。即使您能够提取
会话ID
,cookies
和其他会话属性,将这些属性作为 hook 传递到 Web Driver 。一种清洁的方法是调用
webdriver.quit()
,然后跨越新的浏览上下文。深度潜水
已经进行了许多讨论,并尝试将 web driver 重新连接到现有的运行浏览上下文。在讨论中允许webdriver连接到跑步的浏览器 Simon Stewart [Creator Webdriver]清楚地提到了:
tl; dr
webdriver.firefox.useexisting未实现
No, you can't reconnect to the previous Web Browsing Session after you quit the script. Even if you are able to extract the
Session ID
,Cookies
and other session attributes from the previous Browsing Context still you won't be able to pass those attributes as a HOOK to the WebDriver.A cleaner way would be to call
webdriver.quit()
and then span a new Browsing Context.Deep Dive
There had been a lot of discussions and attempts around to reconnect WebDriver to an existing running Browsing Context. In the discussion Allow webdriver to attach to a running browser Simon Stewart [Creator WebDriver] clearly mentioned:
tl; dr
webdriver.firefox.useExisting not implemented
对于Chromium,您可以获取浏览器的运行过程列表,请检查此过程中的命令行,然后搜索“ - remote-debugging-port =”提取portnumber并将其用于WebDriver的初始化。
将驱动程序设置为
无需任何其他选项设置的启动
,即VB.NET中对我有用的零件,但我认为也可以用其他语言翻译和使用它。
并尽其所用。您可以在页面打开的点上继续,或者创建一个知道的窗口并关闭旧的窗口,如果您喜欢一种新的开始,但是先前的Coockies和Cache。
您可能想杀死旧的“ webdriver.exe”进程,因为在每个重新连接中,它都会产生一个知识。
这样您就可以模拟真实的用户行为,因为普通用户不会始终私有浏览。他们回到您的网站上,上面有旧的cookie和Cache中的数据。因此,您可以优化网站以正确处理旧的缓存资产,并找到用户不需要强制重新加载网站或每次更新时都必须清洁缓存的方法。
for Chromium you can get a list of running processes of the browser, inspect the commandline from this process and search for "--remote-debugging-port=" extract that portnumber and use it in initialisation of the webdriver.
set the DriverOptions to
without any other options set initiate
that the part in VB.net that works for me, but i think it is possbible to translate and use it in other languages too.
and use the driver as usally. you can continue at the point where the page was left open, or create a knew window and close the old one if you like a kind of fresh start, but with the previous coockies and cache.
you may want to kill old "webdriver.exe" processes, because on every reconnet it will spawn a knew one.
in this way you simulate real user behavior because normal users don't browse always in private. they came back to your site with old cookies and data in cache. so you can optimize your site to deal properly with old cached assets and find ways where the user doesn't need to force reload the site or have to clean the cache every time the site gets an update.
我也不知道这是不可能的,所以我也做到了。
这是我的Java版本。
多亏了其他人,他们的回答是有可能的。如果可以在Python中进行,那么肯定可以在Java中进行。
I also didn't know it was impossible, so I did it too.
Here is my Java version.
Thanks to other people showing it was possible in their answers. If it's possible in Python, it must be possible in Java for sure.
好的,在混合了这里共享的各种解决方案并进行调整之后,我现在可以按照以下操作。如果存在,脚本将使用以前左打开的Chrome窗口 - 如果需要,远程连接可以完美地杀死浏览器,并且代码功能正常。
而无需将其写入hte上一次会话时将其写入文件...
我希望有一种方法可以自动化session_id和url以进行上一次活动会话,
OK after mixing various solutions shared on here and tweaking I have this working now as below. Script will use previously left open chrome window if present - the remote connection is perfectly able to kill the browser if needed and code functions just fine.
I would love a way to automate the getting of session_id and url for previous active session without having to write them out to a file during hte previous session for pick up...
This is my first post on here so apologies for breaking any norms
这是2023年对我有用的东西。python代码:
我在 this 重复的线程和类定义在Stackoverflow上的另一个线程上,我现在找不到。取消注释前5行并评论最后2行。然后进行相反的操作,然后添加您的 url 和 sessionId 。
编辑:仅当您在单独的终端中运行第一部分时才有效。您可以在另一个终端中运行第二部分,并根据需要将其重复多次。
Here is something that works for me in 2023. Python code:
I found a partial answer on this duplicate thread and the class definition on another thread on stackoverflow which I cannot find right now. Uncomment the first 5 lines and comment the last 2. Then do the opposite and add your URL and sessionID.
EDIT: It only works if you run the first part in a separate terminal. You can run the second part in another terminal and reuse it as many times as you want.
多亏了原始海报开始此主题,这对我来说是非常有用的讨论,可以为我的Python技能提供特定的用例。
我尝试了 Todor's 上面发布的方法,并且在以下设置方面未成功
OS = Mac OS Ventura; python = 3.10.4; se = 4.12.0
但是,我从 shabad 这很有帮助。
这是我针对上述设置的代码,这些代码更优雅地
苹果脚本,以启动具有特定配置文件python代码的新会话
以附加到本会话
Thanks to the original poster to start this topic, and this has been very helpful discussion for me to pick up on my Python skills for a specific use-case.
I tried Todor's method posted above and was not successful with the following setup
OS = Mac OS Ventura; Python = 3.10.4; SE = 4.12.0
However, I found this method from Shabad that was helpful.
Here is my code for the above settings that worked more elegantly
Apple Script to launch a new session with a specific profile
Python code to attach to this session
大约一个月前(2024年10月上旬),我找到了这个线程,并根据Stiky的代码建立了自己的POC,只是为了确认其有效。不幸的是,从那以后,破坏该方法的Selenium Python代码库发生了更改。
将此功能作为官方功能真是太好了,但是我可能被迫将我的特定项目求助,以保持长期寿命的“所有者”流程将网络驱动器持续使用,但我需要它多久。
About a month ago (early Oct 2024) I found this thread and built my own POC based on stiky's code just to confirm it worked. Unfortunately, since then there have been changes to the Selenium Python codebase that break that method.
It would be nice to have this capability as an official feature, but I may be forced to rearchitect my particular project around keeping a long-lived "owner" process holding the webdriver for however long I need it.
不介绍为什么您认为离开开放式浏览器窗口会解决慢速的问题,您真的不需要手柄来做到这一点。如您所提到的那样,只需继续运行测试而不关闭会话或不调用
driver.quit()
而无需调用即可。这里的问题是自己的跑步者的框架吗?喜欢黄瓜吗?无论如何,您必须具有一些“设置”和“清理”代码。因此,您需要做的是在“清理”阶段确保浏览器恢复其初始状态。这意味着:
Without getting into why do you think that leaving an open browser windows will solve the problem of being slow, you don't really need a handle to do that. Just keep running the tests without closing the session or, in other words, without calling
driver.quit()
as you have mentioned yourself. The question here though framework that comes with its own runner? Like Cucumber?In any case, you must have some "setup" and "cleanup" code. So what you need to do is to ensure during the "cleanup" phase that the browser is back to its initial state. That means: