さて前回「エクセルVBAを使ったアマゾンのトップ画面操作」で説明したプログラムを使って今度は、アマゾンで検索した結果表示された商品のASINコードを取得したいと思います。
ASINコードは、 Amazonグループの独自のコードで書籍以外の商品を識別する10桁の固有番号です。 同じ商品は、どの国のamazonでも、同じASINコードで管理されています。
前回の検索方法で”キーワード”を例えば、“4Kテレビ” と入れてみましょう。
この画面から検索された商品のうち最初のもののASINコードを抜き出します。
前回と同じように「F12」キーを押して、IEに標準で実装されている[DOM Explorer]を起動します。
HTMLは随分と長いですが、どうやら商品説明をクリックするとリンクする<a>コマンドのhref属性の中にありそうです。いくつかのHTMLを眺めてみると、“dp/” または “dp%2F”に続く10桁の文字がASINコードとなるようです。ちなみに、”%2F”はURLエンコードした”/”を表します。
<a class="a-link-normal a-text-normal" href="/gp/slredirect/picassoRedirect.html/ref=pa_sp_atf_aps_sr_pg1_1?ie=UTF8&adId=A3E36MB8XE4AOF&url=%2FTCL-4K%25E5%25AF%25BE%25E5%25BF%259C%25E6%25B6%25B2%25E6%2599%25B6%25E3%2583%2586%25E3%2583%25AC%25E3%2583%2593-%25E3%2583%2589%25E3%2583%25AB%25E3%2583%2593%25E3%2583%25BC%25E3%2582%25AA%25E3%2583%25BC%25E3%2583%2587%25E3%2582%25A3%25E3%2582%25AA-2019%25E5%25B9%25B4%25E3%2583%25A2%25E3%2583%2587%25E3%2583%25AB-55C8%2Fdp%2FB07WYW9473%2Fref%3Dsr_1_1_sspa%3F__mk_ja_JP%3D%25E3%2582%25AB%25E3%2582%25BF%25E3%2582%25AB%25E3%2583%258A%26dchild%3D1%26keywords%3D4k%25E3%2583%2586%25E3%2583%25AC%25E3%2583%2593%26qid%3D1590215406%26sr%3D8-1-spons%26psc%3D1&qualifier=1590215406&id=7000584394847529&widgetName=sp_atf" target="_blank">
<span class="a-size-base-plus a-color-base a-text-normal">TCL 55V型 4K対応液晶テレビ スマートテレビ(Android TV) サウンドバー(ドルビーオーディオ)搭載 ブラック 2019年モデル 55C8</span>
</a>
今回は、プログラムを始めに開示します。
- Dim htmlDoc As HTMLDocument
- Dim strLinkHTML As String
- Dim linkUrl As String
- Dim Asin As String
- Dim strTemp As String
- Dim objLink As IHTMLElement
- Dim dp_location As Long
- Dim strExpression As String
- '検索対象部品が見つからなかったときの処置
- For Each htmlDoc In objIE.document.getElementsByTagName("span")
- strTemp = htmlDoc.innerText
- If InStr(strTemp, "一致する商品") > 0 Or InStr(strTemp, "検索結果が") > 0 Then
- MsgBox "検索対象品が見つかりません"
- Exit Sub
- End If
- Next
- 'ASINを探す処理
- For Each objLink In objIE.document.Links
- If objLink.className = "a-link-normal a-text-normal" Then
- strLinkHTML = objLink.outerHTML
- ' "dp%2F"は"dp/"に文字変換しちゃいます。
- strLinkHTML = Replace(strLinkHTML, "dp%2F", "dp/")
- dp_location = InStr(strLinkHTML, "dp/")
- If dp_location > 0 Then
- Asin = Mid(strLinkHTML, dp_location + 3, 10)
- linkUrl = objLink.href
- strExpression = objLink.innerText
- Dim messageNo As Integer
- messageNo = MsgBox(strExpression, vbOKOnly, Asin)
- Exit For
- End If
- End If
- Next
まず冒頭に、検索結果で検索対象品が見つからなかったときの処置をいれます。
このときアマゾンのメッセージは以下の画面のような表示となります。
いろいろ試してみましたが、毎回、同じメッセージではなく、
「一致する商品はありませんでした。」「検索結果が・・・・」というようなメッセージが表示されるので、そのメッセージが表示された場合は"検索対象品が見つかりません"とメッセージボックスに表示し、ブログラムを終了します。
このメッセージは<span>~</span>要素に囲まれたHTMLに記載されていますので、HTML内に記述された<span>要素の全配列である
objIE.document.getElementsByTagName("span") を使って、それぞれの<span>要素をFor Each 文を使って、htmlDoc に代入してから作業を行います。
strTemp = htmlDoc.innerText
で文字列をstrTemp に代入し、"一致する商品"、"検索結果が" というNG文字が含まれていないかInStr関数を用いて検索しています。
NG文字が無かったばあいは、いよいよASINの取り出しに入ります。
“objIE.document.Links”は、HTML内の全リンクの配列です。それぞれのリンクをFor Each 文を使って、objLinkに代入してから作業を行います。
注意ポイント
[DOM Explorer]を使うと、イメージ写真と説明文の両方に似たようなリンク先の記載が見つかります。今回は、説明文の方のリンク先を選択するためにclass属性が以下のものだけを選択対象とします。
class="a-link-normal a-text-normal"
strLinkHTML = objLink.outerHTML でリンク先を含むテキストデータを取り出します。
お目当てのリンク先を見つけたらいよいよ、ASINコードを取り出します。
冒頭で説明した“dp/” または “dp%2F”に続く10桁の文字がASINコードとなるので、検索を一元化するために、
“dp%2F” → “dp/”
とReplace関数を使って変換してしまいます。
InStr関数を使って、“dp/”を検索し、検索結果をもとに“dp/”に連なる10桁の文字を取得する。
取得結果は メッセージボックスの タイトルに ASINコードを入れ、メッセージには商品説明を入れて表示させました。
応用するとエクラルのスプレッドシートと併せて、複数のASINコードを取得することも可能となります。
最後に全体のプログラムを以下に掲載します。
- Option Explicit
- Const READYSTATE_COMPLETE = 4
- Dim objIE As InternetExplorer
- Dim objElement As IHTMLElement
- Dim objInputTags As IHTMLElementCollection 'Inputオブジェクト配列、集合体
- Dim objInput As IHTMLElement 'Inputオブジェクト
- Dim class_name As String
- Dim htmlDoc As HTMLDocument
- Dim strLinkHTML As String
- Dim linkUrl As String
- Dim Asin As String
- Dim strTemp As String
- Dim objLink As IHTMLElement
- Dim dp_location As Long
- Dim strExpression As String
- Sub getASIN()
- Set objIE = CreateObject("InternetExplorer.Application")
- objIE.Visible = True
- objIE.Navigate2 "https://www.amazon.co.jp/"
- Do While objIE.Busy Or objIE.readyState <> READYSTATE_COMPLETE
- DoEvents '上記の条件が長時間不成立の時、ESCキーで停止できるように追記。
- Loop
- Set objElement = objIE.document.getElementById("twotabsearchtextbox")
- objElement.Value = "4kテレビ" '"fjafjf;afi"
- Set objInputTags = objIE.document.getElementsByTagName("input")
- For Each objInput In objInputTags
- On Error Resume Next 'エラーが発生するとエラーの発生した次の要素から処理
- class_name = objInput.className
- On Error GoTo 0 ' 1つ前で宣言したエラー無視を無効にする。
- If class_name = "nav-input" Then
- objInput.Click '見つけた! すかさずクリック
- 'IEが完全表示されるまで待機
- Do While objIE.Busy = False
- DoEvents
- Loop
- Do While objIE.Busy Or objIE.readyState <> READYSTATE_COMPLETE
- DoEvents '上記の条件が長時間不成立の時、ESCキーで停止できるように追記。
- Loop
- Exit For
- End If
- Next
- '検索対象部品が見つからなかったときの処置
- For Each htmlDoc In objIE.document.getElementsByTagName("span")
- strTemp = htmlDoc.innerText
- If InStr(strTemp, "一致する商品") > 0 Or InStr(strTemp, "検索結果が") > 0 Then
- MsgBox "検索対象品が見つかりません"
- Exit Sub
- End If
- Next
- 'ASINを探す処理
- For Each objLink In objIE.document.Links
- If objLink.className = "a-link-normal a-text-normal" Then
- strLinkHTML = objLink.outerHTML
- ' "dp%2F"は"dp/"に文字変換しちゃいます。
- strLinkHTML = Replace(strLinkHTML, "dp%2F", "dp/")
- dp_location = InStr(strLinkHTML, "dp/")
- If dp_location > 0 Then
- Asin = Mid(strLinkHTML, dp_location + 3, 10)
- linkUrl = objLink.href
- strExpression = objLink.innerText
- Dim messageNo As Integer
- messageNo = MsgBox(strExpression, vbOKOnly, Asin)
- Exit For
- End If
- End If
- Next
- End Sub