Содержимое VBA Scrape генерируется JavaScript - PullRequest
2 голосов
/ 20 марта 2020

Я хочу получить информацию о рекомендуемой цене клиента с URL-адреса, определенного на листе Excel с использованием VBA. Эти значения находятся в Excel в ячейках (i, 11), которые все указывают на указанную c страницу на https://ark.intel.com. Значения начинаются в строке 5.

Например, если я хочу найти цену на Intel Xeon 8268, я бы перешел к https://ark.intel.com/content/www/us/en/ark/products/192481/intel-xeon-platinum-8268-processor-35-75m-cache-2-90-ghz.html. При просмотре источника очевидно, что этот контент генерируется с JavaScript, поэтому я вместо этого использую опцию «Inspect Element» в веб-браузере Firefox

Отсюда я могу перейти вниз и найти то, что я ищу в теге. См. Изображение ниже:

Recommendd Customer Price for Intel Xeon 8268

Я не могу зафиксировать это значение и записать его в столбец Excel, который будет столбцом E. Ниже приведена одна попытка Я сделал:

Sub ProcessorPricing()
    Dim URL As String, lastRow As Long
    Dim XMLHTTP As Object, HTML As Object, objResult As Object, Price As Object

    lastRow = Range("A" & Rows.Count).End(xlUp).row

    Dim cookie As String
    Dim result_cookie As String

    For i = 5 To lastRow

        If Cells(i, 1) <> "" Then

            URL = Cells(i, 11)

            Set XMLHTTP = CreateObject("MSXML2.serverXMLHTTP")
            XMLHTTP.Open "GET", URL, False
            XMLHTTP.setRequestHeader "Content-Type", "text/xml"
            XMLHTTP.setRequestHeader "User-Agent", "Mozilla/5.0 (Windows NT 6.1; rv:25.0) Gecko/20100101 Firefox/25.0"
            XMLHTTP.send

            Set HTML = CreateObject("htmlfile")
            HTML.body.innerHTML = XMLHTTP.responseText

            Set objResult = html.getElementsByID("bladeInside")
            Set Price = objResult.getElementsByTagName("span")(0)

            Cells(i, 5) = Price.Value
            DoEvents
        End If
    Next
End Sub

Любая помощь будет принята с благодарностью.

PS - я также пробовал код, найденный на https://www.myonlinetraininghub.com/web-scraping-with-vba, но безрезультатно

ОБНОВЛЕНИЕ:

Был в состоянии заставить все работать с ваша помощь. Спасибо, Бертран Мартель и Ставрос Джон.

Вот весь сценарий:

Sub UpdateProcessorInfo()
'requirements:  JSON Parser installation needs to be added to project - https://github.com/VBA-tools/VBA-JSON - (Download latest release -> Import JsonConverter.bas -> File -> Import File)
'requirements:  Windows only, include Reference to "Microsoft Scripting Runtime" (Tools -> References -> Check Microsoft Scripting Runtime)
'requirements:  Add a refernce to Microsoft WinHTTP Services 5.1.  (Tools -> References -> Check Microsoft WinHTTP Services 5.1)

Dim Connection As WorkbookConnection
Dim url As String, lastRow As Long
Dim XMLHTTP As Object, html As Object, objResultDiv As Object, link As Object
Dim cookie As String
Dim result_cookie As String
Dim req As New WinHttpRequest
Dim ids As String
Dim responseJSON As Object

For Each Connection In ThisWorkbook.Connections
    Connection.Refresh
Next Connection

Worksheets("Processor_DB_Intel").Range("A2:A1000").Copy
Worksheets("Processor Comparisons").Range("A5").PasteSpecial Paste:=xlPasteValues

lastRow = Range("A" & Rows.Count).End(xlUp).row

Range("k5:k300").Clear

For i = 5 To lastRow

    If Cells(i, 1) <> "" Then

        url = "https://www.google.com/search?q=" & "site:ark.intel.com " & Cells(i, 1) & "&rnd=" & WorksheetFunction.RandBetween(1, 10000)

        Set XMLHTTP = CreateObject("MSXML2.serverXMLHTTP")
        XMLHTTP.Open "GET", url, False
        XMLHTTP.setRequestHeader "Content-Type", "text/xml"
        XMLHTTP.setRequestHeader "User-Agent", "Mozilla/5.0 (Windows NT 6.1; rv:25.0) Gecko/20100101 Firefox/25.0"
        XMLHTTP.send

        Set html = CreateObject("htmlfile")
        html.body.innerHTML = XMLHTTP.responseText
        Set objResultDiv = html.getElementById("rso")
        Set link = objResultDiv.getElementsByTagName("a")(0)

        Cells(i, 11) = link
        DoEvents
    End If

Next

lastRow = Range("A" & Rows.Count).End(xlUp).row

For i = 5 To lastRow

    ids = Cells(i, 13)
    url = "https://ark.intel.com/libs/apps/intel/support/ark/recommendedCustomerPrice?ids=" & ids & "&siteName=ark"

    If Cells(i, 1) <> "" Then

        With req
            .Open "GET", url, False
            .send
            Set responseJSON = JsonConverter.ParseJson(.responseText)
        End With

        On Error Resume Next

        'Debug.Print responseJSON(1)("displayPrice")
        Cells(i, 14) = responseJSON(1)("displayPrice")

    End If
Next

End Sub

Ответы [ 2 ]

3 голосов
/ 20 марта 2020

AS @Bertrand Martel указал, что есть очень удобный API, который вы можете использовать для получения необходимой вам информации.

Для дальнейшего уточнения его ответа, и поскольку у вас возникли проблемы с извлечением цены из JSON ответ, вот мои два цента.

Вам нужно добавить этот JSON парсер в ваш проект. Следуйте инструкциям по установке в ссылке.

Структура ответа выглядит следующим образом:

enter image description here

Итак, все сводится к следующему:

Option Explicit

Sub intel()
Dim req As New WinHttpRequest 'add a reference to Microsoft WinHTTP Services 5.1. MSXML2 works fine as well
Dim url As String, ids As String
Dim responseJSON As Object
ids = "192481"
url = "https://ark.intel.com/libs/apps/intel/support/ark/recommendedCustomerPrice?ids=" & ids & "&siteName=ark"
With req
    .Open "GET", url, False
    .send
    Set responseJSON = JsonConverter.ParseJson(.responseText)
End With
Debug.Print responseJSON(1)("displayPrice") 'For demonstration purposes the price is printed in the immediate window
End Sub
1 голос
/ 20 марта 2020

Как вы заметили, данные не встраиваются в html, а загружаются через Javascript с использованием внешнего JSON API:

https://ark.intel.com/libs/apps/intel/support/ark/recommendedCustomerPrice?ids=192481&mmids=999C0G&siteName=ark

Этот URL создан с использованием идентификатора продукта 192481 и siteName ark. Удаление mmids возвращает только тот продукт, которого должно быть достаточно (если вам не нужен код заказа?):

https://ark.intel.com/libs/apps/intel/support/ark/recommendedCustomerPrice?ids=192481&siteName=ark

Идея состоит в том, что вы извлекаете идентификатор продукта с вашего исходного URL:

https://ark.intel.com/content/www/us/en/ark/products/[PRODUCT_ID_HERE]/intel-xeon-platinum-8268-processor-35-75m-cache-2-90-ghz.html.

и вместо этого вызывайте этот API

...