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

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

VBAプログラム開発、スクレイピング・詳細データ取得拡張【3】未取得書籍のみデータ取得する

今回作成しているのVBA処理の一つに「書籍情報を取得してワークシートへ一覧表示」というものがありました。

Web上に登録されている書籍情報の詳細ページへアクセスして、その内容をワークシートへ集約できるものです。

しかし、現状のままでは使いにくい点があるので、改修していきます。

今回の目的

書籍情報詳細を取得しワークシート表示時に取得済みデータを除外できるようにする

なぜやるか

新たに追加されたデータのみを反映出来るようにするため

やりたいこと

  • ワークシートへ取得済みの書籍情報を認識させる
  • 取得済み書籍情報は取得しないようにする
  • 新たに取得した書籍情報を既存データの続きに表示させる

やったこと

  • 現状の書籍取得手順を確認する
  • 追加書籍判定方法を検討する
  • ワークシート上の書籍情報を取得する
  • Web書籍情報から新規書籍を判定する
  • ワークシート上の書籍情報の続きに反映させる

実施内容

現状の書籍取得手順を確認する

書籍情報取得はできている

冒頭どおり、書籍情報の詳細情報を取得してワークシートへ反映するVBAは作成できています。

しかし、このVBAは全書籍データを取得してワークシートへ出力できるようにしています。

初回のデータ取得はこれで問題ないのですが、2回目以降に問題が発生してきます。

毎回同じ処理が行われる

全データ取得して反映となるので、全てのデータが上書されています。

結果として同じテキストであれば、見た目は変わりませんが画像オブジェクトが同じ位置にどんどん追加されます。

そしてなにより、ワークシートに取得済みのデータをWeb上からすべてダウンロードして上書するという手間がかかっています。

取得済みデータは対象外としたい 

ワークシートにあるデータは取得対象外にできれば、利点があります。

  • 必要データだけが追加できる。
  • 不要データはダウンロードの必要がなくなる。

追加書籍判定方法を検討する

では、どうやってこの処理を追加していくのかを考えます。

ワークシート上の書籍情報を取得

まずは、現状のワークシートにある書籍情報が必要です。

f:id:Fippiy:20190624144544j:plain

書籍情報一覧ワークシート

そして何を比較に使うか?

書籍固有情報としてIDがあり、書籍一覧にもIDを反映させているので、IDによる比較ができれば、判定できそうです。

ワークシートIDとWebIDを比較

Webからの書籍情報取得は、まず書籍一覧ページから書籍詳細URLを取得していました。

URLは書籍IDが含まれているので、この段階でワークシートIDとWebID比較が実施できれば、ワークシートにない書籍だけを選別してURLを取得できそうです。

ここで結果として追加すべき書籍だけが取得できれば、残りの処理はほぼそのまま使えます。

追加書籍反映

新規追加書籍反映は、既存データの続きに反映させます。

今まではワークシート上の先頭から追加していたので、変更しておく必要が有ります。

これには、ワークシート上のID取得を最初に行うので、この時に位置情報を取得しておけば、データ反映時に指定できそうです。

 

VBAコードを修正する

ワークシート上の書籍情報を取得する

まず、Web情報取得前にワークシート側の書籍情報を準備しておきます。

# 書籍情報取得VBA(ワークシート情報取得)

'ワークシート書籍情報取得
MaxRow = SWSheet.Cells(Rows.Count, 1).End(xlUp).Row 'ワークシート要素の最終セル
Set books = SWSheet.Range(Cells(2, 1), Cells(MaxRow, 1)) 'ワークシートID一覧取得
arrBooksId = books '配列化

ワークシート上の連続データの最終セル情報を取得し、2列目から最終列のID情報を取得します。

そして取得データを配列化しておくことで、WebIDとの比較時に扱える様にしておきます。

Web書籍情報から新規書籍を判定する

次は、詳細書籍ページURLを取得する処理を変更します。

この処理は書籍リスト取得専用のプロシージャとして作成していました。

# 詳細ページURL取得プロシージャ

Sub getBookList(htmlDoc As HTMLDocument, i As Integer, URLCol As Collection, _

 Login As BookdataLogin, arrBooksId As Variant)

 '詳細ページURLを取得
 Dim Bookdata As HTMLDivElement 'レコード単位データ
 Dim detailField As HTMLDivElement '詳細フィールドデータ
 Dim BookdataURL As String '詳細ページURL
 Dim BookdataURLDir As String '詳細ページディレクト
 Dim checkId As Variant '書籍ID
 Dim checkIdFlag As Boolean '書籍有無
 checkIdFlag = False

 'URLからID取得
 Dim getIdData As Variant
 Dim getIdElement As Long
 Dim getBookdataId As Long

 For Each Bookdata In htmlDoc.getElementsByClassName("book-table__list")

  '--detail情報からデータ取得

   '--detailを取得
   Set detailField = Bookdata.getElementsByClassName("book-table__list--detail")(0)

   '詳細ページURL
   BookdataURL = detailField.getElementsByTagName("a")(0) 'URL取得
   BookdataURLDir = Replace(BookdataURL, Login.Domain, "") 'ディレクトリ取得

   'ディレクトリからID取得
   getIdData = Split(BookdataURLDir, "/") 'URL要素取得
   getIdElement = UBound(getIdData) 'URL要素確認
   getBookdataId = getIdData(getIdElement) 'URLから番号取得

   'arrBooksIdにある場合は書籍があるので除外
   For Each checkId In arrBooksId
    If checkId = getBookdataId Then
     checkIdFlag = True
     Exit For
    End If
   Next checkId

   If checkIdFlag = False Then URLCol.Add BookdataURLDir
   checkIdFlag = False
  '--detail情報からデータ取得ここまで

  '列番号処理
  i = i + 1
 Next Bookdata

End Sub

URLを取得して、コレクション要素へ追加していました。

この追加時に、先程の配列と比較をすることで書籍が既にワークシート上にあるのか判定するようにしました。

判定結果として、ワークシートに書籍がない時は追加する必要があるので、URLをコレクションへ追加するという処理に変更しました。

 

ワークシート上の書籍情報の続きに反映させる

追加する書籍だけのURLを取得した後は、ワークシート上の書籍データの続きに追加します。

# 書籍情報取得VBA(詳細ページURL取得後)

'詳細ページURLがなければ終了する
If URLCol.Count > 0 Then
 Call getDetailBookdata(SWSheet, waitObjIE.objIE, URLCol, Login, MaxRow)
 ExitMsg = "データ取得が完了しました。"
Else
 ExitMsg = "取得データがありません"
 ExitMsg = "新規取得データはありませんでした"
End If


'VBA終了処理
waitObjIE.objIE.Quit 'objIEを終了させる
MsgBox ExitMsg

URLから詳細情報を取得する処理はgetDetailBookdata()とプロシージャ化していました。

この処理にワークシートの書籍データの続きが指定できれば、必要なデータだけが追加できます。

そこで、初めにワークシートから書籍情報を取得したセルの位置情報を利用します。

 

以上で、Webにしかない書籍をワークシートの続きへ追加できるようになりました。

最後に、処理完了後のメッセージが現状に即していない状態となっているので修正して完了です。