2020年7月13日月曜日

Excel VBAでWebからデータを収集

大人の事情により、Excel VBAでWebからデータを収集する必要になってきたので試しにやってみる。今回は『データを集める技術』を参考にさせていただいた。この中でExcel VBAでAmazonのクラウド関連本の売れ筋ランキングを取得するというサンプルに挑戦。

まずVBAのライブラリの参照設定で「Microsoft HTML Object Library」と「Microsoft Internet Controls」をチェックする。


これでサンプルのコードを動かしてみたが、そのままではうまくランキングを取得できなかった。そこで試行錯誤して2点ほど修正すると、狙い通り売れ筋の本のランキングをExcelに取得できた。


修正の一点目は、Excelが64ビットの場合はWindows APIのSleepライブラリの書き方が違うとのことで、そこで以下のように場合分けするように修正。VBA7の方がおそらく64ビット向けですね。

#If VBA7 Then
Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal ms As LongPtr)
#Else
Private Declare Sub Sleep Lib "kernel32" (ByVal ms As Long)
#End If

二点目は『データを集める技術』の出版時からAmazonのHTMLの構造が変わったためにそこを修正。書名のクラスが以前は”a-fixed-left-grid-inner”だったものが、今はChromeで検証すると"p13n-sc-truncated"となっているようなので、そこを修正。

最終的にうまくデータを取得できたVBAのコードは以下のとおり。

=======================================
Option Explicit

#If VBA7 Then
Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal ms As LongPtr)
#Else
Private Declare Sub Sleep Lib "kernel32" (ByVal ms As Long)
#End If


Private objIE As InternetExplorer

Sub main()
    Set objIE = New InternetExplorer
    Dim url

    url = "https://www.amazon.co.jp/gp/bestsellers/books/3257503051/"

    objIE.Visible = True
    objIE.Navigate2 (url)

    '読み込み完了待ち

    While objIE.readyState <> READYSTATE_COMPLETE Or objIE.Busy = True
        DoEvents
        Sleep 100
    Wend
    Sleep 100

    Dim objDoc As HTMLElementCollection
    Set objDoc = objIE.document
    Dim element As IHTMLElement

    Dim row '書き込むセルの行数
    row = 1
    For Each element In objDoc.getElementsByClassName("p13n-sc-truncated") 
        'シートに取得したタイトルの書き込み
        Worksheets(1).Cells(row, 1) = row
        Worksheets(1).Cells(row, 2) = element.innerText
        row = row + 1
    Next element

    objIE.Quit
    Set objIE = Nothing
End Sub
=======================================

他の分野のベストセラー・ランキングを取得したい時はurlを変えればいい。
例えば、「金融・ファイナンス」なら
url = "https://www.amazon.co.jp/gp/bestsellers/books/1099154/"  
「新書」なら
url = "https://www.amazon.co.jp/gp/bestsellers/books/2189049051/" 
=======================================

また、"p13n-sc-truncated"のような属性の要素を確認するにはChromeでXPathを抽出する。
《ChromeでXPathを抽出する方法》
①目的のノードを選択している状態で、右クリック
②メニューから「検証」を選ぶ
③選択されているノード(青くなっている部分)の上で右クリック
④「Copy」→「Copy XPath」を選択。

FirefoxでXPathを抽出する場合は、前提としてFirebugをインストール。「ツール」→「アドオン」からFirebugを検索。
《FirefoxでXPathを抽出する方法》
①目的のノードを選択している状態で、右クリック
②「Firebugで要素を調査」メニューを選ぶ
③選択されているノード(青くなっている部分)の上で右クリック
④「XPathをコピー」を選択。

Chromeで抜き出すXPathは、目的のノードに一番近いid属性からの相対パス。Firefoxで抜き出すXPathは、ルートノードからの絶対パス。

0 件のコメント: