おまけ スクレイピング
「さて、これまでAPIを使って取得してきたけど、使えない場合はどうするのか。というか、たいていのサイトはAPIは使えないから色々と工夫する必要がるよ。まぁその場合に使うのがスクレイピングだね。ここでは簡単にそのやり方を説明するよ」
「なんだか難しそうです」
「まぁ、ちょっと難しいかな。また、使うのはいいんだけど、色々と注意点があるからね。あんまり頻繁に使って相手側に迷惑をかけない範囲でやってね」
「はーい」
「じゃぁ準備だね。まずメニューバの『ツール』から『参照設定』を開いてね。ししたら、その中から以下の二つを探してチェックを入れる。
・Microsoft HTML Object Library
・Microsoft Internet Controls
「できました」
「じゃぁその次に、このコードを張り付けてみて」
■サンプル 小説家になろうレビュー欄スクレイピングサンプル■
*☆*――*☆*――*☆*――*☆*――*☆*――*☆*――*☆*――*☆*
Private Sub CommandButton1_Click()
'Application.ScreenUpdating = False
Dim i As Integer, k As Double, buf As String, buf2 As Variant, SheetName As String
Dim objIE As InternetExplorer 'IEオブジェクトを準備
Dim htmlDoc As HTMLDocument 'HTMLドキュメントオブジェクトを準備
'Sheet名を変えた場合は""内を変えたシート名に変える
SheetName = "Sheet1"
Sheets(SheetName).Cells.Clear 'Sheetのクリア
Set objIE = CreateObject("Internetexplorer.Application") '新しいIEオブジェクトを作成してセット
objIE.Visible = True 'IEを表示
'objIE.Visible = False 'IEを非表示 実際の運用時は非表示
objIE.navigate "https://yomou.syosetu.com/reviewlist/list/" 'IEでURLを開く
'例はレビュー欄
Do While objIE.Busy = True Or objIE.readyState < READYSTATE_COMPLETE '読み込み待ち
DoEvents
Loop
Set htmlDoc = objIE.document 'objIEで読み込まれているHTMLドキュメントをセット
'総件数を取得 <h2 class="site">レビュー一覧(全47386件)</h2>
buf = htmlDoc.getElementsByClassName("site")(0).outerHTML
Cells(1, 1) = Mid(buf, 26, 5)
Cells(1, 2) = "投稿時間"
Cells(1, 3) = "改稿時間"
Cells(1, 4) = "nコード"
Cells(1, 5) = "レビュータイトル"
Cells(1, 6) = "本文"
Cells(1, 7) = "文字数"
'<h4 class="review_title">XXXXXXX</h4>
For i = 0 To htmlDoc.getElementsByClassName("review_title").Length - 1 'レビュー数だけループ
'レビュー日時 時間 改時間 <span class="review_date">2019年 04月 21日 19時 40分 <span title="2019年 04月 21日 19時 40分">(<u>改</u>)</span></span>
buf = htmlDoc.getElementsByClassName("review_date")(i).outerHTML
Cells(i + 2, 2) = Mid(buf, 27, 21)
If Len(buf) > 60 Then
Cells(i + 2, 3) = Mid(buf, 62, 21)
Else
End If
'小説nコード
buf = htmlDoc.getElementsByClassName("novelinfo")(i).outerHTML
' <p class="novelinfo">
' 小説タイトル:<a href="https://ncode.syosetu.com/nXXXX/" class="novel_title">XXXXX</a><br />
' <a href="https://ncode.syosetu.com/novelview/infotop/ncode/nXXXXX/">小説情報</a>
' </p>
buf2 = Split(buf, "/")
Cells(i + 2, 4) = buf2(3)
'レビュータイトル
' <h4 class="review_title">XXXXX</h4>
buf = htmlDoc.getElementsByClassName("review_title")(i).outerHTML
Cells(i + 2, 5) = Mid(buf, 26, Len(buf) - 30)
'レビュー本文 <p class="reviewhonbun">
buf = htmlDoc.getElementsByClassName("reviewhonbun")(i).outerHTML
'buf = Replace(buf, "", "") 'br改行タグを消してください……
Cells(i + 2, 6) = Mid(buf, 25, Len(buf) - 28)
Cells(i + 2, 7) = Len(buf) - 28
Next
objIE.Quit
Set objIE = Nothing
Set htmlDoc = Nothing
'Application.ScreenUpdating = True
End Sub
*☆*――*☆*――*☆*――*☆*――*☆*――*☆*――*☆*――*☆*
「ここではレビュー欄を例してみた。プログラムを動かすとこんな感じにデータをとってきてくれる」
「おお、すごいです。レビューの中身が取れてます!」
「これでいちいち手でコピペなんかしなくていいよね。投稿時間の分析だって簡単にできちゃうね」
「へぇ、すごい。これってどういう仕組みなんですか?」
「じゃぁ簡単に説明しよう
Set objIE = CreateObject("Internetexplorer.Application") '新しいIEオブジェクトを作成してセット
objIE.Visible = True 'IEを表示
'objIE.Visible = False 'IEを非表示 実際の運用時は非表示
objIE.navigate "https://yomou.syosetu.com/reviewlist/list/" 'IEでURLを開く
この部分で、Excelからインターネットエクスプローラーを立ち上げることができる。そうするとそのブラウザで開いたページの情報はExcelで取り込めるようになるんだ。
HTMLからタグ名や、クラス、id名で囲まれた部分をとることができる。例えば
htmlDoc.getElementsByClassName("review_date")(i).outerHTML
なら、『review_date』というクラスを取得できる。これはレビュー日時に使われるクラス。こんな感じだね。
<span class="review_date">2019年 04月 21日 19時 40分 <span title="2019年 04月 21日 19時 40分">(<u>改</u>)</span></span>
その要素を取り出すことができるんだ。
ちなみにHTMLを見たければ、該当ページで右クリックして、ソースを表示させてみよう。そうするとHTMLが見れるので、そこから欲しいタグを見つけて、やればいいよ。
ちなみにIDはこれでとれるよ。
htmlDoc.getElementById ("id").innerHTML
「へぇ、そうやってAPIでとれない部分をとるのですね。ちょっと面倒かも」
「まぁあんまり、やる人もいないからね。ある程度、HTMLとプログラムの知識がないときついから。まぁ正直APIだけでも十分だと思うよ。慣れてきたらお試しにやるのでもいいかもね。
ということでスクレイピングも終わり。これで、どのサイトでもデータは取れるけど、なるべくサイトの負荷の少ないやり方を考えてね。スクレイピングをするときはデータの集まるところからとる用にすると効率がいいよ。1秒1回ルールも忘れないようにね」
「分かりました私もがんばります」
「じゃぁこの講義も終わりかな」
「ありがとうございました。私データ分析やってみます!」
これがすごくわかりやすいので参考にするといいと思います。
[VBA]30分あればできるVBAスクレイピング
https://qiita.com/SoreKiita/items/4b4c845b7378f6765704




