- はじめに
Fetch APIを使ったサイレントダウンロードの続きです。
AI困惑、(レガシーな)業務システムや、動的にPDFを生成するWebシステムでは、教科書通りにいかない事が多いようです。参考事例に成れば。(と言っても、忘れっぽい私の忘却禄程度ですが)
最初は、有るはず要素に拘って色々検討したAIさん。
' embedタグのsrc属性(絶対URL)を返すJS
getPdfUrlJs = "var el = document.querySelector('embed[type=''application/pdf'']'); return el ? el.src : '';"
なぞ1:消えた type="application/pdf"
例えば、業務システムが動的生成する以下のようなHTML画面に遭遇したとします。
<!DOCTYPE html>
<html lang="ja">
<head>
<TITLE>PDF PREVIEW</TITLE>
<!-- 中略 -->
</head>
<body id="pdfbodyarea">
<div id="pdfarea" class="pdfareastyle">
<!-- ! type="application/pdf" が存在しない -->
<embed class="pdfareastyle" src="http://WIN-**/NS**prt/pdf/N99xx-2026072113574928.pdf">
</div>
</body>
</html>
ここで、 embed[type="application/pdf"] という厳密なCSSセレクタで待機しようとすると、属性が存在しないためタイムアウト・エラーになってしまいます。
(ブラウザはHTTPレスポンスヘッダを見て自動的にPDFだと推測し、HTML上には情報がないケースが多々あるようです。)
この場合、セレクタを緩めて embed や embed[src*=".pdf"] としてターゲットを捕捉する柔軟性が求められます。
なぞ2:相対パスと絶対パス
ターゲット(embed要素)を見つけても、まだ動きません。
要素の src 属性を取得した際、http://~ という絶対URLではなく、/NS01prt/pdf/xxxx.pdf のような「相対パス」が格納されていた。このままダウンロード処理(Fetch API)に渡しても「どのサーバーへのリクエストか分からない」とまたエラー!!。
解決:JavaScriptを使って「どんな形であれ、必ず絶対URL(http://~)に変換して抽出する」
// PDFのURLを安全かつ確実に取得するJS
var el = document.querySelector('embed');
if (!el) return '';
try {
// 相対パスを絶対URLに確実変換する魔法のコード
return new URL(el.getAttribute('src') || el.src, location.href).href;
} catch(e) {
// 万が一の予備ルート
return el.getAttribute('src') || el.src || '';
}
実体URLさえ確実に取得できれば、Invoke-WebFetchDownload の出番です。
Dim savePath As String
Dim actualPdfUrl As String
savePath = "C:\Desktop\テストデータ\DummyPDF_20260722.pdf"
' 1. ダウンロードの事前予約
rpaEngine.RunAction "Enable-SilentDownload", CreateParams("DownloadDirectory", "C:\Desktop\テストデータ", "FileName", "DummyPDF_20260722.pdf")
' 2. PDF画面へ遷移&待機
rpaEngine.RunAction "Invoke-WebNavigation", CreateParams("Url", "https://.../preview")
rpaEngine.RunAction "Wait-WebElement", CreateParams("Selector", "embed", "TimeoutSec", 15)
' 3. PDFの実体URL(絶対パス)を取得
actualPdfUrl = rpaEngine.RunAction("Get-WebEmbedPdfUrl")
' 4. URLを指定してFetchダウンロード発火
rpaEngine.RunAction "Invoke-WebFetchDownload", CreateParams("TargetUrl", actualPdfUrl)
' 5. ダウンロード完了待機
rpaEngine.RunAction "Wait-FileDownload", CreateParams("FilePath", savePath, "TimeoutSec", 30)
' 6. PDF画面を閉じる
後処理:不要になったPDF画面を美しく閉じる
ダウンロードが完了した後は、不要になったPDFのプレビュー画面を片付けます。
システムの仕様(別タブで開くか、同じ画面で遷移するか)に合わせて、以下のコマンドで元の画面に復帰させます。
パターン1:別ウィンドウ(新しいタブ)でPDFが開いている場合
' JavaScript経由で画面を閉じる(エンジン側でゴーストタブも自動破棄されます)
rpaEngine.RunAction "Invoke-WebScript", CreateParams("Js", "window.close();")
Sleep 1000 ' 親画面へのフォーカス復帰待機
パターン2:同じ画面内でPDFに遷移している場合
' JavaScript経由でブラウザの「戻る」を実行
rpaEngine.RunAction "Invoke-WebScript", CreateParams("Js", "window.history.back();")
rpaEngine.RunAction "Wait-WebPageLoad"
と、今回も、Get-WebEmbedPdfUrl を追加しました。