Fippiyのプログラム学習内容アウトプットBlog

日々の学習内容をアウトプットして振り返りを実施する。

VBAプログラム開発、スクレイピング・詳細データ取得拡張【1-4】書籍情報登録結果を取得して表示する

ISBNコードによる複数書籍登録をExcelVBAにて処理できるようになりました。しかし、登録結果はWeb上で表示されるのみであり、Web画面を消すと履歴としては残らないので、登録処理開始時にExcelワークシートへ記載したISBNコードに対して、処理結果を反映出来るようにしていきます。

今回の目的

 書籍登録VBAに処理結果表示機能を追加する

なぜやるか

書籍追加のみで処理結果が不明になるため、結果が分かるように一覧表示化を行う

やりたいこと

  • Web登録結果を取得する 

やったこと

  • 取得するデータを特定する
  • 処理結果を表示する欄を設ける
  • データが取得できることを確認する
  • 全データを取得できるようにする
  • 書籍タイトルもあわせて取得する 

実施内容

取得データを特定する

結果表示画面を確認する

まずは書籍登録後の画面を確認します。

f:id:Fippiy:20190625105745j:plain

Web登録結果

複数書籍ISBNコード登録画面で登録ボタン押下後の画面です。

ここから、処理結果テキストを取得してワークシートに反映させます。

 

取得データの場所を確認する

結果表示画面のHTMLからデータ取得するクラスを確認します。 

# 登録結果HTML(抜粋)

<div class="index-content">
 <div class="books-list">
  <div class="books-list__title bookpage-color">
   ISBNコード登録結果
  </div>

  <div class="isbn-result">
   <div class="isbn-result__box">
    <div class="isbn-result__box--number">1</div>
    <div class="isbn-result__box--detail">
     <div class="isbn-result__box--head">
      <span class="isbn-result__box--isbn">9784862554963</span>
      <span class="isbn-result__box--msg">登録しました</span>
     </div>
     <div class="isbn-result__box--bottom">
      <div class="isbn-result__box--image">
       <img src="https://cover.openbd.jp/9784862554963.jpg">
      </div>
      <div class="isbn-result__box--title">

       キレッキレ股関節でパフォーマンスは上がる!

      </div>
     </div>
    </div>
   </div>
   <div class="isbn-result__box">

    ~ 省略 ~
   </div>
  </div>
 </div>

</div>

div class="isbn-result"クラス内にレコード単位の結果として、div class="isbn-result__box"を生成し、この中に結果を出力する内容となっています。

この中に結果テキストが出力されているので、これを取得してワークシートで指定したISBNコードの隣に結果を反映できるようにします。

f:id:Fippiy:20190626103503j:plain

結果表示イメージ

 

書籍登録結果のデータを取得する

登録ボタン押下後の画面表示待機を実装する

HTML表示で確認したクラスを指定して、データが取得できることを確認します。

# ISBN複数登録プロシージャ(ISBNコード登録処理から)

'フォーム入力
htmlDoc.getElementsByClassName("form-input__detail")(0).Value = EntryISBN
htmlDoc.getElementsByClassName("send isbn")(0).Click

 

 'フォーム入力後の操作検証
 Call WaitResponse(objIE) '読み込み待ち
 Set htmlDoc = objIE.document 'objIEで読み込まれているHTMLドキュメントをセット
 Debug.Print htmlDoc.getElementsByClassName("isbn-result__box--isbn")(0).innerText
 Debug.Print htmlDoc.getElementsByClassName("isbn-result__box--msg")(0).innerText


'VBA終了処理
objIE.Quit 'objIEを終了させる
ExitMsg = "登録処理が完了しました。"
MsgBox ExitMsg

以前作成したISBNコード登録は、登録ボタンをクリック後、終了処理をしてVBAは終わっていました。

今回は、この間にIE読み込み終了後にオブジェクトを取得してデータを取得できるようにしました。

登録ボタンクリック後は読み込み状態となって結果出力を待つ状態となるので、そのまま読み込み待ちを適用することで問題なく動作しました。

 

結果画面のテキスト取得を確認する

先程のVBAコードで結果を確認します。まずはデータ取得が目的なので、1件目のみをイミディエイトに出力して確認します。

f:id:Fippiy:20190626105306j:plain

結果テキスト取得

登録済みの書籍を再度登録する形で試していたので、「登録されています」と出力されていますが、対象のISBNコードと結果テキストが取得できています。

 

複数件取得対応する

データ取得できることが確認できたので、後はこれを登録全データに対応させます。

ForEachで取得要素毎に処理できるようにします。

# ISBN複数登録プロシージャ(データ取得)

'フォーム結果HTML取得
Call WaitResponse(objIE) '読み込み待ち
Set htmlDoc = objIE.document 'objIEで読み込まれているHTMLドキュメントをセット

'結果取得
Dim ResultISBN As HTMLDivElement
i = 2


For Each ResultISBN In htmlDoc.getElementsByClassName("isbn-result__box--msg")
 ISSheet.Cells(i, 3).Value = ResultISBN.innerText
 i = i + 1
Next ResultISBN

結果テキストが格納されている"isbn-result__box--msg"クラスを指定して全メッセージを取得するようにしました。

取得したデータをワークシート上へ返すようにすることで、ワークシート上で結果が分かるようにします。

f:id:Fippiy:20190626140501j:plain

複数結果取得

 複数書籍に対しての結果が取得できました。

 

正常動作をさらに確認するために、対象の書籍を一度削除した上で再度登録処理をしてメッセージが出力されることを確認します。

f:id:Fippiy:20190626141425j:plain

登録結果

登録できた旨のメッセージが表示されました。

 

書籍タイトルも表示させる

登録しましただけでは何が登録されたかが分からない

結果の出力としてはこれで完成なのですが、きっちり登録できた場合はタイトル名も出力できるようにしていきます。

Web上の結果出力を改めて確認しておきます。

f:id:Fippiy:20190625105745j:plain

登録結果Web

正常登録時はISBNコードと"登録しました"というテキスト、そしてタイトル名が表示されます。

f:id:Fippiy:20190626142030j:plain

登録結果Web

登録済みの場合はタイトル名は表示されません。すでに登録されていることを確認して結果を返しています。

これは、APIによる書籍データ取得前にDBに登録済みかを確認し、登録されていれば無駄なAPI通信をしないようにする処理となっています。DBからタイトル名を直接表示させてもいいのですが、今回はこのような仕様で作成していました。

 

この為、正常登録した場合のみタイトル名が表示されるという仕様に対応できるVBAコードを作成する必要があります。

 

レコード単位で処理できるようにする

タイトル名有無で要素情報がずれると困るので、書籍情報取得のようにレコード単位で取得する方法でコードを記述できるように変更していきます。

# ISBN複数登録プロシージャ(データ取得)

'フォーム結果HTML取得
Call WaitResponse(objIE) '読み込み待ち
Set htmlDoc = objIE.document 'objIEで読み込まれているHTMLドキュメントをセット

'フォーム処理結果取得
Call getISBNAnswers(htmlDoc, ISSheet)

 

'VBA終了処理
objIE.Quit 'objIEを終了させる
ExitMsg = "登録処理が完了しました。"
MsgBox ExitMsg

フォーム結果を取得するプロシージャは分けて処理することにしました。

# ISBN登録結果処理

Sub getISBNAnswers(htmlDoc As HTMLDocument, ISSheet As Worksheet)

 '結果処理変数
 Dim ResultRecord As HTMLDivElement 'Record単位データ
 Dim ResultTitle As HTMLDivElement 'タイトル名
 Dim ResultText As HTMLDivElement '結果テキスト
 Dim i As Long
 i = 2

 For Each ResultRecord In htmlDoc.getElementsByClassName("isbn-result__box")
  Set ResultText = ResultRecord.getElementsByClassName("isbn-result__box--msg")(0)
  Set ResultTitle = ResultRecord.getElementsByClassName("isbn-result__box--title")(0)
  ISSheet.Cells(i, 4).Value = ResultText.innerText

  If (ResultTitle Is Nothing) = False Then
   ISSheet.Cells(i, 3).Value = ResultTitle.innerText
  End If

 i = i + 1
 Next ResultRecord

End Sub

"isbn-result__box"というクラスを指定しています、これがレコード単位データの取得として扱えるクラスだったので、レコード単位でのデータ取得を実現しています。

そしてこの中から処理結果テキストと、新規書籍登録の場合のみタイトル名を取得できるようにしました。

 

登録処理を実施して結果を確認します。 

f:id:Fippiy:20190626145101j:plain

書籍タイトル取得

書籍タイトルと登録結果が出力できるようになりました。

 

以上で複数書籍登録結果をワークシートへ反映することで、VBAにてISBNコードを指定してWebデータ登録ができるようになりました。