VBA - извлекать текст с веб-страницы без уникального класса или тега, но с уникальным предшествующим текстом - PullRequest
1 голос
/ 29 октября 2019

Я пытался написать VBA, чтобы получить по одному уникальному номеру из каждого набора похожих веб-страниц. Все они очень похожи, но текущий код, который я использую, использует MSXML2.XMLHTTP и идентифицирует текст в данном классе или теге.

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

Однако, есть уникальный фрагмент текста («ISIN Code:»), а затем номер ISIN, который я хочу, следует в следующей строке. Я слышал об анализе по идентификаторам, но не могу найти их / не знаю, как работает этот подход.

Часть информации, которую я хочу получить, - это "GB00B6Y7NF43":

<tr>
    <th class="align-left">ISIN code:</th>
    <td> GB00B6Y7NF43 </td>
</tr>

Это большая часть кода, который я сейчас использую, чтобы найти некоторую другую информацию на странице, используя подход Item (...). Я не знаю, правильно ли мой код сам по себе, но до сих пор он правильно извлекает информацию, если вы укажете Item (0) или Item (1) и т. Д.

Dim request As Object
Dim response As String
Dim html As New HTMLDocument
Dim td As Object
Dim website As String
Dim charge As Variant

With Worksheets("Sheet1")

website = Range("A14").Value

End With

Set request = CreateObject("MSXML2.XMLHTTP")

request.Open "GET", website, False

request.send

response = StrConv(request.responseBody, vbUnicode)

html.body.innerHTML = response

Worksheets("Information").Activate

        r = r + 2:
        Cells(r, 3) = html.getElementsByClassName("header-row").Item(0).innerText
        Cells(r, 5) = html.getElementsByTagName("td").Item(0).innerText
        Cells(r, 4) = html.getElementsByClassName("icon-link pdf-icon").Item(1).href

Может кто-нибудь помочь мнепредложить подход / стиль кодирования / настройки моего кода, чтобы позволить мне сделать это, потому что я совершенно потерян. Я немного новичок в этом тоже. Спасибо.

Я мог бы пойти дальше и использовать dim ie / appIe и аналогичные методы, но они до сих пор были хитрее и медленнее, чем просто работа с html-текстом.

1 Ответ

0 голосов
/ 29 октября 2019

Это последний дочерний элемент в таблице, поэтому вы можете связать lastchild вызовы

html.querySelector("[summary='More fund information']").children(0).lastchild.lastchild.innertext

Так что

Option Explicit
Public Sub test()
    Dim html As HTMLDocument

    Set html = New HTMLDocument

    With CreateObject("MSXML2.XMLHTTP")
        .Open "GET", "https://www.hl.co.uk/funds/fund-discounts,-prices--and--factsheets/search-results/f/fidelity-asia-class-w-accumulation/key-features", False
        .send
        html.body.innerHTML = .responseText
    End With
    Debug.Print html.querySelector("[summary='More fund information'] ").Children(0).LastChild.LastChild.innerText
End Sub

Более медленный, но, возможно, более надежный во времени метод можетчтобы собрать заголовки таблицы и найти нужный текст ISIN, а затем взять узел NextSibling (td).

Option Explicit
Public Sub test()
    Dim html As HTMLDocument

    Set html = New HTMLDocument

    With CreateObject("MSXML2.XMLHTTP")
        .Open "GET", "https://www.hl.co.uk/funds/fund-discounts,-prices--and--factsheets/search-results/f/fidelity-asia-class-w-accumulation/key-features", False
        .send
        html.body.innerHTML = .responseText
    End With

    Dim i As Long, nodes As Object

    Set nodes = html.querySelectorAll("[summary='More fund information'] th")
    For i = 0 To nodes.Length - 1
        If nodes.Item(i).innerText = "ISIN code:" Then
            Debug.Print nodes.Item(i).NextSibling.innerText
            Exit For
        End If
    Next
End Sub
...