Power Automate Desktop Webページからデータを抽出する 2
Webスクレイピング
はじめに
PADでスクレイピングの2回目。
前回は、抽出したい属性を一つずつ選択しました。今回は違う方法を試してみます。
前回: Power Automate Desktop Webページからデータを抽出する
レシピ
Microsoft Rewardsのポイント履歴をExcelに出力して保存します。
抽出する項目
- 状態
- 日付
- リワード
- ポイント
スクレイピングする
まず初めに、スクレイピングの部分から作っていきます。
Microsoft Rewardsのサイトを開いて、注文履歴を表示します。
PADから新しいフローを追加します。フロー名は適当にどうぞ。
-
新しい Microsoft Edge を起動
今回は、毎回URLから開くようにします。
ただ、デバッグの度に毎回ウィンドウが開くのは鬱陶しいので最初は開いたまま作りこみます。
開きっぱなしにしていた方が、例えば今回はUI要素は使っていませんが、セレクターのテストするときなどにも便利だと思います。
完成後にこの状態にします。
-
Webページからデータを抽出する
テーブルからどこでもいいので要素を選んで、HTMLテーブル全体を抽出します。
-
抽出プレビューで確認
この方法で抽出した場合は、ヘッダー名が日本語でとれるみたいです。
ポイント #1と#2は要らないので.NETスクリプトで削除しようと思います。
リワードのテキストも弄ろうと思います。
-
ここまでのコード
FUNCTION Main_copy GLOBAL
WebAutomation.LaunchEdge.AttachToEdgeByTitle TabTitle: $'''リワードの引き換え''' AttachTimeout: 5 BrowserInstance=> Browser
WebAutomation.ExtractData.ExtractHtmlTable BrowserInstance: Browser Control: $'''html > body > div:eq(0) > div:eq(1) > main > div:eq(1) > div:eq(1) > div:eq(1) > table''' ExtractionParameters: {[$'''状態''', $'''日付''', $'''リワード''', $'''ポイント''', $'''ポイント #1''', $'''ポイント #2'''], [$'''''', $'''''', $'''''', $'''''', $'''''', $''''''] } PostProcessData: False TimeoutInSeconds: 60 ExtractedData=> DataFromWebPage
END FUNCTION
スクレイピングの作りこみは完成。
.NETスクリプトを使う
DataTableに格納できたので、ここから.NETスクリプトでデータを弄っていきます。
今はこの状態になっています。
状態 | 日付 | リワード | ポイント | ポイント #1 | ポイント #2 |
---|---|---|---|---|---|
↓ポイント #1 / #2を削除して以下のようにします。
状態 | 日付 | リワード | ポイント |
---|---|---|---|
.NET スクリプト実行
Language: C#
.NET script imports:
Script Parameters:
.NET parameter name | Type | Direction | Input value | Output value |
---|---|---|---|---|
dt | Datatable | In-Out | %DataFromWebPage% | %DataFromWebPage% |
dt.Columns.Remove("ポイント #1");
dt.Columns.Remove("ポイント #2");
var table = dt.Clone();
foreach (DataRow row in dt.Rows)
{
var s = row["リワード"].ToString();
var position = s.IndexOf("注文番号");
var rewards = s.Substring(0, position).Trim();
table.Rows.Add(row["状態"], row["日付"], rewards, row["ポイント"]);
}
dt = table;
何のアイテムに引き換えたかだけで十分なので
IndexOf
を使って注文番号より前のテキストを取得してトリムします。
実行して確認します。
Excelにデータを書き込む手順は省略
省略。
VBSを使います
Excelの仕上げはVBSでやっちゃいます。
VBScript の実行
Option Explicit
Dim objExcel, objWorkbook, objSheet
Set objExcel = CreateObject("Excel.Application")
objExcel.Application.Visible = False
Set objWorkbook = objExcel.Workbooks.Open("%ExcelFile%")
Set objSheet = objWorkbook.Sheets(1)
Dim dataAll
Set dataAll = objSheet.UsedRange
dataAll.Borders.LineStyle = True
Const xlCenter = -4108
Const xlThemeColorAccent6 = 10
Dim header
Set header = dataAll.Resize(1)
With header
.HorizontalAlignment = xlCenter
.Interior.ThemeColor = xlThemeColorAccent6
.Interior.TintAndShade = 0.8
End With
objWorkbook.Save
objWorkbook.Close True
objExcel.Quit
完成
VBScriptで罫線を引いて、ヘッダーを中央揃え・セルの塗りつぶしを行いました。
完成フロー
FUNCTION Main_copy GLOBAL
**REGION 設定
Folder.GetSpecialFolder SpecialFolder: Folder.SpecialFolder.Personal SpecialFolderPath=> Documents
SET ExcelFile TO $'''%Documents%\\MicrosoftRewards.xlsx'''
**ENDREGION
**REGION スクレイピング
WebAutomation.LaunchEdge.LaunchEdge Url: $'''https://rewards.bing.com/redeem/orderhistory''' WindowState: WebAutomation.BrowserWindowState.Normal ClearCache: False ClearCookies: False WaitForPageToLoadTimeout: 60 Timeout: 60 BrowserInstance=> Browser
WebAutomation.ExtractData.ExtractHtmlTable BrowserInstance: Browser Control: $'''html > body > div:eq(0) > div:eq(1) > main > div:eq(1) > div:eq(1) > div:eq(1) > table''' ExtractionParameters: {[$'''状態''', $'''日付''', $'''リワード''', $'''ポイント''', $'''ポイント #1''', $'''ポイント #2'''], [$'''''', $'''''', $'''''', $'''''', $'''''', $''''''] } PostProcessData: False TimeoutInSeconds: 60 ExtractedData=> DataFromWebPage
WebAutomation.CloseWebBrowser BrowserInstance: Browser
**ENDREGION
Scripting.RunDotNetScript Language: System.DotNetActionLanguageType.CSharp Script: $'''dt.Columns.Remove(\"ポイント #1\");
dt.Columns.Remove(\"ポイント #2\");
var table = dt.Clone();
foreach (DataRow row in dt.Rows)
{
var s = row[\"リワード\"].ToString();
var position = s.IndexOf(\"注文番号\");
var rewards = s.Substring(0, position).Trim();
table.Rows.Add(row[\"状態\"], row[\"日付\"], rewards, row[\"ポイント\"]);
}
dt = table;''' @'name:dt': DataFromWebPage @'type:dt': $'''Datatable''' @'direction:dt': $'''InOut''' @dt=> DataFromWebPage
**REGION 出力
Excel.LaunchExcel.LaunchUnderExistingProcess Visible: True Instance=> ExcelInstance
Excel.WriteToExcel.WriteCell Instance: ExcelInstance Value: DataFromWebPage.ColumnHeadersRow Column: $'''A''' Row: 1
Excel.WriteToExcel.WriteCell Instance: ExcelInstance Value: DataFromWebPage Column: $'''A''' Row: 2
Excel.ResizeColumnsOrRows.AutofitAllColumns Instance: ExcelInstance
Excel.RenameWorksheet.RenameWorksheetWithIndex Instance: ExcelInstance Index: 1 NewName: $'''注文履歴'''
Excel.CloseExcel.CloseAndSaveAs Instance: ExcelInstance DocumentFormat: Excel.ExcelFormat.FromExtension DocumentPath: ExcelFile
WAIT (File.WaitForFile.Created File: ExcelFile)
**ENDREGION
@@copilotGeneratedAction: 'False'
Scripting.RunVBScript.RunVBScript VBScriptCode: $'''Option Explicit
Dim objExcel, objWorkbook, objSheet
Set objExcel = CreateObject(\"Excel.Application\")
objExcel.Application.Visible = False
Set objWorkbook = objExcel.Workbooks.Open(\"%ExcelFile%\")
Set objSheet = objWorkbook.Sheets(1)
Dim dataAll
Set dataAll = objSheet.UsedRange
dataAll.Borders.LineStyle = True
Const xlCenter = -4108
Const xlThemeColorAccent6 = 10
Dim header
Set header = dataAll.Resize(1)
With header
.HorizontalAlignment = xlCenter
.Interior.ThemeColor = xlThemeColorAccent6
.Interior.TintAndShade = 0.8
End With
objWorkbook.Save
objWorkbook.Close True
objExcel.Quit'''
END FUNCTION
おわりに
HTMLテーブル全体を抽出すると楽で良いですね。
余計な列を削除しようとしたら.NETスクリプトを使うのが良いかも。
あとはExcelを使って削除するとか。
Discussion