【RPA】Power Automateでウェブスクレイピングを実行し、結果をExcelにまとめる

# 本記事の内容

- Power Automateでのウェブスクレイピングの基礎をまとめた記事です。

とあるWebサイトをポチポチクリックし、その内容をエクセルに貼り付ける情報収集作業を行う必要があり、
"作業対象ボリュームが多い単純作業"だったので、RPA(Microsoft PowerAutomate Desktop)を使って自動化を試みました。
実際に実行したプログラムは、私自身の情報が入っているため紹介できないのですが、、
ノウハウの共有としてQitaのサイトを題材にしたウェブスクレイピングの実現方法を本記事にまとめました。

以下がQitaのサイトでデモ実施した動画です。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Microsoft PowerAutomate Desktopでウェブスクレイピングの勉強してみた。思ったより簡単にプログラムを書くことが出来た。Qitaのトップページに表示された記事を開きExcelに転記しています。 <a href="https://twitter.com/hashtag/Microsoft?src=hash&amp;ref_src=twsrc%5Etfw">#Microsoft</a> <a href="https://twitter.com/hashtag/PowerAutomate?src=hash&amp;ref_src=twsrc%5Etfw">#PowerAutomate</a> <a href="https://twitter.com/hashtag/%E3%82%A6%E3%82%A7%E3%83%96%E3%82%B9%E3%82%AF%E3%83%AC%E3%82%A4%E3%83%94%E3%83%B3%E3%82%B0?src=hash&amp;ref_src=twsrc%5Etfw">#ウェブスクレイピング</a> <a href="https://twitter.com/hashtag/Webscraping?src=hash&amp;ref_src=twsrc%5Etfw">#Webscraping</a> <a href="https://t.co/GzQ9sVtuJS">pic.twitter.com/GzQ9sVtuJS</a></p>&mdash; kaname kun (@kanamekunkun) <a href="https://twitter.com/kanamekunkun/status/1548649447482990593?ref_src=twsrc%5Etfw">July 17, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

デモでは、Qitaのトップページにアクセスし、上位４つのリンクを取得。それぞれのページに遷移し、内容をExcelに転記という操作をしています。

# 実施環境
- Windows 10
- Chrome
- Microsoft PowerAutomate Desktop
　※Microsoft関連について、以下の前提です。
　　・Power Automateのライセンスは入手済み。
　　・Microsoftアカウントは作成済み。

# 手順の流れ
1. Microsoft PowerAutomateのインストール
2. フローの作成
3. 実行している際の様子

## 1.Microsoft PowerAutomateのインストール

Microsoftが提供しているインストーラーでインストールを進めます。

こちらのサイトが参考になりました。
[【ダウンロード手順】Microsoft Power Automate Desktopの使い方](https://enpreth.jp/media/microsoft-power-automate-download/)


## 2.フローの作成

PowerAutomateの「フロー」というのは、プログラムです。
「フロー」でどのような操作をPowerAutomateに行わせるか定義を行います。

ウェブスプレイピングを行うために必要な操作はおおよそ以下です。必要に応じて④～⑥を繰り返します。
① データを張りつけるExcelを開く
② ブラウザーを起動し情報収集するサイトにアクセス
③ 開いたページにて収集対象の遷移先情報(URLやクリックする用のタグ)を取得する
④ 情報集対象のページへ遷移する
⑤ 遷移先のページで入手したい情報をコピーする
⑥ コピーした内容をExcelに貼り付ける
⑦ ブラウザーを閉じる
⑧ エクセルを閉じる

PowerAutomateで作成したフローは以下のようになっています。
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017667/472e4344-cd6e-fbfc-4060-1841f8da9384.png)
実際のプログラムに数字（ex ①等）をマッピングし分かりやすくしました。

以降で具体的な実装方法を解説していきます。

### ① データを張りつけるExcelを開く

Excelの起動は以下の図のようにExcelタブの中の「Excelの起動」を利用します。

![2-1-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017667/aca181cc-73ba-dece-9fc1-2f7fc5187449.png)

以下のような設定を行います。
![2-1-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017667/11d3b2eb-75f3-020b-f7a3-6bede5ccc515.png)

デフォルトから変更したのは、ドキュメントパスだけです。
Excelの起動で「次のドキュメントを開く」を指定しているので、ドキュメントパスに指定したExcelファイルが開かれます。
このプログラムが実行されると開いたExcelは「ExcelInstance」という変数で操作できるようになります。

予め成形済みのExcelを用意しておくことで、入力されたデータの見やすさを工夫しました。
今回は以下のようなフォーマットにしました。
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017667/bc2c7fb9-ad70-781f-a34f-1a6ec6eb85fe.png)


次に入力を行うシートをアクティブ（選択された状態）にします。

Excelタブの中の「アクティブなExcelワークシートの設定」を利用します。
![2-2-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017667/fb6e3523-5341-2eb0-1618-a688326e892d.png)

以下のような設定を行います。
![2-2-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017667/381ffbb8-901f-9458-79f1-c5d621973a4c.png)

デフォルトで変更したのは、ワークシート名だけです。
こちらは実際に書き込みを行うシート名に合わせる必要があります。

Excelインスタンス欄に「%ExcelInstance%」という値がありますが、これはExcelInstanceという変数を利用するという意味となります。%%に挟まれたエリアはすでに定義済みの変数名と同じものがあった場合は、その変数が参照されるようになります。
こちらは一つ目のプログラムで設定したExcelインスタンスの変数です。


### ② ブラウザーを起動し情報収集するサイトにアクセス

ブラウザー自動化タブの中の「新しいChromeを起動する」を利用します。
![2-3-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017667/57e134e3-d7fb-ebe7-a2cb-ae69034de2b3.png)

以下のような設定を行います。
![2-3-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017667/8fd5bd10-d5ac-b39e-f651-a154ca2a99ad.png)

初期URL欄に指定したURLがブラウザー起動時に開かれるページです。
ここでは、Qitaのトップページを指定しています。
このプログラムで生成されるブラウザーは「Browser」変数で操作できるようになります。


### ③ 開いたページにて収集対象の遷移先情報(URLやクリックする用のタグ)を取得する

ブラウザー自動化 > Webデータ抽出タブの中の「Webページからデータを抽出する」を利用します。
![2-3-5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017667/a30a90ca-3271-4066-bdce-38b7b8e5a13c.png)

以下のような設定を行います。
![2-3-6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017667/fe69434a-828a-ba1d-91a9-fc2543dc1307.png)

特に変更は行わず情報を取得する対象のブラウザーを画面の最前面に表示します。
表示するとライブWebヘルパーが開くので、こちらを利用して取得方法を定義します。
![2-3-7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017667/2a441454-2846-6ba7-a967-fb9575fbe398.png)

ブラウザー上で、遷移先したいリンクを右クリックし「要素の値を抽出」> 「Href:(https://〇〇」をクリックする。
![2-3-8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017667/1788eae6-b706-6d96-15eb-8c2493a82423.png)

次も一個下のリンクを同様の手順で実施するとライブWebヘルパーが以下のようになり、同一のレイアウトで繰り返されるリンクを自動で取得している。
![2-3-9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017667/6ffb94ff-1ea8-c484-b9ac-cf80ca57b3a7.png)

このページの場合は、トップページに記事が30個ピックアップされるようなので、30リンク分の取得がされていた。
抽出方法が定まったので「終了」ボタンを押し、元の画面の「保存」ボタンを押下する。
これで取得したリンク先が生成された変数である「DataFormWebPage」に格納されるようになる。

実際にDataFormWebPageにどの様な値が格納されるかは、デバック実行すると確認できる。
具体的には以下のようになっていて、トップページの記事のURLを取得することができます。
![2-3-10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017667/9b4e81df-63d4-a393-5b6a-5c51a36392d7.png)
![2-3-11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017667/1bd8be56-7290-e733-57e4-6daca36aa71b.png)

0オリジンの2次元配列のようになっているので、DataFormWebPage[0][0]とすると一つ目のURLの値("https://qiita.com/Myv_yy_YJPY/items/cab100720692d8fc7af8" )が取得できる。
二つ目の値を取る場合は、DataFormWebPage[1][0]となって一つ目の配列のインデックスが大きくなっていく。

ちなみに詳しいデバック実行手順はこちらを参照ください。とても参考になりました。
[Power Automate Desktopがなんとなく使える講座 #5 デバッグとエラー処理](https://qiita.com/spumoni/items/eccd0606be506eb1cf95)

また「変数の設定」を定義し、DataFormWebPageの行数をカウントすることで、何個取得できたかを変数(%pageCount%)として保持しておく。

![2-3-12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017667/42bd3ee9-c605-0707-326f-e1e0ef17c164.png)


### ④ 情報集対象のページへ遷移する

④～⑥の操作はループするため、URLを繰り返し取得するためには、DataFormWebPage[i][0]としてiをインクリメントしていく。

ループ処理を入れるためにループタブの中の「Loop」を利用します。
![2-4-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017667/f9e57d7e-a720-c9fc-de39-b7c17b1cc9ed.png)

以下のような設定を行います。
![2-4-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017667/9397aecc-5d7f-a744-36bf-d662b1e3a03b.png)
今回はデモとして、4つ目迄記事の情報を取得するため、開始値:0 終了値:3 増分:1としています。Loopが回るごとに変数「LoopIndex」の値がカウンターとして1ずつ増えます。

ループ内の処理の一つ目では、ブラウザー自動化 > 「Webページに移動します」を利用します。
![2-4-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017667/e006d9dd-be48-bc94-7e9f-040f1c5591e3.png)

以下のような設定を行います。
![2-4-4+.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017667/37b2dd8b-12eb-4243-1be6-0b4b1a619860.png)
URL欄は、「%DataFromWebPage[LoopIndex][0]%」とすることで、ループのカウンターが増えるごとに取得できるURLが変わっていく。


### ⑤ 遷移先のページで入手したい情報をコピーする

処理が煩雑のため「サブフローの実行」を用いて、ブラウザーから値を取得して、Excelに貼り付ける処理は別モジュールとして切り出します。
![2-5-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017667/31a92e31-91cb-bf6b-3097-f020046e4298.png)

サブフローの操作は以下のようになっています。Webページで値を取得して、Excelに貼り付ける動作をサブフロー内で何度も繰り返しています。
![2-5-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017667/474b1f54-cb5b-f03e-19da-468778c02870.png)

ブラウザー自動化 > Webデータ抽出タブの中の「Webページからデータを抽出する」を利用し、以下のような設定を行います。
![2-5-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017667/4aea59df-a905-6fea-259d-1adda21797c1.png)

③と同じような手順で、テキスト値を取得した。変数にtitleには、取得したテキストの値が入る。
![12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017667/2ffcbaa2-8799-0b7a-835b-f7c371d47580.png)


### ⑥ コピーした内容をExcelに貼り付ける

Excel > 「Ｅxcelワークシートに書き込み」を利用し、以下のような設定を行います。
![2-5-5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017667/bc9440c4-2bb8-fe10-a1ce-0bbd1ffe1cc5.png)

「書き込む値：」欄で実際に入力する値を入れています。 ※ここは、記事タイトルなので、変数%title%を入れます。
列、行ともに1オリジンなので、以下としました。こうすることで、ループカウントが増えるたびに入力値が右のセルにずれていきます、
列：%2 + LoopIndex%
行：１

上記の手順で取得した記事のタイトルはExcelに転記できました。
同様の手順で、他の項目もExcelに記載できます。


### ⑦ ブラウザーを閉じる

ブラウザー自動化タブの中の「Webブラウザーを閉じる」を利用します。
![2-7-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017667/71cf3450-7ac8-ad6f-7cac-c7feb28685c0.png)

以下のような設定を行います。
![2-7-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017667/9bf7cb11-a04c-f687-c2e3-e363ad2e3b36.png)
ブラウザーインスタンス欄に②で生成したブラウザーの変数(%Browser%)を指定する必要があります。
※ %Browser% は初期値として設定されいているので、複数ブラウザーを生成している場合のみ変更が必要です。

### ⑧ エクセルを閉じる

Excelタブの中の「Excelを閉じる」を利用します。

以下のような設定を行います。

ブラウザーインスタンス欄に②で生成したブラウザーの変数(%Browser%)を指定する必要があります。
※ %Browser% は初期値として設定されいているので、複数ブラウザーを生成しいる場合のみ変更が必要です。

手順は以上。

## おわりに
ざっくりですがここまでの手順でPower Automateを用いてウェブスクレイピングの最低限のことが出来るようになります。
いろいろ試して頂ければと思います。



以下にMainのサンプルプログラムを載せます。編集画面上にコピペするとフローを貼り付けられます。

```Main
Excel.LaunchExcel.LaunchAndOpenUnderExistingProcess Path: $'''\\\\home_nas\\Qiita.xlsx''' Visible: True ReadOnly: False Instance=> ExcelInstance
WebAutomation.LaunchChrome.LaunchChrome Url: $'''https://qiita.com/''' WindowState: WebAutomation.BrowserWindowState.Normal ClearCache: False ClearCookies: False WaitForPageToLoadTimeout: 60 Timeout: 60 BrowserInstance=> Browser
Excel.SetActiveWorksheet.ActivateWorksheetByName Instance: ExcelInstance Name: $'''Qita'''
WebAutomation.ExtractData.ExtractList BrowserInstance: Browser Control: $'''html > body > div:eq(0) > div:eq(1) > div > div:eq(0) > main > section > div > article''' ExtractionParameters: {[$'''h2 > a''', $'''Href''', $''''''] } PostProcessData: False TimeoutInSeconds: 60 ExtractedData=> DataFromWebPage
SET pageCount TO DataFromWebPage.RowsCount
LOOP LoopIndex FROM 0 TO 3 STEP 1
    WebAutomation.GoToWebPage.GoToWebPage BrowserInstance: Browser Url: DataFromWebPage[LoopIndex][0] WaitForPageToLoadTimeout: 60
    CALL InfoGet
END
WebAutomation.CloseWebBrowser BrowserInstance: Browser
Excel.CloseExcel.CloseAndSave Instance: ExcelInstance


```
Ｗebヘルパーで画面上で取得したUI要素はコピーできないようなので注意。再度自身で設定いただく必要がありそうです。

``` InfoGet
WebAutomation.ExtractData.ExtractSingleValue BrowserInstance: Browser ExtractionParameters: {[$'''html > body > div:eq(0) > div:eq(2) > div:eq(0) > div > div:eq(3) > div:eq(0) > div:eq(0) > h1''', $'''Own Text''', $''''''] } TimeoutInSeconds: 60 ExtractedData=> title
Excel.WriteToExcel.WriteCell Instance: ExcelInstance Value: title Column: 2 + LoopIndex Row: 1
Excel.WriteToExcel.WriteCell Instance: ExcelInstance Value: DataFromWebPage[LoopIndex][0] Column: 2 + LoopIndex Row: 2
WebAutomation.ExtractData.ExtractSingleValue BrowserInstance: Browser ExtractionParameters: {[$'''html > body > div:eq(0) > div:eq(2) > div:eq(0) > div > div:eq(3) > div:eq(0) > div:eq(0) > div:eq(0) > div > div > div:eq(0) > div > a''', $'''Own Text''', $''''''] } TimeoutInSeconds: 60 ExtractedData=> articleAuthor
Excel.WriteToExcel.WriteCell Instance: ExcelInstance Value: articleAuthor Column: 2 + LoopIndex Row: 3
WebAutomation.ExtractData.ExtractSingleValue BrowserInstance: Browser ExtractionParameters: {[$'''html > body > div:eq(0) > div:eq(2) > div:eq(0) > div > div:eq(3) > div:eq(0) > div:eq(0) > div:eq(1)''', $'''Own Text''', $''''''] } TimeoutInSeconds: 60 ExtractedData=> articlteTag
Excel.WriteToExcel.WriteCell Instance: ExcelInstance Value: articlteTag Column: 2 + LoopIndex Row: 4
WebAutomation.ExtractData.ExtractSingleValue BrowserInstance: Browser ExtractionParameters: {[$'''html > body > div:eq(0) > div:eq(2) > div:eq(0) > div > div:eq(0) > div:eq(0) > a''', $'''Own Text''', $''''''] } TimeoutInSeconds: 60 ExtractedData=> lgtmCount
Excel.WriteToExcel.WriteCell Instance: ExcelInstance Value: lgtmCount Column: 2 + LoopIndex Row: 5
WebAutomation.ExtractData.ExtractSingleValue BrowserInstance: Browser ExtractionParameters: {[$'''html > body > div:eq(0) > div:eq(2) > div:eq(0) > div > div:eq(0) > div:eq(1) > span''', $'''Own Text''', $''''''] } TimeoutInSeconds: 60 ExtractedData=> stockCount
Excel.WriteToExcel.WriteCell Instance: ExcelInstance Value: stockCount Column: 2 + LoopIndex Row: 6
WebAutomation.ExtractData.ExtractSingleValue BrowserInstance: Browser ExtractionParameters: {[$'''html > body > div:eq(0) > div:eq(2) > div:eq(0) > div > div:eq(3) > div:eq(0)''', $'''Own Text''', $''''''] } TimeoutInSeconds: 60 ExtractedData=> articleContent
Excel.WriteToExcel.WriteCell Instance: ExcelInstance Value: articleContent Column: 2 + LoopIndex Row: 7


```

# 参考文献
本記事の作成に当たり、以下の情報を参考にさせて頂きました。
- [Power Automate Desktopがなんとなく使える講座 #5 デバッグとエラー処理](https://qiita.com/spumoni/items/eccd0606be506eb1cf95)
- [【ダウンロード手順】Microsoft Power Automate Desktopの使い方](https://enpreth.jp/media/microsoft-power-automate-download/)