本投稿では、ニーズプラットフォームに寄せられたニーズの解決事例を紹介します。
ニーズの内容
ウェブスクレイピングのやり方を教えてほしい!
ウェブスクレイピングについて
ウェブスクレイピングとは?
インターネット上から、自動的に必要な情報を抽出する作業を指します。
特徴
- インターネットに溢れている情報から必要な情報のみを抽出し組み合わせることで、自分専用の新しいデータベースを作成することができる。
- ホームページの内容をコピペするような業務があれば、ウェブスクレイピングを導入することにより時間短縮 & 転記ミスの防止につながる。
注意点
ウェブスクレイピングの実施が違法となるケースがあります。
- Webサイトの利用規約
- サーバへの負荷
- 著作権
といった点が争点になりますので、どのようなケースが違法になるのか事前確認をオススメします。ウェブスクレイピングの注意点については、下記の記事を参考にしました。
違法とされる基準には曖昧な部分があります。各々がウェブスクレイピングを実施する上で注意すべき点を理解し、どのように実施すれば問題ないか考えるようにしましょう!
プログラム動作内容
「京のまち企業訪問」のホームページにアクセスし、登録されている企業をリストでExcelファイルに出力する内容。
情報収集を行うにあたり、ホームページの利用規約は事前に確認しておきましょう。
第5条(利用者の禁止事項)に「5. 本サイトを利用しての営利を目的とした情報提供・収集等の行為」とあるため、本プログラムにより収集した情報を営利目的で使用することは利用規約に抵触します。
本記事ではあくまでウェブスクレイピング方法の紹介の題材として本ウェブサイトを利用させていただいているため、本プログラムにより収集した情報は学習の範囲での利用をお願いします。
プログラム紹介
実行結果とソースコード
上記のような出力結果がExcelファイルのシートに出力されるプログラムです。1行目にリストを作った状態でプログラムを実行し、2行目以降に結果が出力されるようにします。
Option Explicit
Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Sub get_list()
'ポイント(1) InternetExplorerオブジェクトの生成
Dim objIE As InternetExplorer
Set objIE = New InternetExplorer
'ポイント(2) 京のまち企業訪問ホームページを開く
objIE.Visible = True
objIE.Navigate "https://www5.city.kyoto.jp/kigyo/kg_102.cgi?CT=20&PN=1"
'ポイント(3) ページが進む前に次の動作が始まるのを防ぐ
Do While objIE.Busy = True Or objIE.readyState < READYSTATE_COMPLETE
DoEvents
Loop
'HTMLDocumentオブジェクトの生成
Dim htmlDoc As HTMLDocument
Set htmlDoc = objIE.document
'ポイント(4) Excelシートの行数を格納する変数
Dim counter_Excelrow As Integer
'ポイント(5) ホームページのページ番号を格納する変数
Dim counter_IEpage As Integer
'1行目はリストのため、2行目からスタート
counter_Excelrow = 2
'1ページ目は既に開いているため、2ページ目からスタート
counter_IEpage = 2
'ポイント(6) データを抜き出すページ数に合わせて繰り返し回数を設定する (本プログラムでは10ページ分)
'2022年4月時点の掲載企業3956件を全て網羅したい場合は400回試行が必要だが、注意が必要
For counter_IEpage = 2 To 10
Do While objIE.Busy = True Or objIE.readyState < READYSTATE_COMPLETE
DoEvents
Loop
Dim i As Integer
'ポイント(7) 1ページの企業数(10件)の数だけ試行を繰り返す
For i = 0 To 9
'Withステートメントを用いてオブジェクトの複数記載を省略
'Class名を利用して企業情報にアクセス
With ThisWorkbook.Worksheets(1)
.Cells(counter_Excelrow, 1).Value = htmlDoc.getElementsByClassName("colset_article_ttl")(i).innerText
.Cells(counter_Excelrow, 2).Value = htmlDoc.getElementsByClassName("colset_article_txt")(i).innerText
'ポイント(8) Replace関数 & Mid関数を用いて不要な部分を削除
.Cells(counter_Excelrow, 3).Value = Replace(Mid(htmlDoc.getElementsByClassName("colset_article_access")(i).innerText, 7), vbLf, "")
End With
'次の読み込みのため、企業情報を記録するExcelシートの行を1行下げる
counter_Excelrow = counter_Excelrow + 1
'ポイント(9) エラーが発生しても、無視して次のステップに進む
On Error Resume Next
Next
Do While objIE.Busy = True Or objIE.readyState < READYSTATE_COMPLETE
DoEvents
Loop
'ポイント(10) アクセス間隔を1秒開ける
Call Sleep(1000)
'ポイント(11) 次のページに進む
objIE.Navigate "https://www5.city.kyoto.jp/kigyo/kg_102.cgi?CT=20&PN=" & counter_IEpage & "&RDNG=&RDNG2="
Next
End Sub
ポイント(1) InternetExplorerオブジェクトの生成
作業がExcel内で完結するプログラムにおいて見かけることはありませんが、Internet Explorerと連携させる場合には、Internet Explorerオブジェクトと呼ばれるオブジェクトを生成する必要があります。
Internet Explorerオブジェクトを使うためには、参照設定より下記の2つのライブラリを追加する必要があります。VBEのツール → 参照設定からアクセスし、チェックを入れてください。
- Microsoft HTML Object Library
- Microsoft Internet Controls
ポイント(2) 京のまち企業訪問ホームページを開く
Internet ExplorerオブジェクトのNavigateメソッドを利用し、ホームページを開きます。ポイント(1)、(2)の初期設定については、下記の記事が分かりやすいです。
ポイント(3) ページが進む前に次の動作が始まるのを防ぐ
ポイント(3)の部分を削除した状態でプログラムを実行すると、エラーが発生します。なぜでしょうか?
答えは簡単で、ページの遷移よりも早くプログラムがHTMLドキュメントを取りに行こうとすることにより、取得対象がない状態になっているためです。
このようなエラーを防止するために、ページが開いてからHTMLドキュメントを取りに行けるように工夫をしてあげる必要があります。ポイント(3)については、下記の記事を参考にしました。
ポイント(1)~(3)はウェブスクリプトの決まり文句と言っても過言ではないため、しっかり使えるようにしておきましょう。
ポイント(4) Excelシートの行数を格納する変数
ウェブスクレイピングにより読み取ったデータはExcelファイルに書き出されます。ポイント(4)で宣言した変数counter_Excelrowはデータが格納される行数を示しています。
1行目にはデータは入らない設計のため、変数counter_Excelrowは2からスタートさせています。1つのデータの書き込みが終わるたびに+1されるようになっており、すべてのデータの読み込みが完了するまでリセットされることなく読み込みが進みます。
for文による繰り返しで使用される変数を流用することも可能ですが、数のカウントを目的とした変数は別で設定しておくと分かりやすいです。
ポイント(5) ホームページのページ番号を格納する変数
本題のウェブスクレイピングに入っていきます。まずはホームページを見てみましょう。
右上にページ数があるため、現在のページ(1ページ目)に表示されている10件分の情報を取った後に2ページ目、3ページ目…とアクセスしていくとよさそうですね。
これらのページ数に対応する変数counter_IEpageを宣言し、後で使用できるようにしておきます。
ポイント(6) データを抜き出すページ数に合わせて繰り返し回数を設定する
最初にブラウザを立ち上げた時点で検索画面の1ページ目がすでに表示された状態になっているため、変数counter_IEpageは2からスタートさせます。終わりはデータを抜き出すページ数に合わせて変更してください。
10件表示の状態で掲載企業3956件のデータを取得する場合、約400回試行することになります。ホームページへのアクセス回数があまりにも多いと、DoS攻撃(短期間に集中的にホームページへのアクセスを集中させ、サーバーダウンさせること)になってしまう可能性があるため、十分注意してください。
一度に全てのデータを取得するのではなく、時間を空けつつ少しずつデータを集めていくのも有効な方法です。
前半パートのまとめ
今回の記事でポイント(6)まで紹介しましたが、いかがだったでしょうか。
後半の記事ではポイント(7)以降を紹介しています。下記のリンクからアクセスできます。
コメント