【问题标题】:Amazon Sales Data (with Excel VBA)亚马逊销售数据(使用 Excel VBA)
【发布时间】:2016-03-30 02:37:40
【问题描述】:

我正在尝试获取我通过 Excel VBA 搜索的每个关键字的结果编号(在 HTML 代码中)。通过 className、id 和 data-asin 缩小标准,但最后一个被证明是棘手的,因为 VBA 还不支持该参考库。

这段代码的结构是做什么的:

  1. 访问 amazon.com 并转到搜索栏。

  2. 循环从 C 列开始。从 SearchTerm1 列中提取一个搜索词并进行搜索。

  3. 加载结果页面后,尝试通过 className、ID(均在 HTML 代码中找到)和 ASIN 编号(此编号从 B 列中提取以匹配数据 - asin 搜索结果页面上的值)。如果没有所有 3 个条件,如果产品列在第一个结果页面上,excel 将无法找到该产品。

  4. 如果在第一页找到该产品,则获取其结果位置(例如,“result_0”表示第一个结果,result_1 表示第二个结果)并将其放入 D 列 (SRank1)。
  5. 如果未找到产品,则循环继续进行,直到搜索词列为空。
  6. 如果第一页没有找到该产品,则继续前进页面并搜索指定的产品,以获取该项目的“搜索排名”。
  7. 对 SearchTerm2、3 和 4 列重复相同的步骤。

下面的截图是只根据className和ID条件拉取的代码,它从页面拉取最后一个产品结果,这不是我分析产品表现的目标。

仅当产品是搜索页面上的第一个结果时,包含的代码才会拉产品排名,这意味着某些东西终于可以工作了,但缺少一两步来从页面中获取所有产品位置。

我们将不胜感激任何帮助或推动正确方向。我希望 VBA 对这类销售研究的东西更加通用。到目前为止,它已经创造了奇迹,但我可能已经达到了它的极限。代码如下。

Sub AmazonSearchRank()

    Dim MyHTML_Element As IHTMLElement
    Dim MyURL As String

    Dim AASearchRank As Workbook
    Dim AAws As Worksheet
    Dim InputSearchOrder As HTMLInputElement
    Dim elems As IHTMLElementCollection
    Dim TDelement As HTMLTableCell

    Dim InputSearchButton As HTMLInputButtonElement
    Dim IE As InternetExplorer
    Dim AASearchTerms As Workbook
    Dim SearchTermsSheet As Worksheet

    Dim x As Integer
    Dim i As Long

    MyURL = "https://www.amazon.com"
    Set IE = New InternetExplorer
    With IE
        .Silent = True
        .Navigate MyURL
        .Visible = True
        Do
            DoEvents
        Loop Until .ReadyState = READYSTATE_COMPLETE
    End With
    Set HTMLDoc = IE.Document

    Set AASearchRank = Application.Workbooks.Open("C:\Users\CompanyName\Desktop\Automation Anywhere\Sample_Items_For_SearchRank.xls")
    Set AAws = AASearchRank.Worksheets("Sheet1")

    Set InputSearchButton = HTMLDoc.getElementById("nav-search-submit-text")
    Set InputSearchOrder = HTMLDoc.getElementById("twotabsearchbox")
    If Not InputSearchOrder Is Nothing Then
        InputSearchButton.Click
        Do
            DoEvents
        Loop Until IE.ReadyState = READYSTATE_COMPLETE
    End If

    x = 2
    If AAws.Range("D" & x).Value = "" Then
        Do Until AAws.Range("B" & x) = ""
            Set InputSearchOrder = HTMLDoc.getElementById("twotabsearchtextbox")
            InputSearchOrder.Value = AAws.Range("C" & x)

            Set InputSearchButton = HTMLDoc.getElementsByClassName("nav-input")(0)
            InputSearchButton.Click
              Do
                DoEvents
            Loop Until IE.ReadyState = READYSTATE_COMPLETE
            Application.Wait (Now + TimeValue("0:00:05"))

            Set elems = HTMLDoc.getElementsByClassName("s-result-item celwidget")
            i = 2
            For Each TDelement In elems
                If TDelement.className = "s-result-item celwidget" And InStr(TDelement.ID, "result") InStr(TDelement.innerHTML, AAws.Range("B" & x).Value) Then
                    AAws.Range("D" & x).Value = TDelement.ID
                    i = i + 1
                End If
            Next
        x = x + 1
        Loop
    End If

End Sub

【问题讨论】:

  • 您能否稍微修改您的问题以使其更清楚。添加您的代码做了什么,它做错了什么,还添加了工作表屏幕截图的描述,以及每列的用途(给出的内容,以及要找到的内容)。
  • 嘿@omegastripes,我在问题中编辑了很多东西。如果还有什么需要澄清的,请告诉我。我非常接近解决这个难题,但我不确定我错过了什么。

标签: vba excel amazon-web-services web-scraping xmlhttprequest


【解决方案1】:

以下示例针对表单Terms 上显示的每个搜索查询从亚马逊下载产品,并使用ASIN 和描述填充表单Products。它使用 XHR,因此不需要 IE。代码如下:

Sub Test()
    lngRow = 1
    ' search each term
    For Each strTerm In Sheets("Terms").UsedRange
        lngPage = 1
        Do
            ' HTTP GET request of the search result page
            strUrl = "https://www.amazon.com/s/ref=nb_sb_noss_2?page=" & lngPage & "&keywords=" & EncodeUriComponent(strTerm)
            Set objXHR = CreateObject("MSXML2.XMLHttp")
            objXHR.Open "GET", strUrl, False
            objXHR.Send
            strResp = objXHR.ResponseText
            ' split response to array by items
            arrResp = Split(strResp, "<li id=""result_")
            ' process each item on the page
            For i = 1 To UBound(arrResp)
                strItem = arrResp(i)
                ' extract ASIN
                strTmp = Split(strItem, "data-asin=""")(1)
                strTmp = Split(strTmp, """")(0)
                Sheets("Products").Cells(lngRow, 1).NumberFormat = "@"
                Sheets("Products").Cells(lngRow, 1).Value = strTmp
                ' extract the product description
                strTmp = Split("<li id=""result_" & strItem, "</li>")(0) & "</li>"
                Sheets("Products").Cells(lngRow, 2).Value = GetInnerText(strTmp)
                ' show current item
                Sheets("Products").Cells(lngRow, 1).Select
                ' next row
                lngRow = lngRow + 1
            Next
            ' adjust sheet
            Sheets("Products").Columns.AutoFit
            Sheets("Products").Rows.AutoFit
            ' next page
            lngPage = lngPage + 1
        Loop Until UBound(arrResp) = 0 ' empty search result
    Next
End Sub

Function EncodeUriComponent(strText)
    Static objHtmlfile As Object
    If objHtmlfile Is Nothing Then
        Set objHtmlfile = CreateObject("htmlfile")
        objHtmlfile.parentWindow.execScript "function encode(s) {return encodeURIComponent(s)}", "jscript"
    End If
    EncodeUriComponent = objHtmlfile.parentWindow.encode(strText)
End Function

Function GetInnerText(strHtmlContent)
    Dim objHtmlFile, objBody
    Set objHtmlFile = CreateObject("htmlfile")
    objHtmlFile.write strHtmlContent
    Set objBody = objHtmlFile.getElementsByTagName("body")(0)
    GetInnerText = Trim(objBody.innerText)
End Function

我放在Terms 表上:

Product 工作表上的结果包含 571 项:

这不是一个完整的答案,但我希望它对你有所帮助。

【讨论】:

  • 这绝对有帮助,而且是一个很好的解决方案,但我正在寻找 VBA。我试了一下,效果很好。我只需要对其进行一些调整,以便代码将排除第二列中所有多余的数据。绝对在代码中给了我一些方向 - 谢谢你,善良的用户。
  • 您能否帮助我尝试仅使用 XML 来引用 ASIN 代码?我正在做一个小项目,试图在搜索页面加载后获取每个产品的位置编号(结果编号)。我附上了电子表格的屏幕截图,其中包含我从一位卖家那里提取的产品示例列表。此外,一些注释会很有帮助 - 我几乎没有使用 XML 的经验。
  • 谢谢!我也在努力尝试调整代码。我只需要重新学习所有这些的语法。循环会有点挑战,哈哈。
  • 我得到了该死的工作。这只是我必须删除的一个 sn-p 代码,猜猜它是哪一个? TDelement.ID。我现在需要做的就是插入一个函数,该函数允许页面前进,直到 Excel 能够找到 ASIN 编号,然后移动到下一个搜索词。
【解决方案2】:

经过反复试验,我终于解决了这个该死的事情。我只需要取出包含“And InStr(TDelement.ID,“result”)”的部分代码,然后一切都像黄油一样顺利。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-07-29
    • 1970-01-01
    • 2022-09-23
    • 1970-01-01
    • 2021-05-26
    • 2021-08-15
    • 2012-12-03
    相关资源
    最近更新 更多