SeleniumeBasicでPDFをハンドル usage_pdf

リファレンス

 PDFファイルのハンドル例です。構文のメイン内容がほぼJavaScriptの構文で占められていますので、SeleniumBasicの基本構文はあまり出てきません。Examplesでは3例あったのですが、実行に成功できた2例を紹介します。

  • 利用目的は業務効率化です。(テスト自動化ではありません)
  • ブラウザはGoogleChromeが対象です。(EdgeやFirefoxは対象外)
  • 原文のVBAでは現在エラー発生する場合が多いため、修正を加えてます。
Examples.xlsmの保存場所(ここをクリック)

 Examples.xlsmが保存されている場所は、SeleniumBasicがインストールされているサブフォルダ内になります。SeleniumBasicのインストール完了時に保存フォルダを確認することができます。ただ、大体以下フォルダのどちらかにファイル保存されています。

  • C:\Program Files\Seleniumbasic\Examples\Excel
  • shell:Local AppData\SeleniumBasic\Examples\Excel
目次

PDFデータのレンダリング

 PDFデータをレンダリングして、Web要素を取得できる様にする構文になります。
 レンダリングの概念については、以下ページを参照してみてください。

リモートデバッグモードでChrome起動

 PDFデータを扱う上で今回、Chromeの拡張機能を利用します。SeleniumBasicでChrome拡張利用するに当たって、今回はリモートデバッグモードを利用します。リモートデバッグモードの利用方法は、以下ページを参照ください。

PDF Viewer(PDF.js)のインストール、有効化

 リモートデバッグモードで起動したChromeでChromeウェブストアを開き、PDF Viewerの拡張機能を付加します。

STEP
検索ボックスに"pdf,js"を入力し、検索実行します
STEP
PDF Viewer(PDF.js)をクリックします
STEP
「Chromeに追加」をクリック
STEP
「拡張機能を追加」をクリック

SeleniumBasic実行

 では、SleniumBasicの構文を紹介します。リモートデバッグモードでChromeを起動した状態で、以下構文を実行します。

Private Sub Handle_PDF()
Const JS_WAIT_PDF_RENDERED As String = _
    "(function fn(){" & _
    "  var pdf=PDFViewerApplication.pdfViewer;" & _
    "  if(pdf && pdf.onePageRendered){ " & _
    "    pdf.onePageRendered.then(callback);" & _
    "  }else{" & _
    "    window.setTimeout(fn,60);" & _
    "  }" & _
    "})();"

    Dim driver As New ChromeDriver, Assert As New Assert
    driver.SetCapability "debuggerAddress", "127.0.0.1:9222"
    driver.Get "https://static.mozilla.com/moco/en-US/pdf/mozilla_privacypolicy.pdf"
    driver.ExecuteAsyncScript JS_WAIT_PDF_RENDERED
    Dim firstline As String
    firstline = driver.FindElementByCss("#viewer > div:nth-child(1) > div.textLayer > span:nth-child(1)").Text
    Assert.Equals "Websites Privacy Policy", firstline
    Stop
    driver.Quit
End Sub

2~10行目:JavaScript構文の設定
13行目:リモートデバッグモードの設定
14行目:PDFデータのサイトをゲット
15行目:JavaScript構文の実行(非同期処理)
16、17行目:PDFデータ表題のWeb要素をFindElementByCssで取得
18行目:Assertで取得内容が合致しているか確認

 VBA構文の15行目にあるJavaScript構文を実行しなければ、17行目のFindElementByCssでWeb要素をキャッチできずエラーが発生します。

JavaScript構文紹介

JavaScript構文を以下に紹介します。

(function fn(){  
    var pdf=PDFViewerApplication.pdfViewer;  
    if(pdf && pdf.onePageRendered){
        pdf.onePageRendered.then(callback);  
    }else{
        window.setTimeout(fn,60);  
    }
})();

PDFデータのテキスト取得

 SeleniumBasicでGetしたPDFデータをJavaScriptで要素取得し、PDFデータの1ページ目の文字列をイミディエイトウィンドウに出力します。前段と同様、Chromeはリモートデバッグモードで起動しておきます。

Private Sub Handle_PDF_advanced()
Const JS_READ_PDF As String = _
    "(function fn(){" & _
    "  var pdf=PDFViewerApplication.pdfViewer;" & _
    "  if(pdf && pdf.onePageRendered){ " & _
    "    pdf.onePageRendered.then(function(){" & _
    "      var pdftxt=[],cnt=pdf.pagesCount,cpt=cnt;" & _
    "      for(var p=1; p<=cnt; p++){" & _
    "        pdf.pdfDocument.getPage(p).then(function(page){" & _
    "          page.getTextContent().then(function(content){" & _
    "            var lines=[], items=content.items;" & _
    "            for(var i=0, len=items.length; i<len; i++)" & _
    "              lines.push(items[i].str);" & _
    "            pdftxt[page.pageIndex]=lines.join();" & _
    "            if(--cpt < 1) callback(pdftxt);" & _
    "          });" & _
    "        });" & _
    "      }" & _
    "    });" & _
    "  }else{" & _
    "    setTimeout(fn, 60);" & _
    "  }" & _
    "})();"

    Dim driver As New ChromeDriver
    driver.SetCapability "debuggerAddress", "127.0.0.1:9222"
    driver.Get "https://static.mozilla.com/moco/en-US/pdf/mozilla_privacypolicy.pdf"
    Set pdfPages = driver.ExecuteAsyncScript(JS_READ_PDF)
    Debug.Print pdfPages(1)
    driver.Quit
End Sub

2~23行目:JavaScript構文の設定
26行目:リモートデバッグモードの設定
27行目:PDFデータのサイトをゲット
28行目:JavaScript構文の実行
29行目:PDFデータ1ページの文字列をイミディエイトウィンドウに出力します。

JavaScript構文を以下に紹介します。

(function fn(){
    var pdf=PDFViewerApplication.pdfViewer;
    if(pdf && pdf.onePageRendered){
        pdf.onePageRendered.then(function(){
            var pdftxt=[],cnt=pdf.pagesCount,cpt=cnt;
            for(var p=1; p<=cnt; p++){
                pdf.pdfDocument.getPage(p).then(function(page){
                    page.getTextContent().then(function(content){
                        var lines=[], items=content.items;
                        for(var i=0, len=items.length; i<len; i++)lines.push(items[i].str);
                        pdftxt[page.pageIndex]=lines.join();
                        if(--cpt < 1) callback(pdftxt);
                    });
                });
            }
        });
    }else{
        setTimeout(fn, 60);
    }
})();
よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

VBAを中心とした自動化、効率化の手法を紹介しています。現在は、SeleniumBasicのexamplesを紹介しています。その内、SeleniumBasic以外の手法も掲載したいと思っております。

目次