Excel VBA Webscrape, как я могу получить значения диапазона? - PullRequest
0 голосов
/ 11 января 2019

Относительно плохо знаком с VBA и плохо знаком с веб-копированием Мне было поручено получить некоторые данные с веб-сайта. Я пытался найти здесь помощь, пробовал много перестановок, основываясь на том, что я нашел, но не получил нужные мне результаты. Фрагмент веб-страницы DOM Explorer (с использованием «F12 Developer Tools») показывает следующее (отредактировано, чтобы сделать его общим):

<div class=”nav nav-list”>
<div>
<span class=”nav-list-item”>Item:</span>
        <span>
            mySearchString and other text
        </span>
</div>
<div>…</div>
<div>
        <span class=”nav-list-item”>Retail UPC:</span>
        <span>upcNumber</span>
</div>
<div>…</div>
</div>
</div>

Я пытаюсь найти «mySearchString», извлекаю «и другой текст», ищу «Retail UPC:» и извлекаю «upcNumber».

Пробовал использовать вложенные операторы if, но не мог заставить их работать. Ниже приведен фрагмент последней версии того, с чем я играл:

Dim harborDesc() as String
Dim ieObj As InternetExplorer
Set ieObj = CreateObject("InternetExplorer.Application")    
Dim htmlEle As Object
Dim itemurl As String

Itemurl = “url of interest”
ieObj.navigate itemurl    'in this case, the web page is has the same name as the itemNum
Do While ieObj.readyState <> READYSTATE_COMPLETE  'wait by repeating loop until ready
Loop

For Each htmlEle In ieObj.document.getElementsByClassName("nav-list-item")
                harborDesc = Split(htmlEle.innerText, htmlEle.getElementsByTagName("span")(1).innerText)
Next htmlEle

Заранее спасибо за любые советы / помощь

Ответы [ 2 ]

0 голосов
/ 11 января 2019

Вы можете настроить нодлист и зациклить их в поиске по поисковым запросам.

nodeList генерируется из запроса css с синтаксисом Or, что означает, что вы получите

<span class="nav-list-item">  

, но также соответствуют тем элементам, которые являются тегом span соседний брат например,

<span class="nav-list-item">Retail UPC:</span> 
<span>upcNumber</span> 

image

Вы используете Instr в .innerText, чтобы соответствовать первому поисковому запросу. Затем, если найдено, используйте Replace, чтобы удалить сопоставленный текст, и оставьте остаток, как указано в вашем вопросе.

Если вы найдете Retail UPC по данному индексу, тогда upcNumber должно быть по следующему индексу.


VBA:

Option Explicit
Public Sub FindInfo()
    Const SEARCH_TERM1 As String = "mySearchString"
    Const SEARCH_TERM2 As String = "Retail UPC:"
    Dim html As HTMLDocument, searchTermCandidates As Object
    Dim i As Long, index As Long, ieObj As InternetExplorer
    Set ieObj = New InternetExplorer
    With ieObj
        .Visible = True
        .Navigate2 "url"

        While .Busy Or .readyState < 4: DoEvents: Wend

        Set html = .document

        Set searchTermCandidates = html.querySelectorAll("span.nav-list-item, span.nav-list-item + span")
        For i = 0 To searchTermCandidates.Length - 1
            If InStr(searchTermCandidates.item(i).innerText, SEARCH_TERM1) > 0 Then
                Debug.Print Replace$(searchTermCandidates.item(i).innerText, SEARCH_TERM1, vbNullString)
            End If
            If searchTermCandidates.item(i).innerText = SEARCH_TERM2 Then
                Debug.Print searchTermCandidates.item(i + 1).innerText
            End If
        Next
        .Quit
    End With
End Sub
0 голосов
/ 11 января 2019

Возможно, что htmlEle.getElementsByTagName("span")(1) пытается вернуть массив элементов, где есть только 1, и, таким образом, единственное возвращаемое значение этого массива будет находиться в первой точке массива htmlEle.getElementsByTagName("span")(0).

Кроме того, то, как вы используете Split(), не имеет смысла для меня. Параметрами для Split() являются Split(expression, [ delimiter, [ limit, [ compare ]]]), означающие, что .innertext элемента <span>, который вы ищете, будет разделителем? Кроме того, я нигде не вижу, чтобы harborDesc определялся как массив соответствующего размера (или любого размера) в первую очередь, что, вероятно, объясняет ваш Error 91, так как Split() нужен массив для принять значения.

EDIT:

Добавлю это из моих комментариев.

Если вам нужен текст из внутреннего текста <span>, вы должны делать что-то вроде

Dim harborDesc() As String
Redim harborDesc(0 to 1) 
For Each htmlEle In ieObj.document.getElementsByClassName("nav-list-item") 
    Redim Preserve harborDesc(0 to UBound(harborDesc) + 1)
    harborDesc(UBound(harborDesc) - 1) = htmlEle.getElementsByTagName("span")(0).innerText
Next htmlEle

РЕДАКТИРОВАТЬ 2:

Если у вас возникают проблемы с поиском элементов «span», возможно, вы находите соответствующий класс «nav-list-item», в котором нет элемента «span». В этом случае было бы целесообразно создать вложенный For-Loop для проверки, например

Dim ieObj As InternetExplorer
Set ieObj = CreateObject("InternetExplorer.Application")    
Dim htmlEle As Object
Dim spanEle as Object
Dim itemurl As String

Itemurl = “url of interest”
ieObj.navigate itemurl    'in this case, the web page is has the same name as the itemNum
Do While ieObj.readyState <> READYSTATE_COMPLETE  'wait by repeating loop 
until ready
Loop

For Each htmlEle In ieObj.document.getElementsByClassName("nav-list-item")
    For Each spanEle in htmlEle.getElementsByTagName("span")
        Debug.Print spanEle.innertext
    Next spanEle
Next htmlEle
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...