WebDriverBiDiMode
BiDi セッション/ブラウザ相当です。Playwright の Browser に対応します。
Dim mode As WebDriverBiDiMode
Set mode = ShSetting01_StartBrowser.StartBiDiMode
Dim tab As WebDriverBiDiContext
Set tab = mode.getTab(setMain:=True)
tab.navigate "https://example.com"
mode.CloseBrowserタブからすぐ始めたい場合は設定シートの StartBiDiModeContext → WebDriverBiDiContext が簡単です。
起動・再接続・終了
OpenBrowser
Public Function OpenBrowser(caps As BrowserCapabilities) As Stringブラウザを WebDriver BiDi として起動し、session.new まで行います。日常利用では設定シート経由を推奨します(内部でこのメソッドを呼んでいます)。戻り値は初期接続先の URL 文字列です。
| 引数 | 意味 |
|---|---|
caps | 起動時のオプションをまとめた BrowserCapabilities |
ユーザーデータフォルダ名・ブラウザの種類・追加の起動引数・初期 URL などは、すべて caps で渡します。session.new に渡す sessionCapabilitiesRequest は、caps.Set_BiDiSessionCapabilitiesRequest で設定します。
Dim caps As New Dictionary
' ... capabilities を組み立て ...
Set BrowserCapabilities.Set_BiDiSessionCapabilitiesRequest = caps
Dim mode As WebDriverBiDiMode
Set mode = New WebDriverBiDiMode
mode.OpenBrowser BrowserCapabilitiessessionCapabilitiesRequest の詳細は はじめに。
reattach
Public Sub reattach(reattachInfo As ReattachOptions)既存の BiDi 接続へ再接続します。通信経路(Pipe / Port)は、ReattachOptions で指定します。
| 引数 | 意味 |
|---|---|
reattachInfo | 再接続時のオプションをまとめた ReattachOptions。制御経路の指定が必須。BiDi-CDP Mapper が再始動されたときに使う Set_BiDiSessionCapabilitiesRequest なども、ここで設定します |
戻り値はありません。CDPBrowser.reattach と同じく、再接続に失敗した場合は VBA エラーで停止します(エラーで止めたくない場合は呼び出し側で On Error を使ってください)。
' Pipe 版
ReattachOptions.Set_PipeMode = ShSetting01_StartBrowser.CurrentUserName
Dim mode As New WebDriverBiDiMode
mode.reattach ReattachOptions
' Port(WebSocket)版
Dim ws As CDPCoreViaWebSocket
Set ws = New CDPCoreViaWebSocket
' ... 接続済み ws を用意する ...
ReattachOptions.Set_WebSocketMode(ws) = UserName
Set mode = New WebDriverBiDiMode
mode.reattach ReattachOptions注意
- パイプが生きていない場合は、このメソッドから再開できません。Part1 からやり直してください
- BiDi-CDP Mapper が再始動された場合のほか、デバッグ中の BiDi セッションが無い(
session.statusのreadyがTrue)場合にも、session.newを行います。このときSet_BiDiSessionCapabilitiesRequestが適用されます ReattachOptionsは使い切りです。reattachを呼ぶたびに、制御経路を指定し直してください
詳細は 再接続 / WebSocket モード。
CloseBrowser
Public Sub CloseBrowser()browser.close を送ってブラウザを終了し、Excel テーブル上のメインタブ情報と接続ハンドルを解放します。
mode.CloseBrowsersessionEnd
Public Function sessionEnd() As BiDiCDPJsonBiDi コマンド session.end を実行し、ブラウザは閉じずに、BiDi による制御(デバッグ)だけを終わらせます。ブラウザを開いたまま後始末をしたいときに使います。WebSocket 経由の場合は、WebSocket の切断も同時に起こります。
mode.sessionEnd ' ブラウザは開いたまま、BiDi 制御だけ終了注意
通信の切断が同時に起こるため、エラーは無視する動作になっています(StopBiDiError:=False 相当)。ブラウザごと終了したい場合は CloseBrowser を使ってください。
タブ
newTab
Public Function newTab( _
Optional newWindow As Boolean, _
Optional isBackground As Boolean, _
Optional setMain As Boolean _
) As WebDriverBiDiContext新規タブ(またはウィンドウ)を開き WebDriverBiDiContext を返します。BiDi では作成時に URL 直指定はできません。開いたあと navigate してください。
| 引数 | 意味 |
|---|---|
newWindow | True で新しいウィンドウ、False(既定)で既存ウィンドウにタブ |
isBackground | True でバックグラウンド(非アクティブ)で開く |
setMain | True で Excel に context を記録(reattach 用) |
Dim tab As WebDriverBiDiContext
Set tab = mode.newTab(setMain:=True)
tab.navigate "https://example.com"
Set tab = mode.newTab(newWindow:=True, isBackground:=True)関連: マルチタブ
getTab
Public Function getTab( _
Optional Url As String, _
Optional maxDepth As Long, _
Optional setMain As Boolean, _
Optional doRetrySecond As Double _
) As WebDriverBiDiContext既に開いている browsing context を URL 部分一致などで探し、WebDriverBiDiContext として返します。見つからない場合は Nothing になり得ます。
| 引数 | 意味 |
|---|---|
Url | URL 部分一致。省略時は見つかった先頭(未接続相当)の context |
maxDepth | browsingContext.getTree の深さ。0(既定)ならトップレベルのみ(iframe 除外) |
setMain | True で Excel に context を記録 |
doRetrySecond | 指定秒以内に見つかるまでリトライ。0(既定)なら 1 回のみ |
' 直近のタブへ
Dim tab As WebDriverBiDiContext
Set tab = mode.getTab(setMain:=True)
' URL 部分一致
Set tab = mode.getTab(Url:="example.com")
' iframe まで含めて最大 5 秒リトライ
Set tab = mode.getTab(Url:="https://challenges.cloudflare.com/", maxDepth:=2, doRetrySecond:=5)注意
WebDriver BiDi ではタブ名(タイトル)での検索はできません。URL で探してください。
serializeMainTab
Public Property Get serializeMainTab() As String
Public Property Let serializeMainTab(contextId As String)Excel テーブルにメイン browsing context id を記録/読み取ります。newTab / getTab の setMain:=True が内部でこれを使います。
Debug.Print mode.serializeMainTab
mode.serializeMainTab = tab.contextプロトコル・イベント
ExecuteBiDi / ExecuteBiDiAsync
Public Function ExecuteBiDi(methodName As String, _
Optional params As Dictionary, _
Optional StopBiDiError As Boolean = True) As BiDiCDPJson
Public Function ExecuteBiDiAsync(methodName As String, _
Optional params As Dictionary, _
Optional StopError As Boolean = True) As Longセッション/ブラウザ向け BiDi コマンドです。結果を待つか(ExecuteBiDi)、待たずに後で確認するか(ExecuteBiDiAsync)の 2 種類があります。
| 引数 | 意味 |
|---|---|
methodName | メソッド名(例: "browsingContext.navigate" / "browser.close") |
params | params の Dictionary。省略時は空の {} |
StopBiDiError / StopError | 失敗時に停止するか。既定は True |
ExecuteBiDiAsync はコマンド実行時の id(Long)のみを返し、結果は待ちません。回収は TakeResultBiDi で行います。
Dim params As New Dictionary
params.Add "url", "https://example.com"
params.Add "wait", "complete"
' ※ Context 側の ExecuteBiDi は context を自動付与
Dim result As BiDiCDPJson
Set result = mode.ExecuteBiDi("browser.getUserContexts", New Dictionary)詳細は 低レイヤー BiDi / CDP コマンドについて。
SetBiDiPlusChannel
Public Property Let SetBiDiPlusChannel(ChannelStr As String)BiDi+ 独自の拡張フィールドである goog:channel(v3.1.1〜)を設定します。以降に送信する全 BiDi コマンドへ、指定した文字列タグが自動付与されます。CDP そのものの動作には影響せず、ログを見返す際の目印として使えます。
| 引数 | 意味 |
|---|---|
ChannelStr | 付与する goog:channel の値。空文字(または vbNullString)でフィールド自体を外す |
mode.SetBiDiPlusChannel = "MyTask" ' 以降のBiDiコマンドすべてに `"goog:channel":"MyTask"` が付与されるWebDriverBiDiContext からは ThisWebDriverBiDiMode.SetBiDiPlusChannel 経由で同じ値を設定します。詳細は 低レイヤー BiDi / CDP コマンドについて(「goog:channelフィールド」節)。
TakeEvents
Public Sub TakeEvents(Optional StopApiError As Boolean = True, Optional destruction As Boolean)非同期応答/イベントの吸い上げです(almighty:受信 → 解析 → 蓄積中の全メッセージについて RaiseEvent までを一括で行う)。TakeResultBiDi の前に呼び出す必要があります。
| 引数 | 意味 |
|---|---|
StopApiError | Pipe/WebSocket 障害時に停止するか。既定は True |
destruction | True でストリームに蓄積せず破棄するだけ(RaiseEventは起きない) |
mode.TakeEventsTakeEvent / NewResBiDi / AnalyzeBiDi
Public Sub AnalyzeBiDi(Optional StopApiError As Boolean = True, Optional destruction As Boolean)
Property Get NewResBiDi() As Boolean
Public Sub TakeEvent()TakeEvents を分解した manual な低レベル部品です。特定イベント検出時に即座に割り込んで残りのイベント処理を止めたい、といった上級者向け用途で使います。
| メンバー | 役割 |
|---|---|
AnalyzeBiDi | Pipe/WebSocket からバイト配列を受け取り、テキストへ変換して 1 件分取り出せる状態にする |
NewResBiDi | AnalyzeBiDi 後、取り出せる新規メッセージがあるか(Get 専用) |
TakeEvent | 蓄積済みメッセージを 1 件だけ取り出し RaiseEvent する |
TakeResultBiDi
Property Get TakeResultBiDi(commandID As Long) As StringExecuteBiDiAsync が返した id をキーに、蓄積された実行結果(JSON 文字列)を取り出します。取り出し後は Dictionary から削除されます。結果がまだ無い場合は空文字を返します。
Dim cmdId As Long
cmdId = mode.ExecuteBiDiAsync("browsingContext.navigate", params)
Do
mode.TakeEvents
Dim raw As String
raw = mode.TakeResultBiDi(cmdId)
If LenB(raw) Then Exit Do
DoEvents
LoopTIP
コマンド回数が20億を超えると、オーバーフロー対策により蓄積中の結果履歴が すべて削除されます。未回収の ExecuteBiDiAsync 結果も消える点に注意してください。
LastBiDiJsonError
Property Get LastBiDiJsonError() As DictionaryExecuteBiDi 経由で記録された、最後の BiDi コマンドエラーです。Err.LastDllError と同様、成功しても消えません。
StopBiDiError:=False のとき、戻り値が Nothing なら本プロパティで詳細を確認します。
Dim result As BiDiCDPJson
Set result = mode.ExecuteBiDi("webExtension.install", params, False)
If result Is Nothing Then
Debug.Print mode.LastBiDiJsonError("message")
' 必要なら mode.LastBiDiJsonError.RemoveAll でクリア可
End IfBiDiEvents
Property Get BiDiEvents() As Dictionary
Property Set BiDiEvents(ObjDic As Dictionary)標準モジュール上で BiDi の非同期イベントを受け取るための蓄積口です(CDP の BrowserEvents 相当)。
| 操作 | 意味 |
|---|---|
Set … = New Dictionary | 記録開始 |
Set … = Nothing | 記録停止 |
| 退避した Dictionary を再代入 | セーブ/再開 |
Set mode.BiDiEvents = New Dictionary
' ... SubscribeBiDiEvent 後に操作 ...
mode.TakeEvents
' mode.BiDiEvents を参照
Set mode.BiDiEvents = NothingSubscribeBiDiEvent
Property Set SubscribeBiDiEvent(Optional subscribe As Boolean = True, Optional params As Dictionary, events As Collection)
Property Let SubscribeBiDiEvent(Optional subscribe As Boolean = True, Optional params As Dictionary, events)session.subscribe / session.unsubscribe を実行します。どのイベントを購読中かの管理は呼び出し側で行います。
v3.2.0でのリネーム
以前は sessionSubscribe という名称でした。挙動に変更はありません。
| 引数 | 意味 |
|---|---|
subscribe | True(既定)で購読、False で購読解除 |
params | WebDriverBiDiContext からタブ単位で呼ぶ際に内部で使用。直接指定は不要 |
events | SET: イベント名の Collection/LET: 1次元配列または文字列1件(例: "network.beforeRequestSent") |
' Collection版(SET)
Dim events As New Collection
events.Add "network.beforeRequestSent"
events.Add "network.responseCompleted"
events.Add "log.entryAdded"
Set mode.SubscribeBiDiEvent = events
' 配列版(LET、v3.1.1.1〜)
mode.SubscribeBiDiEvent = Array("network.beforeRequestSent", "network.responseCompleted", "log.entryAdded")
' 解除
Set mode.SubscribeBiDiEvent(False) = eventsparams を省略した場合はブラウザ全体(全タブ共通)での購読になります。タブ単位で購読したい場合は WebDriverBiDiContext.SubscribeBiDiEvent(v3.1.1.1〜)を使ってください。
手順・セーブ/再開は イベント購読 を参照してください。
タイムアウト
TimeOutSecond
Property Let TimeOutSecond(TimeSec As Double)
Property Get TimeOutSecond() As DoubleBiDi コマンド結果待ちの上限です。デフォルトは 30 秒です。
mode.TimeOutSecond = 60
Debug.Print mode.TimeOutSecond ' 60(v3.2.0〜、読み返し可能に)v3.2.0での変更
以前は LET 専用(書き込みのみ)で設定中の値を読み返せませんでしたが、v3.2.0 で Property Get が追加され、現在値を読み返せるようになりました。
タブ側(WebDriverBiDiContext)からは ThisWebDriverBiDiMode.TimeOutSecond で同じ値を触れます。
詳細は タイムアウト設定方法について。
ユーティリティ
sleep
Public Sub sleep(Optional seconds As Double = 0.5)指定秒待ちます。既定は 0.5 秒です。
mode.sleep 1TimerCounter
Public Function TimerCounter() As Double単調増加の経過ミリ秒です。VBA の Timer 関数の代わりに、自前ループのタイムアウト判定へ使えます。
Dim startMs As Double
startMs = mode.TimerCounter
Do
mode.TakeEvents
If mode.TimerCounter - startMs > 5000 Then Exit Do
DoEvents
Loop詳細は タイムアウト設定方法について。
printMsg
Public Sub printMsg(LogLevel_ As LogLevelName, strMsg As String, From As String, _
Optional isHeader As Boolean = False, Optional doRaiseError As Boolean)デバッグ/ログ出力です。通常はフレームワーク内部から呼ばれます。
高度な/内部寄りの API
日常利用では意識不要です。拡張やフレームワーク連携向けです。
RunCollect_InfoList
Property Set RunCollect_InfoList(ArgCollect As Collection)browsingContext.contextCreated で得た InfoList を、渡した Collection に蓄積します。Nothing で収集停止(用が済んだら必ず解放)。
Dim info As New Collection
Set mode.RunCollect_InfoList = info
' ... タブ作成などの操作 ...
Set mode.RunCollect_InfoList = NothingEnableDiscoverContexts
Property Let EnableDiscoverContexts(Flag As Boolean)browsingContext.contextCreated / contextDestroyed の購読と、確保中 WebDriverBiDiContext のカウントに使います。Context の生成/破棄時に呼ばれる想定です。
v3.2.0での変更
navigationStarted / domContentLoaded / load の購読も同時に行うようになりました(WaitEvents によるイベント駆動の読み込み待機のため)。
ExEventCore
Property Get ExEventCore() As WebDriverBiDiCore自作の拡張クラスで、BiDi の非同期イベント(RaiseEvent)を WithEvents で受け取るときに使う、上級者向けの通信コア(WebDriverBiDiCore)への参照です。自作の拡張クラス以外では使いません。

