Tips というより開発時に調べた Script 等を忘れないように書き留めた覚え書きです。
最近はここに書き留めておくことも忘れている始末で、我ながら情けなく思う今日この頃です。
ということで、不定期更新というか最近更新していませんが、JavaScript や VBScript などを紹介していきますのでご参考になれば幸いです。

WebView2 コントロールを使ってみる2 / 操作方法

2022年6月16日ついに Internet Explorer のサポートが終了しましたね
InternetExplorer(Tridentエンジン)がベースのWebBrowserコントロールは早くても2029年までは使用できますのでしばらくは問題ないと思いますが、最近のWebページではデザインが崩れたり、JavaScriptがエラーになることがあるのが困りものですよね

そこで遅まきながら Edgeブラウザ(Chromium)がベースの WebView2 コントロールを使ってみた時の備忘録です

記載日:2022年 7月18日

WebView2 の初期化

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

Webページの表示

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

Webページの操作

WebBrowser コントロールでは getElementById メソッドや document プロパティ等で直接DOM操作できましたが、WebView2コントロールにはありません
WebView2 コントロールでは、ExecuteScriptAsync メソッドを使用して、JavaScript のコードを実行してWebページを操作します

HTMLの取得

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! 検索

Yahoo!検索ページの検索フォーム部分のHTMLは下記になっています

Yahoo!検索

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

DOM等の値を取得する

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

ページの先頭へ