背景
Power Automate Desktop や RPA だと 定期的な Web Scraping を動かすのがだるい
ってことで、Power Automate でやれる方法を試行してみた記録
概要
詳細例
サイトを取得して OneDrive へ保存
- URL からファイルをアップロード でサイトを取得して OneDrive へ保存
- ファイル コンテンツの取得 で利用できるように取得しておく
HTML ページを XML 変換
HTML をそのまま xml() 関数で変換できるサイトなら、特に苦労なく使うだけ
今回は、以下のような問題があったので、正規表現や replace() を利用して、XML 化出来るように修正をした
課題と対処
- script や meta、コメントなど
-
<!-- Google Tag Manager (noscript) -->
- 正規表現で除外
-
- タグが閉じていない
- タグ自体を正規表現で除外
- タグ内属性で、"=" がないもの。 async, defer, etc.
-
<script src="/oo/np/lsync.js" async>
- replace() で除外
-
- 特殊文字
- ,  ,  , etc.
- replace() で除外
- ,  ,  , etc.
- 構成が壊れているもの
- 不要なら、正規表現で除外
- 必要なら、なんとかして閉じタグを追加 <今回はこれ
あとは、以下のようにして変換するのみ
xml
@{xml(outputs('Compose_div抜けの対処(追加)'))}
正規表現の使い方は、以下で
XML から XPATH で取得
あとは xpath で、欲しい場所を指定して取得してくるだけ
以下の例だと・・
- text() = "電気銅" となっている の親 の兄弟 に欲しい価格情報が順番に四点入っているので、以下のような xpath() で取得。sibling は便利
xpath
@{xpath(outputs('Compose_to_XML'), '//span[contains(text(),"電気銅")]/../following-sibling::td')}
取得結果はこんな感じになるので
あとは、以下で値を取得するのみ
- $content を取得
-
base64ToString でデコード
<td class="market-detail-list__value">1,110</td>
- タグを排除する
- substring(), indexof() で頑張ってやってるが、もっと良い方法が欲しい・・
- int() で数値への変換
欲しい値を取得@{int(substring(base64ToString(outputs('Compose_xpath')[0]['$content']), add(indexOf(base64ToString(outputs('Compose_xpath')[0]['$content']), '">'), 2), sub(length(base64ToString(outputs('Compose_xpath')[0]['$content'])), add(5, add(indexOf(base64ToString(outputs('Compose_xpath')[0]['$content']), '">'), 2)))))}
あとがき
xml/xpath で Web スクレイピングが出来た
PAD や PRA, Selenium などと比較すると、取得自体へ面倒だけど、環境準備とか不要ってのがいい
最新データを定期取得して通知する程度ならこれでもいいんじゃね?と
keyword
web scraping in Power Automate by xml and xpath functions