Seleniumで思わぬエラーが発生したのでメモとして残しておきます。
TL;DR
- UnexpectedAlertPresentExceptionはalertに処理がブロックされているときに起きます。
- seleniumのalertオブジェクトを操作することで解消します。
こんなケースで発生
自分の場合では、JSのコードを実行する処理でこのエラーが発生しました。
driver.get(url) js = "console.log('hello');" driver.execute_script(js) # => UnexpectedAlertPresentException Error!
どういうエラーなのか
ドキュメントを参照すると、下のような記述があります。
Thrown when an unexpected alert is appeared. Usually raised when when an expected modal is blocking webdriver form executing any more commands.
アラートモーダルが何か処理をブロックしている場面で起こるようです。今回だとアラートモーダルがJSの実行がブロックしてしまっていたようです。 ※ ちなみにdocsではwhenが重なってしまっていますが、master repositoryを見に行ったら治ってました。
検証
とても簡単な検証ですが、アラートモーダルがJS実行をブロックする様子を見てみたいと思います。
このように、アラートを消さないとJSは実行されません。
対応
下のようにalertオブジェクトからacceptを呼び出すとアラートモーダルで「OK」を押した動作と同じことになります。
alert = driver.switch_to_alert() alert.accept()
さらに、「もしアラートが出ていたらOKを押してもう一度、本来のJSを実行したい」場合は下記のような実装になると思います。
while True: try: driver.execute_script("console.log('hello');") except UnexpectedAlertPresentException: alert = driver.switch_to_alert() alert.accept() print("Alert accepted") else: break
さいごに
以上、Seleniumネタでした。
関係ないですが、2月3日にPythonもくもく会をつくばで開催します!今回はまだ席が若干余っているのでもし興味ある方は是非ご参加ください〜。