VBAでWebスクレイピングする方法を前回2通り勉強しました。
今回は、もう少し実践的に、「Amazonでキーワードを検索して、1番に出てきた商品情報を取得する」をやってみました。
前回のやり方ではなく、今回はIE(InternetExplorer)を操作するやり方でやっています。
DOMメソッドだとクラス名が取得できない
Webブラウザを使わずにHTMLを取得していくやり方を前回紹介しました。
これ↓はそのコードの一部です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
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の在庫ステータスを取得しよう
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
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があります。
ということで、解決策として、単純に待つコードを挿入しました。
修正後ソースコード
修正後のコードはこちら。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
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でスクレイピングやってみてください!
んじゃ、また~
コメント