VBAでWebスクレイピングする方法を前回2通り勉強しました。
今回は、もう少し実践的に、「Amazonでキーワードを検索して、1番に出てきた商品情報を取得する」をやってみました。
前回のやり方ではなく、今回はIE(InternetExplorer)を操作するやり方でやっています。
DOMメソッドだとクラス名が取得できない
Webブラウザを使わずにHTMLを取得していくやり方を前回紹介しました。
これ↓はそのコードの一部です。
Dim httpreq As Variant
Set httpreq = CreateObject("MSXML2.XMLHTTP")
httpreq.Open "GET", "https://www.amazon.co.jp"
httpreq.Send
Do While httpreq.readyState < 4
DoEvents
Loop
Dim html As Variant
Set html = CreateObject("htmlfile")
html.write httpreq.responseText
(略)
このやり方で、Amazonで商品を検索して、結果を取り出そうとしたところ、重要なことを後から知りました。
のです。
h1やh2といったタグ名でHTMLを取り出すことはできるのですが、クラス名で取り出すやり方がありません。
参考: https://docs.microsoft.com/en-us/previous-versions/aa926433(v=msdn.10)?redirectedfrom=MSDN
例:<h1>*****</h1>はタグ名「h1」で取り出せる
<div class=”aa”>*****</div>はクラス名「aa」で取り出せない
タグ名だけだと、取り出したい情報を取り出せません。
というわけで、「MSXML2.XMLHTTP」を使うDOMメソッドは断念。
IEを操作するやり方
Webブラウザを使用するやり方としては、前回紹介したSeleniumを使用する方法があります。
が、今回はSeleniumを使用せず、IE(InternetExplorer)を直接操作するやり方でやってみることにしました。
ソースコード
IEを使用してAmazonの商品を検索して1番に出てきた商品情報を取得するソースコードを作ってみました。
参考サイト:【Webスクレイピング】VBAでAmazonの在庫ステータスを取得しよう
Sub amazonSearch2()
Dim searchWord As String
Dim azUrl As String 'URL
Dim azName As String '商品名
Dim azValue As String '価格
Dim ws As Worksheet
Dim erow As Integer
Dim irow As Integer
erow = Cells(Rows.Count, 1).End(xlUp).Row '最終行
Set ws = ActiveSheet
Dim ie As InternetExplorer
Dim html As HTMLDocument
Set ie = CreateObject("Internetexplorer.Application")
' ie.Visible = True 'IEを表示しないようにコメントアウト
For irow = 1 To erow
ie.navigate ("https://www.amazon.co.jp/") 'amazonに接続
Do While ie.Busy = True Or ie.readyState < 4
DoEvents
Loop
Set html = ie.document
Dim searchForm As HTMLInputTextElement
Set searchForm = html.getElementById("twotabsearchtextbox") '検索窓
searchForm.Value = ws.Cells(irow, 1) 'セルの値(検索する文字列)を入力
Dim btnSearch As HTMLFormElement
Set btnSearch = html.getElementsByClassName("nav-input")(0) '検索ボタン
btnSearch.Click
Do While ie.Busy = True Or ie.readyState < 4
DoEvents
Loop
'商品名
azName = html.getElementsByClassName("a-size-base-plus a-color-base a-text-normal")(0).innerText
ws.Cells(irow, 2) = azName
'価格
azValue = html.getElementsByClassName("a-price-whole")(0).innerText
ws.Cells(irow, 3) = azValue
'リンク
Dim elm As Object
Set elm = html.getElementsByClassName("a-size-base a-link-normal s-no-hover a-text-normal")(0)
azUrl = elm.href
ws.Cells(irow, 4) = azUrl
Next irow
Set html = Nothing
Set searchFom = Nothing
Set btnSearch = Nothing
Set link = Nothing
Set ie = Nothing
Set ws = Nothing
MsgBox ("終了しました")
End Sub
ちなみに、このソースコードの実行は以下の参照設定が必要です。
- Microsoft HTML Object Library
- Microsoft Internet Controls
ソースの処理の流れは
- IEを設定
- Amazonのページに遷移
- 検索窓にキーワードを設定
- 検索ボタンをクリック
- 商品一覧の一番左上の商品の商品名と価格、商品リンクを取得
となっています。
ここで、ページを遷移したら、
Do While ie.Busy = True Or ie.readyState < 4
DoEvents
Loop
でページ遷移の処理を待つようにしています。
商品情報を取得するためのHTMLのクラス名はChromeのデベロッパーツールで調べました。
エラー発生
上記のソースコードで実行してみると、41行目のところでエラーになります。
なんのこっちゃ??
ここで躓いてしまいました。
しばらくあれこれやってみたのですが、このページで解決しました。
参考サイト:https://teratail.com/questions/209560
IEの状態が完了となっても、javascriptがまだ処理中の場合にエラーになるようです。
確かに、Amazonの検索結果ページのHTMLを見てみると、javascriptがあります。
ということで、解決策として、単純に待つコードを挿入しました。
修正後ソースコード
修正後のコードはこちら。
Private Declare Sub Sleep Lib "kernel32" (ByVal ms As Long)
Sub amazonSearch2()
Dim searchWord As String
Dim azUrl As String 'URL
Dim azName As String '商品名
Dim azValue As String '価格
Dim ws As Worksheet
Dim erow As Integer
Dim irow As Integer
erow = Cells(Rows.Count, 1).End(xlUp).Row
Set ws = ActiveSheet
Dim ie As InternetExplorer
Dim html As HTMLDocument
Set ie = CreateObject("Internetexplorer.Application")
' ie.Visible = True
For irow = 1 To erow
ie.navigate ("https://www.amazon.co.jp/")
Do While ie.Busy = True Or ie.readyState < 4
DoEvents
Loop
Set html = ie.document
Dim searchForm As HTMLInputTextElement
Set searchForm = html.getElementById("twotabsearchtextbox")
searchForm.Value = ws.Cells(irow, 1)
Dim btnSearch As HTMLFormElement
Set btnSearch = html.getElementsByClassName("nav-input")(0)
btnSearch.Click
Do While ie.Busy = True Or ie.readyState < 4
DoEvents
Loop
Sleep (1000) '1秒まつ javascriptを待つため
azName = html.getElementsByClassName("a-size-base-plus a-color-base a-text-normal")(0).innerText
ws.Cells(irow, 2) = azName
azValue = html.getElementsByClassName("a-price-whole")(0).innerText
ws.Cells(irow, 3) = azValue
Dim elm As Object
Set elm = html.getElementsByClassName("a-size-base a-link-normal s-no-hover a-text-normal")(0)
azUrl = elm.href
ws.Cells(irow, 4) = azUrl
Next irow
Set html = Nothing
Set searchFom = Nothing
Set btnSearch = Nothing
Set link = Nothing
Set ie = Nothing
Set ws = Nothing
MsgBox ("終了しました")
End Sub
1行目と42行目を追加しました。
1行目はSleep関数の定義で、42行目でページ遷移後に1秒待つようにしています。
修正したコードでエラー無く実行できました。
4つほどキーワードをアマゾン検索してみた結果がこちら。
リンクもきちんと取得できていました。
CrowdWorksとかで案件を探していると、「Amazonの情報取得ツールを作って」というような依頼が結構あります。
今回Amazonの検索を試しに作ってみたのは、こういったCrowdWorks等の依頼を受注できるようにするためでもあったりします。
webスクレイピングはHTMLの該当箇所を探すのに慣れちゃえば、結構面白いですね。
あなたもVBAでスクレイピングやってみてください!
んじゃ、また~
おススメのプログラミング独学方法をこちらの記事で紹介しています。
コメント