InnerText возвращает пустое значение для указанного класса c span - PullRequest
0 голосов
/ 02 февраля 2020

Я пытаюсь получить информацию о ценах обычной (126,37 €) и сниженной (101,10 €) информации с этого сайта.

Упрощенный код HTML выглядит следующим образом:

<div class="vw-productFeatures ">
  <ul class="feature-list -price-container">
    <li class="feature -price">
      <span class="value">126,37</span>
    </li>
  </ul>
  <ul class="feature-list vw-productVoucher">
    <li class="voucher-information">Mit Code
      <span class="voucher-reduced-price">101,10</span>
    </li>
  </ul>
</div>

Итак, я в основном go шаг за шагом (div класс -> ul class -> li class -> span class) и получаю innerText в конце.

I Я могу получить обычную цену, однако spanclass.innerText по сниженной цене возвращается пустым.

Это код, с которым я работаю:

Function getHTMLelemFromCol(HTMLColIn As MSHTML.IHTMLElementCollection, tagNameIn As String, classNameIn As String) As MSHTML.IHTMLElement
    Dim HTMLitem As MSHTML.IHTMLElement

    For Each HTMLitem In HTMLColIn
        If (HTMLitem.tagName = tagNameIn) Then
            If (HTMLitem.className = classNameIn) Then
                Set getHTMLelemFromCol = HTMLitem
                Exit For
            End If
        End If
    Next HTMLitem
End Function
Function getPrice(webSite As String, divClass As String, ulClass As String, liClass As String, spanClass As String) As String
    Dim XMLPage As New msxml2.XMLHTTP60
    Dim HTMLDoc As New MSHTML.HTMLDocument
    Dim HTMLitem As MSHTML.IHTMLElement
    Dim HTMLObjCol As MSHTML.IHTMLElementCollection

    XMLPage.Open "GET", webSite, False
    XMLPage.send
    HTMLDoc.body.innerHTML = XMLPage.responseText

    Set HTMLObjCol = HTMLDoc.getElementsByClassName(divClass)
    Set HTMLitem = getHTMLelemFromCol(HTMLObjCol, "DIV", divClass)          ' Find the div class we are interested in first
    Set HTMLitem = getHTMLelemFromCol(HTMLitem.Children, "UL", ulClass)     ' Find the ul class we are interested in
    Set HTMLitem = getHTMLelemFromCol(HTMLitem.Children, "LI", liClass)     ' Find the li class we are interested in
    Set HTMLitem = getHTMLelemFromCol(HTMLitem.Children, "SPAN", spanClass) ' Find the span class we are interested in

    getPrice = HTMLitem.innerText
End Function
Sub Run()
    Dim webSite As String, divClass As String, ulClass As String, liClass As String, spanClass As String, regularPrice As String, reducedPrice As String

    webSite = "https://www.rakuten.de/produkt/msi-b450-tomahawk-max-atx-mainboard-4x-ddr4-max-64gb-1x-dvi-d-1x-hdmi-14-1x-usb-c-31-2843843890"
    divClass = "vw-productFeatures "

    ' Get the regular price
    ulClass = "feature-list -price-container"
    liClass = "feature -price"
    spanClass = "value"
    regularPrice = getPrice(webSite, divClass, ulClass, liClass, spanClass)

    ' Get the reduced price
    ulClass = "feature-list vw-productVoucher -hide"
    liClass = "voucher-information"
    spanClass = "voucher-reduced-price"
    reducedPrice = getPrice(webSite, divClass, ulClass, liClass, spanClass)

    Debug.Print "Regular price: " & regularPrice
    Debug.Print "Reduced price: " & reducedPrice
End Sub

Вывод, который я получаю:

Regular price: 126,37
Reduced price: 

Отладчик показывает, что он может найти правильный класс span, но у него нет атрибута (включая innerText), который содержит информацию о цене.

Как получить сокращенный информация о цене?

Ответы [ 2 ]

1 голос
/ 03 февраля 2020

Иногда, когда большая часть содержимого страницы зависит от вызовов API, проще использовать автоматизацию браузера.

Он не идеален с точки зрения производительности, но быстрее работает и работает в крайнем случае. Альтернативный подход заключается в мониторинге веб-трафика c между вами и сервером и проверке возможности эмуляции веб-запросов для получения сниженной цены. Это будет быстрее, но может потребоваться некоторое время, чтобы понять, как это работает.

Есть компромиссы для каждого подхода к рассмотрению. Ниже приведен код Inte rnet Explorer Automation, который работает для меня, чтобы получить данные, которые, я полагаю, вам нужны.

Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

Sub GetReducedPrice()
    Dim text As String

    With CreateObject("internetexplorer.application")
        .navigate "https://www.rakuten.de/produkt/msi-b450-tomahawk-max-atx-mainboard-4x-ddr4-max-64gb-1x-dvi-d-1x-hdmi-14-1x-usb-c-31-2843843890"
         Do While .Busy And .readyState <> 4: DoEvents: Loop
         Sleep 1000 ' wait a little bit too
         text = .document.querySelector(".voucher-reduced-price").innerText
        .Quit
    End With

    Debug.Print "the reduced price is: " & text
End Sub

Результат:

the reduced price is: 101,10

0 голосов
/ 02 февраля 2020

Нет класса -hide для снижения цены:

ulClass = "feature-list vw-productVoucher"

Вы можете использовать простые селекторы, чтобы получить обе цены с querySelector ( пример ) вместо сложных методов с ненужными итераций.

regularPrice = HTMLDoc.querySelector(".-price .value").innerText
reducedPrice = HTMLDoc.querySelector(".voucher-reduced-price").innerText

Обновление: Ваучер здесь https://tags.tiqcdn.com/utag/rakuten/main/prod/utag.js и рассчитывается на основе product_shop_id и дат.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...