見出し画像

[SeleniumVBA]非同期処理(Ajax with jQuery)の完了を待機する一案

はじめに

インストール不要なSeleniumVBAでは、ExcelVBAを使ってやりたいことがほぼできる機能が備わっています。

「ほぼ」と書いたのは、SeleniumVBAだけの問題ではなくSelenium全体の問題なのですが、非同期処理への対応が難しいことが挙げられるのではないかと思っています。

困ったこと

現在(2024年10月現在)でも、jQueryを用いてAjax(非同期処理)を利用しているWEBサイトはまだまだ多いと思います。

そういったWEBサイトでAjaxが仕込まれているセレクトボックスの選択や、ボタンをクリックしたとき、Ajaxの処理完了まで待ってから次の処理を行わないと、期待した結果にならないことがよくあります。

期待した結果にならなくても、エラーにならず、何事もないように振る舞うため、待機処理として「On Error GoTo~」も使えません。

最初は訳も分からないままwaitの固定秒数をかませて対応していたので、根本的解決になっていませんでした。

Ajaxの処理完了後、新たな要素が表示されることが明確な場合は、既存の機能(IsPresent)を使用して要素が表示されるまで待つのがベストだと思います。

しかし、既存要素の値の更新の場合は使えないので厄介です。また、値の更新がない場合も想定すると、処理が完了したかどうかをどのように判別したらよいか分からず、袋小路に入っていました。

対応策

幸運なことにjQueryにおいては、以下の4行の追加でAjaxの処理が完了するまで待つことができるそうです(おそらく)。このコードでは50ミリ秒毎に待ってから再度処理完了の有無を確認しています。

Do Until driver.ExecuteScript("return jQuery.active == 0") And _
  driver.ExecuteScript("return document.readyState== 'complete'")
    driver.Wait 50
Loop

もちろんWEBサイトがjQueryを使用していることが前提のコードですので、jQuery未使用の場合はエラーになって止まります。

Ajaxが使用されているかどうかは、以下のようにHTML中に記述がある、もしくはリンクされたJSファイル中に「ajax」があるどうかで確認しています。

’【Ajax使用有無の判別】

’JavaScript
$.ajax({
 url: ‘××××’ //URLまたはディレクトリを記載
 })
 .done(function(data){ // 通信が成功したときの処理 
 })
 .fail(function(data){ // 通信が失敗したときの処理
 })
 .always(function(data){ //通信の成否にかかわらず実行する処理 
});

'JSファイルのリンク
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.0/jquery.min.js"></script>

またjQueryを使用しないで非同期処理をしているWEBサイトへの対応は分かりません。もし分かる方がいらっしゃいましたら教えてください。

この記事が気に入ったらサポートをしてみませんか?