如何使用selenium重新连接webdriver打开的浏览器?

时间:2017-12-18 03:34:41

标签: python-3.x selenium session selenium-webdriver webdriver

由于某些未知原因,我的浏览器打开远程服务器的测试页面非常慢。所以我想我是否可以在退出脚本后重新连接到浏览器但不执行webdriver.quit()这将使浏览器保持打开状态。它可能是一种HOOK或webdriver句柄。 我已经查找了selenium API文档,但没有找到任何函数。 我使用的是Chrome 62,x64,windows 7,selenium 3.8.0。 我将非常感谢这个问题是否可以解决。

3 个答案:

答案 0 :(得分:7)

No, you can't reconnect to the previous Web Browser session after quiting the script. Even if you are able to extract the Session ID, Cookies and other session attributes from the previous Browsing Session 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 Session.

History :

Previously there had been some discussions and attempts to reconnect WebDriver to an existing running browsing session. You can find the discussions in these QA :

答案 1 :(得分:2)

,这实际上很容易做到。

硒<-> Webdriver会话由连接URL和session_id表示,您只需重新连接到现有的会话即可。

免责声明-该方法使用硒的内部属性(某种程度上为“私有”),在新版本中可能会有所变化;您最好不要将其用于生产代码;最好不要将其用于远程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库会自动为其启动一个新会话-现在您有1个具有2个会话(浏览器实例)的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”进程,完成该进程后必须手动终止。它不能由已连接到远程硒进程的驱动程序关闭。
原因-每当您启动本地浏览器实例,然后调用其quit()方法时,它就有2个部分-第一个是从Selenium实例中删除会话(在第二部分代码中做了此操作)在那里),另一种是停止本地服务(chrome / geckodriver)-通常正常。

问题是,对于远程会话,第二部分丢失了-您的本地计算机无法控制远程进程,这就是该远程集线器的工作。因此,第二部分实际上是一个pass python语句-无操作。

如果在远程集线器上启动太多的硒服务,并且无法对其进行控制-则会导致该服务器的资源消耗。像BrowserStack这样的云提供商会采取相应措施-他们正在关闭服务,直到最近60年代都没有活动,等等-这是您不想做的事情。

对于本地SE服务-只是不要忘记偶尔从您遗忘的孤立的硒驱动程序中清理OS:)

答案 2 :(得分:0)

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:

  • Blank page is displayed
  • Cookies are erased for the session