最近はここに書き留めておくことも忘れている始末で、我ながら情けなく思う今日この頃です。
ということで、不定期更新というか最近更新していませんが、JavaScript や VBScript などを紹介していきますのでご参考になれば幸いです。
2022年6月16日ついに Internet Explorer のサポートが終了しましたね
InternetExplorer(Tridentエンジン)がベースのWebBrowserコントロールは早くても2029年までは使用できますのでしばらくは問題ないと思いますが、最近のWebページではデザインが崩れたり、JavaScriptがエラーになることがあるのが困りものですよね
そこで遅まきながら Edgeブラウザ(Chromium)がベースの WebView2 コントロールを使ってみた時の備忘録です
記載日:2022年 7月18日
WebView2 を利用するには初期化する必要があります
また、初期化の完了を待たないで webView2.CoreWebView2 にアクセスすると NullReferenceException が発生する場合があります
下記の例ではフォームロード時に初期化しています
初期化には時間がかかりますので、EnsureCoreWebView2Async メソッドで初期化が完了するのを待っています
Imports Microsoft.Web.WebView2.Core Public Class Form1 Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load InitializeAsync() End Sub Private Async Sub InitializeAsync() Await WebView21.EnsureCoreWebView2Async(Nothing) End Sub End Class
WebView2 コントロールを使ってWebページを表示するには webView2.CoreWebView2.Navigate メソッドを使用します
WebView21.CoreWebView2.Navigate([開きたいページのURL])
WebBrowser コントロール同様、WebView2 コントロールにおいてもページの読み込み・表示が終わるまでの待機する処理が必要になります
あまり良い処理ではないかもしれませんが、参考までに一例を紹介します
Imports Microsoft.Web.WebView2.Core Public Class Form1 Private mstrStatusCode As String = "" Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load InitializeAsync() End Sub Private Async Sub InitializeAsync() Await WebView21.EnsureCoreWebView2Async(Nothing) End Sub Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click mstrStatusCode = "" Dim time As Integer = 0 'サイトの表示を開始 WebView21.CoreWebView2.Navigate("https://www.kanaya440.com") '読み込み完了まで待機 Do While mstrStatusCode = "" If time > 60000 Then '1分経過したらキャンセル MsgBox("サイトからの応答がありませんでした", MsgBoxStyle.Information Or MsgBoxStyle.OkOnly) Exit Sub End If Threading.Thread.Sleep(1) time += 1 Application.DoEvents() Loop '読み込み結果(ステーテスコード)をイミディエイトウインドウに表示 Debug.Print(mstrStatusCode) End Sub Private Sub WebView21_NavigationCompleted(sender As Object, e As CoreWebView2NavigationCompletedEventArgs) Handles WebView21.NavigationCompleted '読み込み結果(ステーテスコード)を変数にセット mstrStatusCode = e.HttpStatusCode End Sub End Class
WebBrowser コントロールでは getElementById メソッドや document プロパティ等で直接DOM操作できましたが、WebView2コントロールにはありません
WebView2 コントロールでは、ExecuteScriptAsync メソッドを使用して、JavaScript のコードを実行してWebページを操作します
2行目:ExecuteScriptAsyncメソッドの戻り値として取得できます
3行目:Regex.Unescape で文字列の中にエスケープされた文字がある場合は、そのエスケープを解除しています
4、5行目:取得した文字列は「"」で括ってあるので、前後の「"」を削除しています
Private Async Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click Dim html = Await WebView21.ExecuteScriptAsync("document.documentElement.outerHTML") html = Regex.Unescape(html) html = html.Remove(0, 1) html = html.Remove(html.Length - 1, 1) Debug.Print(html) End Sub
Yahoo!検索ページの検索フォーム部分のHTMLは下記になっています
3行目:検索窓の input タグが「name="p"」なので、「getElementsByName('p')」に検索文字列を代入しています
5行目:form タグが「name="sf1"」なので、「forms['sf1'].submit()」でフォームを Submit しています
Private Async Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click '検索欄に文字を設定する WebView21.ExecuteScriptAsync($"document.getElementsByName('p')[0].value = 'ホームページの素';") 'submitして検索を実行 WebView21.ExecuteScriptAsync($"document.forms['sf1'].submit();") End Sub
1行で書くこともできます
Private Async Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click WebView21.ExecuteScriptAsync($"document.getElementsByName('p')[0].value = 'ホームページの素'; document.forms['sf1'].submit();") End Sub
ExecuteScriptAsyncメソッドの戻り値として取得できます
下記は Yahoo! 検索ページで検索窓に入力された文字列を取得する例です
Private Async Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click Dim result = Await WebView21.ExecuteScriptAsync("document.getElementsByName('p')[0].value") 'Unicodeエスケープ文字を元に戻す result = Regex.Unescape(result) '先頭の1文字を削除 result = result.Remove(0, 1) '末尾の1文字を削除 result = result.Remove(result.Length - 1, 1) Debug.Print(result) End Sub