いくつかの未知の理由により、私のブラウザは私のリモートサーバーのテストページを非常にゆっくりと開きます。スクリプトを終了した後にブラウザに再接続できるかどうかを考えていますが、webdriver.quit()
を実行しないと、ブラウザが開いたままになります。おそらく、フックまたはWebdriverハンドルの一種です。 Selenium APIドキュメントを調べましたが、機能が見つかりませんでした。私はChrome 62、x64、windows 7、Selenium 3.8.0を使用しています。質問が解決できるかどうかは非常にありがたいです。
No、スクリプトを終了した後、以前の_Web Browser
_セッションに再接続できません。 _Session ID
_、Cookies
、および以前の_Browsing Session
_から他のセッション属性を抽出できたとしてもそれでも、これらの属性をフックとしてWebDriver
に渡すことはできません。
よりクリーンな方法はwebdriver.quit()
を呼び出してから、新しい_Browsing Session
_をスパンすることです。
以前は、いくつかの議論があり、既存の実行中のブラウジングセッションにWebDriver
を再接続する試みがありました。これらのQAでディスカッションを見つけることができます。
Selenium <-> webdriverセッションは接続URLとsession_idで表され、既存のセッションに再接続するだけです。
免責事項-このアプローチはSeleniumの内部プロパティ(ある意味では「プライベート」)を使用しており、新しいリリースでは変更される可能性があります。運用コードには使用しない方がよいでしょう。最後に説明されている警告/リソースの排出のため、リモート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}')
_
これら2つのプロパティがわかったので、別のインスタンスが接続できます。 「トリック」は、Remote
ドライバーを開始し、上記の__url
_を提供することです。したがって、実行中のSeleniumプロセスに接続します。
_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ライブラリが自動的に新しいセッションを開始するためです。これで、2つのセッション(ブラウザインスタンス)を持つ1つのWebdriverプロセスができました。
URLに移動すると、その新しいブラウザーインスタンスで実行されていることがわかります。前回の起動で残ったインスタンスではなく、望ましい動作ではありません。
この時点で、2つのことを行う必要があります。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()
メソッドを呼び出すと、2つの部分があります。最初の部分は、Seleniumインスタンスからセッションを削除することです( 2番目のコード部分で行われます)、もう1つはローカルサービス(chrome/geckodriver)を停止することです。通常は問題なく動作します。
問題は、リモートセッションの場合、2番目の要素が欠落していることです。ローカルマシンはリモートプロセスを制御できません。これが、そのリモートのハブの働きです。つまり、2番目の部分は文字どおりpass
pythonステートメント-何もしないことです。
リモートハブで開始するSeleniumサービスが多すぎて、それを制御できない場合は、そのサーバーからのリソースの消耗につながります。 BrowserStackのようなクラウドプロバイダーはこれに対して対策を講じます-彼らは過去60秒間など活動のないサービスを閉鎖しています-これはあなたがしたくないことです。
ローカルSEサービスについては、忘れていた孤立したSeleniumドライバからOSを時々クリーンアップすることを忘れないでください:)
なぜブラウザウィンドウを開いたままにしておくと遅くなるという問題を解決できると思いますか?セッションを閉じずに、つまり、あなたが言ったようにdriver.quit()
を呼び出さずにテストを実行し続けるだけです。ここでの質問は、独自のランナーに付属するフレームワークですか?きゅうりが好き?
いずれの場合も、「セットアップ」および「クリーンアップ」コードが必要です。したがって、「クリーンアップ」フェーズ中にブラウザが初期状態に戻っていることを確認する必要があります。つまり: