Py学习  »  Todor Minakov  »  全部回复
回复总数  1
6 年前
回复了 Todor Minakov 创建的主题 » 在SeleniumWeb驱动程序python中打开相同的会话[重复]

是的 这其实很容易做到。

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服务,不要忘记偶尔清理一下你忘记的孤立硒驱动程序的操作系统。