Selenium を使わずに、Actions リクエストを送る

# Actions とは？
Actions コマンドは、WebDriver を使ってブラウザにローレベルアクセスをするための機能です。
オブジェクトをダブルクリックしたいとか、右クリックしたいとか、あるキーを押しながら左クリックしたい、と言う時に使用します。
「ctrl」キーを押しながら、リンクを左クリックして、新しいタブでリンク先ページを開く、という操作を例に、サンプルを提示します。
なお、対象ブラウザは Edge および Chrome です。
## Python & Selenium での、Actions の使い方
```python:Actions の使い方
    driver = webdriver.Edge(r"C:\Users\〇〇\Downloads\edgedriver_win64\msedgedriver.exe")
    # 中略
    actions = ActionChains(driver)  # Actionsオブジェクトの生成
    actions.key_down(Keys.CONTROL)  # ctrlキー押下
    actions.click(driver.find_element_by_xpath('クリックしたいエレメントのXPath')) # 指定エレメント左クリック
    actions.perform() # 定義した Actions の実行
```
上記の通り、とても簡単です。
Selenium 凄い！
## Selenium を使わずに、WebDriver に Actions リクエストを送る(curl編)
```:Actions を送信するための curl コマンド
curl -sSL -X POST -H "Content-Type: application/json" -d "Actions を定義したJSON文字列" localhost:9515/session/取得したセッションID/actions
```
```json:Actions を実行するための JSON 文字列(見易い様に改行を入れて加工)
{"actions":
  [
    {"type":"key",
     "id":"keyboard_1",
     "actions":[{"type":"keyDown","value":"\u0011"}]
    },
    {"type":"pointer",
     "id":"default mouse",
     "parameters":{"pointerType":"mouse"},
     "actions":
       [
         {"duration":100,
          "x":0,
          "y":0,
          "type":"pointerMove",
          "origin":
            {"ELEMENT":"クリックしたいエレメントのID",
             "element-6066-11e4-a52e-4f735466cecf":"クリックしたいエレメントのID"
            }
         },
         {"button":1,"type":"pointerDown"},
         {"button":1,"type":"pointerUp"}
       ]
    },
    {"type":"key",
     "id":"keyboard_2",
     "actions":[{"type":"keyUp","value":"\u0011"}]
    }
  ]
}
```
```:Actions を開放するための curl コマンド
curl -sSL -X DELETE localhost:9515/session/取得したセッションID/actions
```
わ～ぉ・・・、とても長いですね・・・
## Selenium を使わずに、WebDriver に Actions リクエストを送る(VBA編)
上記と同じことを、VBAで表すと、こうなります。
例のごとく、下記のJSONパーサ&コンバータが必要です。

https://github.com/VBA-tools/VBA-JSON

セッションIDの取得方法とか、エレメントIDの取得方法は、下記を参考にしてください。

https://qiita.com/tamarinn_x/items/b5000ede6a355ae9609a

```vb:Actions を実行するためのVBA
Private Const Front_URL As String = "http://localhost:"
Private Const Back_URL As String = "/session"
Private Base_URL As String

'新しいタブでリンク先を開く(引数 SessionID:セッションのID、ElementID:クリックするエレメントのID)
Private Function Open_NewTab(ByRef SessionID As String, ByRef ElementID As String) As Boolean 
    Dim varRet As Variant
    Dim Params As Object
    Dim objKeyUD1(0 To 0) As Object
    Dim objKeyUD2(0 To 0) As Object
    Dim objID(0 To 2) As Object
    Dim objTmp As Object
    Dim objTmp2 As Object
    Dim objMouse(0 To 2) As Object

    Base_URL = Front_URL & "9515" & Back_URL

    Set Params = CreateObject("Scripting.Dictionary")
    Set objID(0) = CreateObject("Scripting.Dictionary")
    Set objID(1) = CreateObject("Scripting.Dictionary")
    Set objID(2) = CreateObject("Scripting.Dictionary")
    Set objKeyUD1(0) = CreateObject("Scripting.Dictionary")
    Set objKeyUD2(0) = CreateObject("Scripting.Dictionary")
    Set objMouse(0) = CreateObject("Scripting.Dictionary")
    Set objMouse(1) = CreateObject("Scripting.Dictionary")
    Set objMouse(2) = CreateObject("Scripting.Dictionary")
    Set objTmp = CreateObject("Scripting.Dictionary")
    Set objTmp2 = CreateObject("Scripting.Dictionary")

    'Ctrl押下
    objKeyUD1(0).Add "type", "keyDown"
    objKeyUD1(0).Add "value", Chr(17)
    objID(0).Add "type", "key"
    objID(0).Add "id", "keyboard_1"
    objID(0).Add "actions", objKeyUD1

    'マウスクリック
    objTmp.Add "pointerType", "mouse"
    objTmp2.Add "ELEMENT", ElementID
    objTmp2.Add "element-6066-11e4-a52e-4f735466cecf", ElementID
    objMouse(0).Add "duration", 100
    objMouse(0).Add "x", 0
    objMouse(0).Add "y", 0
    objMouse(0).Add "type", "pointerMove"
    objMouse(0).Add "origin", objTmp2
    objMouse(1).Add "button", 1
    objMouse(1).Add "type", "pointerDown"
    objMouse(2).Add "button", 1
    objMouse(2).Add "type", "pointerUp"
    objID(1).Add "type", "pointer"
    objID(1).Add "id", "default mouse"
    objID(1).Add "parameters", objTmp
    objID(1).Add "actions", objMouse

    'Ctrlリリース
    objKeyUD2(0).Add "type", "keyUp"
    objKeyUD2(0).Add "value", Chr(17)
    objID(2).Add "type", "key"
    objID(2).Add "id", "keyboard_2"
    objID(2).Add "actions", objKeyUD2

    Params.Add "actions", objID

    varRet = SendRequest("POST", Base_URL & "/" & SessionID & "/actions", Params)("value")
    If IsNull(varRet) Then Open_NewTab = True
    SendRequest "DELETE", Base_URL & "/" & SessionID & "/actions"

End Function

'これは【Excel VBAでSeleniumBasicを使わずにスクレイピングする】から利用させて頂いてます
'リクエストの送信
Private Function SendRequest(method As String, URL As String, Optional data As Object = Nothing) As Object
    ' クライアントの起動
    Dim client As Object
    Set client = CreateObject("MSXML2.ServerXMLHTTP")

    ' メソッドに応じてリクエスト送信
    client.Open method, URL
    If method = "POST" Or method = "PUT" Then
        client.setRequestHeader "Content-Type", "application/json"
        client.send JsonConverter.ConvertToJson(data)
    Else
        client.send
    End If

    ' 送信完了待ち
    Do While client.readyState < 4
        DoEvents
    Loop

    ' レスポンスをDictionaryに変換してリターン
    Dim Json As Object
    Set Json = JsonConverter.ParseJson(client.responseText)
    Set SendRequest = Json
End Function
```
こんな感じ、です。
WebDriverを起動する部分とか端折ってますが、これも[こちら](https://qiita.com/tamarinn_x/items/b5000ede6a355ae9609a "Edge & WebDriver を、Selenium を使わずにオプション付きで起動する")を参考にしていただければと思います。