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

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

VBAプログラム開発、スクレイピング【3】表示ページの対象データを取得する

前回記事にて1件のデータ取得から表示全データを取得しました。

しかし、まだタイトル名のみを取得していたので、今回は他のデータも取得してExcelの表示まとめます。

今回の目的

一覧表示データをさらに取得し、情報をExcelシートにまとめる

なぜやるか

現在はタイトル名しか取得できていないので、関連情報もまとめて取得しweb上のデータをExcelに取り込んで管理できるようにするため

やりたいこと

  • 本の詳細テキストを取得する
  • 詳細ページURLを取得する

やったこと

実施内容

取得する情報を整理する

書籍情報の一覧表示を改めて確認します。

f:id:Fippiy:20190606134732j:plain

book一覧表示

book.indexにて一覧表示しているデータは以下の通りです。

取得済みデータ

  • タイトル名 

残っているデータ

  • 詳細説明

  • 詳細ページURL(リンク)
  • 本の画像 

現在のところ、タイトル名のみを取得していました。

他の情報も取得してExcelファイル上で管理出来るようにしていきます。

f:id:Fippiy:20190606141340j:plain

情報を追加

 

 

詳細説明を取得

本の詳細情報が記載されている場合はタイトル名の下にテキスト表示されているので、こちらをスクレイピングによって取得します。

タイトル名と取得方法は同じで、詳細情報を記載している位置を指定すれば取得できます。

# book.index(HTML)

<div class="book-table__list">
 <div class="book-table__list--checkbox">
  <input type="checkbox" name="select_books" value="8">
 </div>
 <div class="book-table__list--picture">
  <a href="/book/8">
   <img src="~/9784797398892.jpg">
  </a>
 </div>
 <div class="book-table__list--detail">
  <a href="/book/8">

   <h3 class="list-book-title">

    1冊ですべて身につくHTML &amp; CSSとWebデザイン入門講座

   </h3>

  </a>
  <p class="list-book-detail">

   日本で2年間グラフィックデザイナーとして...

  </p>
 </div>
</div>

pタグに"list-book-detail"として詳細情報が出力されているので、こちらを指定します。

# スクレイピングVBA

i = 1
For Each Str In htmlDoc.getElementsByClassName("list-book-detail")
 Worksheets("スクレイピング").Cells(i + 1, 3).Value = Str.innerHTML
 i = i + 1
Next Str

VBAコード内でタイトル名取得後に、"list-book-detail"クラスを指定してExcel内の3列目に書き出しました。

f:id:Fippiy:20190606141235j:plain

詳細情報取得

取得クラス名が変更になっただけなので、ここはすんなりと取得できました。

 

 

リンクを取得

次は、書籍詳細ページへのURLを取得します。

書籍一覧表示の中でリンクをクリックすると、より詳細な情報を表示するページに遷移します。 

f:id:Fippiy:20190606144315j:plain

詳細ページ

今回は、リンクとして設定しているURLを取得しExcelファイル上に追記していきます。

 

URLを参照する

まずは、リンク情報がどこにあるかを確認します。 

# book.index(HTML)

<div class="book-table__list">
 <div class="book-table__list--checkbox">
  <input type="checkbox" name="select_books" value="8">
 </div>
 <div class="book-table__list--picture">
  <a href="/book/8">
   <img src="~/9784797398892.jpg">
  </a>
 </div>
 <div class="book-table__list--detail">
  <a href="/book/8">

   <h3 class="list-book-title">

    1冊ですべて身につくHTML &amp; CSSとWebデザイン入門講座

   </h3>

  </a>
  <p class="list-book-detail">

   日本で2年間グラフィックデザイナーとして...

  </p>
 </div>
</div>

リンク先はaタグを利用してhrefでURLを指定しています。

 

URLにクラス名がない

しかし、今回は今までの手順では取得できません。

まず、aタグに対してクラス名を設定していないので、クラス名だけでは取得するのは難しそうです。それに加えて、同じリンク先のaタグが2つあります。

一覧表示からのリンクは、画像とタイトル名に対してリンクを作成して、詳細ページに移動できるように作成していました。詳細テキストに対してはリンクを設定していません。

このため、どちらのリンクからでも詳細ページに移動できるようにするため、リンクを2箇所設定していました。

 

URL取得方法を検討する

では、どうやってURLを取得するか?

取得元を「タイトル名に指定しているURL」と決めてスクレイピングすることにしました。

# book.index(HTML)

<div class="book-table__list--detail">
 <a href="/book/8">

  <h3 class="list-book-title">

   1冊ですべて身につくHTML &amp; CSSとWebデザイン入門講座

  </h3>

 </a>
 <p class="list-book-detail">

  日本で2年間グラフィックデザイナーとして...

 </p>
</div>

"book-table__list--detail"このクラス名の情報を取得し、この中からaタグを指定してURLを取得します。

 

スクレイピングしてURLを取得する 

# スクレイピングVBA

i = 1

Dim GetUrl As String

For Each Str In htmlDoc.getElementsByClassName("book-table__list--detail")
 GetUrl = Str.getElementsByTagName("a") 'URL取得
 Worksheets("スクレイピング").Cells(i + 1, 4).Value = GetUrl '取得URL反映
 i = i + 1 '次の行指定
 Next Str

 

detailの情報をまず取得します。ここまではクラス名指定によるスクレイピングデータなので、今までとは同じ方法を使っています。

そこから、取得したStr毎にタグ名を指定した要素を取得します。.getElementsByTagName("a")としてaタグの情報を取得しました。

データさえ取得できれば、後はExcelシートへ書き出せば完了です。4行目にURL欄を設けていたので、4行目を指定して書き出してやればデータ表示できそうです。

 

f:id:Fippiy:20190606141018j:plain

URL取得

各書籍の詳細ページ向けのURLを取得しました。

ここまで取得できれば、一覧表示サイトにアクセスせずに取得したデータから直接詳細ページまで確認に行くこともできそうです。

 

bookIDを取得

今回のサイトでは詳細ページはbookdataのIDを指定してリンクを貼っているので、リンクからID名が判別できるので、これを左側に番号ではなくIDとして表示させてみる

f:id:Fippiy:20190606141401j:plain

URLの数値をIDとして左側へ反映

今までA列に番号として、通し番号を設定していましたが、URLにDBのIDが反映されているので、これを利用して番号ではなく、ID表示に変更させる。

 

# スクレイピングVBA

i = 1
Dim GetUrl As String
Dim GetUrlData() As String
Dim GetUrlElement As Integer
Dim GetID As Integer

For Each Str In htmlDoc.getElementsByClassName("book-table__list--detail")
 GetUrl = Str.getElementsByTagName("a") 'URL取得
 Worksheets("スクレイピング").Cells(i + 1, 4).Value = GetUrl '取得URL反映


 GetUrlData = Split(GetUrl, "/") '1.URL要素取得
 GetUrlElement = UBound(GetUrlData) '2.URL要素確認
 GetID = GetUrlData(GetUrlElement) '3.URLから番号取得
 Worksheets("スクレイピング").Cells(i + 1, 1).Value = GetID '4.ワークシートへ反映


 i = i + 1 '次の行指定
Next Str

先程のURLを取得した後にID番号を取得するコードを追加しました。

 

1.URL要素取得

取得したURLをSplitを利用して"/"で分割することで、複数の要素として再取得するようにしました。

こうすることで、GetUrlDataに分割したテキストが配列として格納されます。

GetUrlDataは配列となるので、Dim宣言時にGetUrlData()として配列形式にしています。

※配列として宣言していなかったので、結果的にここでつまっていました。

 

2.URL要素確認

配列に対してUBound()とすることで、配列要素の数が返り値として取得できます。今回、欲しいデータはURLの一番最後に表示されるIDとなる数値なので、UBoundの値を指定することで、一番最後のテキストが取得できるようになります。

 

3.URLから番号取得

URLから要素を配列として取得し、IDを取得するための位置も確認がとれたので、配列内の一番最後の要素を取得します。これによってURLから書籍のIDを取得することができました。

 

4.ワークシートへ反映

取得したIDをExcelの1列目に反映してやれば、通し番号からIDへの書き換えは完了です。通し番号を設定していたコードは不要になるので、削除しておきます。

 

これで番号のみを1行目に反映させることで、番号順ではなく、書籍管理サイトからID番号毎にデータが取得できるようになりました。

f:id:Fippiy:20190606141850j:plain

サイト上リストをID毎にレコードとして取得

ウェブページにあった情報がExcel上にデータとして取得できるようになりました。

 

後は書籍の画像を表示できれば一覧表示からのデータ取得は全て出来るようになります。

画像処理については次回の記事で作成予定です。