Power Automate for Desktopでセレクター編集・例外処理を設定する

# はじめに
無料のRPAツールであるPowerAutomateDesktopを触ったことがなかったので、[こちら](https://qiita.com/maekawawawa/items/ba6a4e8e8c72bd549e0a)の記事を参考に、Yahoo!路線情報にExcelから取得した出発地点と到着地点の情報を入力後、検索結果の料金を取得しExcelに入力する自動化のフローを作成しました。
作成する中で、ブラウザの画面処理とセレクターの編集、例外処理をフローに加えてみたかったので、以下の3点を追加しました。
- Webレコーダーを使用しない
- 検索結果の料金を上から順番に3つ取得する
- 料金を取得できなかった時でも次の処理に進むようにする(例外処理)

中でも、セレクター編集のところで少し工夫が必要だったので、忘れないように記事にまとめることにしました。

:::note info

Yahoo!路線情報の利用規約で、RPAによる自動化処理は禁止されていませんが、本記事を参考に作成・実行する際は自己責任でお願いいたします。
:::


### Power Automate、Power Automate for Desktopとの違い
Power系ツールは似た名前が多く、それぞれの違いを理解できていなかったので、簡単にまとめました。

|名称|概要|例|
|--|--|--|
|Power Automate|ブラウザで起動し、クラウド上で様々なアプリと連携して処理をおこなうツールで、ブラウザ操作(クリック、入力)の自動化は**できない**|Outlook カレンダー イベントに基づいて Planner でタスクを作成する|
|Power Automate Desktop|個人のPCにインストールし、デスクトップ上から起動するRPAツールで、ブラウザ操作(クリック、入力)の自動化が**できる**|Excelから申請情報を取得し、ブラウザの申請ページに情報を入力する|
|Power Automate **for** Desktop|投稿日時点での Power Automate Desktop の正式名称|-|

# 事前準備
- 検索結果を入力するExcelファイルの列を以下のように設定しておく。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3128319/8e9ba204-0442-f30e-e9e5-3a6e0d2da806.png)

※出発地と到着地は任意で設定してください。


# 作成手順
全体の流れは[こちら](https://qiita.com/maekawawawa/items/ba6a4e8e8c72bd549e0a)の記事とほとんど変わらないので、自分で手を加えた箇所を重点的に記載します。

Excelの起動～Excelワークシートから出発地点と到着地点を読み取るアクションを以下のように設定します。
ここまでは参考記事と同じです。
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3128319/f1cff41b-faae-a3ad-bde8-d7d69b6c3dd1.png)

### Webレコーダーを使用せずブラウザの処理を設定
以下の流れをWebレコーダーでなく、手作業で1→2→3→4→6の順に設定します。
主に、6で行うセレクターの編集について詳しく説明します。
※5の手順は省略しました。
>Webブラウザの操作の流れは以下の通りです。
>1.路線情報の画面を起動する
>2.路線情報の出発地項目に「%departure%」の値を入れる
>3.路線情報の到着地項目に「%arrival%」の値を入れる
>4.検索ボタンを押下する
>5.検索結果画面に遷移したら乗換回数が少ない順の画面に切り替える
>6.表示された料金を取得して変数に格納する


まず、`1.路線情報の画面を起動する`を設定します。
アクション一覧から任意のブラウザ起動のアクションを設定します。
今回は「新しいMicrosoft Edgeを起動」を使用します。
![無題2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3128319/96e77746-6069-b541-3e22-dcaa2248b668.png)
アクションの詳細は以下のとおりです。
初期URLにはYahoo!路線図のホーム画面のURLを設定します。
![無題1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3128319/f03a5123-51e0-87ef-ac2f-e5a5890eb6bc.png)
次は`2.路線情報の出発地項目に「%departure%」の値を入れる`を設定します。
ブラウザに出発地点を入力するアクションを設定したいので、「Webページ内のテキストフィールドに入力する」を使用します。
![無題3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3128319/36f513f6-7ff3-4919-5b7d-780578e71e1b.png)
まず画面のUI要素を指定したいので、Yahoo!路線図のホーム画面を開いた状態で「UI要素」欄をクリック→「UI要素の追加」をクリックします。
![無題5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3128319/b43e7fdd-56c8-b5c2-e6b4-837e241a6963.png)
UI要素ピッカー画面が表示されるので、出発地点入力欄にマウスカーソルをホバーし、赤い枠が表示されたらCtrlキー+左クリックで選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3128319/72a3bc42-f27e-0387-4317-77d1b727c91f.png)
選択後、UI要素ピッカー画面が自動で閉じ、選択したUI要素のセレクターが自動で設定されます。
「テキスト」はExcelから取得した出発地点の`%departure%`を設定します。
![無題6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3128319/35aa1716-eef7-1b90-fa97-918be9d25455.png)

次に`3.路線情報の到着地項目に「%arrival%」の値を入れる`を設定します。
出発地点と同様の方法で設定するので、アクションの詳細は以下のようになります。
![無題7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3128319/0baf4135-49b6-7662-5c2d-7faa726049b9.png)
次に、`4.検索ボタンを押下する`アクションを設定します。
「Webページのボタンを押します」を使用します。
![無題8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3128319/5119b4ce-89c0-f32e-863c-30315e72e658.png)
アクションの詳細画面で、検索ボタンのUI要素を取得し、保存ボタンをクリックします。
![無題9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3128319/24109393-a3bd-faeb-fd4f-c9edfb43f47e.png)

### セレクターを編集する(Power Automate for Desktop)
次に`6.表示された料金を取得して変数に格納する`を設定します。
Yahoo!路線情報の検索結果は、経路の候補が最大で3つ表示されるので、それを全て取得します。
![無題11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3128319/c6bc1fa4-e3ba-5127-2991-ba37636f24b7.png)
アクションは「Webページ上の要素の詳細を取得します」を使用します。
![無題10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3128319/23dc779b-0d28-b688-4540-0c31b0918d69.png)
アクションの詳細画面で一行目の`6090円`のUI要素を取得します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3128319/99b37e7c-637b-aeef-a1a0-22e25dd7bdbf.png)
この時取得した料金の値を格納する「生成された変数」は自動で`%AttributeValue%`に設定されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3128319/ca826bfb-bc5a-6f28-7b06-3db5e117b0f2.png)

ここで、今取得したUI要素で、別の検索結果画面の料金も正しく取得できるかテストをします。
Yahoo!路線情報ページで異なる検索条件結果を表示させてから、画面の右上の◇が3つ重なっているUIをクリックします。
![無題12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3128319/2e2a591d-8721-049d-ec71-e83cbc247516.png)
今まで取得したUI要素の一覧が表示されるので、`6090円`をダブルクリックします。
![無題13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3128319/03adf954-9661-69d7-2ea6-9b14c22e8140.png)

セレクターの編集画面が表示されました。
この画面では取得したUI要素の確認、編集、新規登録、テストなどができます。
画面の構成は、画面下部のセレクターのプレビュー欄と、画面中央～右の要素欄が連動しており、要素を編集することで、プレビューに自動でセレクターが反映される仕様になっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3128319/bae39e88-8246-0b2e-fe1c-52bd40ceef39.png)

今回はUI要素のテストをしたいので、フラスコマークの「テスト」をクリックし、UI要素をテストする の「テスト」をクリックします。
![無題14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3128319/1e7fd20c-d6a1-69c3-b5fa-d7b397e32523.png)
どのページのUI要素を取得するか聞かれるので、Yahoo!路線情報のページを選択しOKをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3128319/ead1a2e8-1342-9d6a-bef9-365b4de9e266.png)

:::note warn

この時、最初にUI要素を取得した時と検索結果が違う（一行目が`6090円`でない）ページを表示させておいてください。
![無題16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3128319/3c44f172-2f26-e719-7e9d-15600e50da0e.png)
:::

テストボタン押下後、セレクター画面に赤い！マークが表示されました。
これは画面からUI要素が取得できず、テストが失敗したことを意味します。
失敗した理由は、セレクターに`ul[Id="rsltlst"] > li > dl > dd > ul > li[Text="6,090円"]`と表記があるためです。
このセレクターだと、検索結果の一行目が`6090円`のときしか要素を取得できません。
![無題17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3128319/80bdff34-8a4a-2f7b-7221-d33df4f7cc65.png)

どんな検索をしても正確な料金が取得できるよう、正規表現を使用してセレクターを以下のように編集します。
- 「演算子」を`と等しい`→`次の値で終わる`
- 「値」を`6090円`→`円`

編集結果、セレクタープレビューは`ul[Id="rsltlst"] > li > dl > dd > ul > li[Text$="円"]`になりました。これで`円`で終わる要素`(〇〇円)`を取得できるはずです。
再度テストを行います。
![無題18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3128319/d44c9a69-603f-d524-dff9-813c5826b118.png)

テストが成功すると緑色のチェックマークが表示されるのですが、オレンジ色の！マークが表示されました。詳細を見てみると、このUI要素では複数の要素が取得されてしまうのでよくない、とのことでした。
![無題20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3128319/075b1855-505a-dd85-0a42-1361be2d9321.png)
試しに2行目の料金のUI要素を取得してみると、1行目のUI要素とまったく同じUI要素が取得されたので、セレクターをさらに編集する必要がありそうです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3128319/bde2f8a8-e8e2-fa86-994b-d7c209681b96.png)

1行目、2行目、3行目を区別する要素をセレクターに追加したいので、[こちら](https://qiita.com/spumoni/items/fcc71034ce162fcf3db7)の記事を参考に、ブラウザ(Microsoft Edge)の機能を使用してセレクターを取得してみたいと思います。

### セレクターを編集する(Microsoft Edge)
>取得したい箇所を右クリックし、「開発者ツールで調査する」を選択。HTMLのコードが表示され、該当の個所がハイライトしていますので、その箇所で右クリックして、「コピー」⇒「selectorをコピー」とします。

上記引用のように1行目の料金のセレクターを取得したところ、`#rsltlst > li:nth-child(1) > dl > dd > ul > li.fare`が取得できました。
2行目の料金のセレクターは`#rsltlst > li:nth-child(2) > dl > dd > ul > li.fare`だったので、`li:nth-child(1)`の **(1)** が行を表していることがわかります。
このセレクターだと、1行目、2行目、3行目を区別できそうなので、Power Automate for desktopのセレクター編集画面に設定します。
右上の「テキストエディタ」をクリックします。
![無題22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3128319/c8b8420f-dcb6-d81b-7dcf-ffa705d1fd29.png)
セレクターを手入力で編集できる画面が表示されるので、ブラウザから取得したセレクターをコピー＆ペーストします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3128319/c8d63045-bfe9-8c1d-69cb-8ae4887c3638.png)
テストボタンをクリックすると緑色のチェックマークが表示され、正しく要素が取得できたことがわかりました。
![無題23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3128319/06399ed7-cc19-39d6-3b4a-a572e40e7b5f.png)

これで1行目の料金のUI要素を取得できました。同様に2行目と3行目の設定も行います。
セレクターの`li:nth-child(1)`の数字と取得したい行がリンクしている（`li:nth-child(1)`→1行目、`li:nth-child(2)`→2行目）のでループ処理で取得するアクションを設定します。

ループアクションを設定します。
![無題24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3128319/a8f84757-b38f-f60a-c698-32728717f66d.png)
アクションの詳細は以下のように設定します。
- 開始値と増分は`1`
- 取得する料金は最大3行なので、終了値は`3`
- 変数名は`LoopIndex2`
※この設定で`LoopIndex2`の値がループの1回目→1、2回目→2、3回目→3になります。
![無題25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3128319/2a95809b-6bab-5c52-6f72-55b413724258.png)

次に上記で追加したループアクションの中に「Webページ上の要素の詳細を取得します」アクションを移動します。セレクター画面を開き、`#rsltlst > li:nth-child(1) > dl > dd > ul > li.fare`の  **`(1)`** を`%LoopIndex2%`に変更します。
これでループが1回目の時は1行目、2回目の時は2行目の料金が取得できるようになりました。
![無題27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3128319/df0953b5-adca-6a37-84d5-07e3478cfa0f.png)
セレクターの名前もわかりやすいように任意の名前に変更しておくとよいです。
![無題26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3128319/2c244c13-6f03-07b8-75c9-b6a23a82dff2.png)
最後に、ループ処理のお約束として、追加したループアクションの先頭に、料金を格納する変数`%AttributeValue%`を初期化するアクション「変数の設定」を設定しておきます。
![無題29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3128319/2dbd5d36-bc92-b561-e969-51680a3c86ec.png)
変数に`%AttributeValue%`、値に`%''%`を設定します。
`%''%`で変数に空の値を格納することができます。
![無題30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3128319/809f1e67-aa6e-af1a-ade5-44b2795cc835.png)

ここまでのフローは以下のようになります。
これでループの中で1行目から3行目までの料金を取得できるようになりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3128319/8b3de9a3-52c0-a837-60da-78acc73e33bc.png)

次に取得した料金をExcelに書き込む処理を設定します。
「Excelワークシートに書き込む」アクションを「Webページ上の要素の詳細を取得します」の下に設定します。
![無題38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3128319/a693b11b-b983-f103-0566-c3d01a61043c.png)


アクションの詳細は以下のように設定します。
- Excelインスタンス：`%ExcelInstance%`(初期値)
- 書き込む値：`%AttributeValue%`
- 書き込みモード：`指定したセル上`(初期値)
- 列：`%2 + LoopIndex2%`
- 行：`%LoopIndex%`

![無題39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3128319/3b684069-8c04-4541-5ad3-76b718872b6b.png)
ループ処理の中で書き込むので、書き込み列と行はループの変数を使用して設定します。
列のアルファベットを数字に置き換えると以下のようになります。

|出発地点|到着地点|1行目料金|2行目料金|3行目料金|
|--|--|--|--|--|
|A列|B列|C列|D列|E列|
|1|2|3|4|5|

内側のループの変数`%LoopIndex2%`は1→2→3と増えていくので、初期値で`2`を足した、`%2 + LoopIndex2%`を列項目に設定すると、3→4→5になるので、書き込み列の番号と一致させることができます。

外側のループの変数`%LoopIndex%`の初期値は2でExcelの書き込み行も2行目からなので、行項目には`%LoopIndex%`をそのまま設定します。

ここまででフローはほぼ完成ですが、何度かテスト実行をしている中でエラーがでて処理が途中で止まってしまうことがありました。以下は例外処理について記載します。

### 例外処理
Yahoo!路線情報で検索処理を行ったとき、検索結果が1行しかない時は処理が途中で止まってしまいました。
![無題40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3128319/f95ee804-ae43-207e-68a3-c140038c42ef.png)
このような時も次の処理に進むように例外処理を設定します。
「Webページ上の要素の詳細を取得します」の編集画面を開き、左下の「エラー発生時」ボタンをクリックします。
![無題33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3128319/298ac8b8-c189-3791-1480-5dd59d304285.png)
2行目、3行目がなくても次の処理に進むようにしたいので、「フロー実行を続行する」をクリックします。
![無題34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3128319/70d2a2eb-313d-0aa7-7584-d36e320816c3.png)
「例外処理モード」の項目が表示されます。初期値が「次のアクションに移動」になっているのでそのまま保存ボタンをクリックします。
![無題35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3128319/34e0a5b9-ad8c-0752-8dc1-608ae4595b46.png)
これで2行目、3行目の表示がなかった時も、次の処理に遷移させることができます。

### 最後に
「Webブラウザーを閉じる」アクションを内側のループを出た直後に、「Excelを閉じる」アクションをフローの一番下に挿入します。
![無題41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3128319/f280ffe6-af92-f5c9-169b-029a589361fa.png)
「Excelを閉じる」詳細で「Excelを閉じる前」を`ドキュメントを保存`に変更し保存します。
![無題42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3128319/5669a236-12a7-61f7-bb40-35969db8e4ba.png)
![無題43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3128319/35eca0e5-c411-4942-728f-fd901ee780d2.png)

以上でフローが完成しました。
画面上部の実行ボタンをクリックしてフローを実行します。
フローが止まることなく、最後まで実行されました。
Excelに処理結果も記入されています。
※網走→釧路間は検索結果が1行しか表示されませんでしたが、止まることなく実行されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3128319/84b4dabe-7fa4-543b-bd8b-cfa6bba70409.png)

### 完成フロー
![無題44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3128319/f337a3dc-2932-d37f-8736-16619e557f48.png)


# 感想
アクションを設定すると変数名が自動的に設定されたり、セレクターの編集も、Power Automate for Desktopの機能だけでなく、MicrosoftEdgeの機能を使って簡単に設定できたり、細かな仕様がとても親切で使いやすいツールだと思いました。
また、本記事を作成するうえで、下記サイトを参考に致しました。細かな解説などたいへん参考になりました。ありがとうございました。

# 参考サイト
- [Power AutomateとPower Automate Desktopの違い](https://inhousese.break-employee.com/2023/01/19/powerautomate_powerautomatedesktop/#toc4)
- [【初心者向け】Power Automate for Desktopとは？](https://www.teijitaisya.com/pad-about/)
- [【Power Automateの新しいRPA機能】Power Automate Desktopの操作方法(ExcelとWebブラウザ操作の自動化)](https://qiita.com/maekawawawa/items/ba6a4e8e8c72bd549e0a)
- [CSSセレクターを使いこなす : Power Automate for desktopがなんとなく使える講座 #12](https://qiita.com/spumoni/items/fcc71034ce162fcf3db7)