VBA возвращает html элемент href из таблицы классов - PullRequest
0 голосов
/ 13 апреля 2020

У меня есть такая структура html:

<table class="series">
<tr>
    <th>1.</th>
    <td><div><a href="?id=12">1st part</a></div></td>
</tr>
<tr>
    <th>2.</th>
    <td><div><a href="?id=13">2nd part</a></div></td>
</tr>
<tr>
    <th>3.</th>
    <td><div><a href="?id=14">3rd part</a></div></td>
</tr>
<tr>
    <th>4.</th>
    <td><div><a href="?id=15">4th part</a></div></td>
</tr>
<tr>
    <th>5.</th>
    <td><b>5th part</b></td>
</tr>
<tr>
    <th>6.</th>
    <td><div><a href="?id=16">6th part</a></div></td>
</tr>

, и мне нужно получить URL href всегда предыдущей части, в которой я сейчас. Как вы можете видеть, в этом html я в 5-й части, поэтому мне нужно вернуть «? Id = 15» как предыдущую часть, где я на самом деле. Дело в том, что текущая часть может быть где угодно 1-й (в этом случае return будет NULL), 2-й, 10-й, 50-й. Или даже весь этот класс может отсутствовать на странице, поэтому return должен быть также NULL.

мой прогресс такой:

 Sub GetPageTitle()
    Set IE = CreateObject("InternetExplorer.Application")
    With IE
        .Visible = True
        .Navigate "www.something.com/do.php?id=5"
        Do Until .ReadyState = 4
            DoEvents
        Loop

        'Series
        Set my_data = .Document.getElementsByClassName("series")
        Dim link
        Dim i As Long: i = 2
        For Each elem In my_data
            Set link = elem.getElementsByTagName("a")(0)

            'copy the data to the excel sheet
            Debug.Print link.href
            Debug.Print link.innerText
            i = i + 1
        Next

        .Quit
    End With
End Sub
  • это было для того, чтобы просто отладить каждый href в элементе, однако для l oop не работает, он всегда отлаживается только один раз ...

Я, конечно, пытался заменить (0) на некоторые автоматические c приращения i , но без изменений. А также, если я придумаю отладку, у меня все еще нет идеи получить результат URL предыдущей части: (

Ответы [ 2 ]

0 голосов
/ 13 апреля 2020

Используя следующие допущения

no class 'series' then null (or better to use table.series ?) With just series assumption is it only occurs for table element

if no bold in table then null

else iterate rows using counter 

if bold found:
    if row = 0  then 
        null 
    else test row - 1  (prior row)
        if has single href attribute then href else null

, вы можете написать оператор выбора и суррогатную переменную htmldocument для применения каждого теста внутри вспомогательной функции

Option Explicit

Public Sub PrintPriorHref()
    Dim html As MSHTML.HTMLDocument, table As MSHTML.HTMLTable, ie As SHDocVw.InternetExplorer

    Set ie = New SHDocVw.InternetExplorer
    Set html = New MSHTML.HTMLDocument

    With ie
        .Visible = True
        .navigate "www.something.com/do.php?id=5"
        Do: DoEvents: Loop While .Busy Or .readyState <> READYSTATE_COMPLETE

        html.body.innerHTML = .document.body.innerHTML

        Set table = html.querySelector(".series")
        Debug.Print GetPriorHref(table)
        .Quit
    End With

End Sub

Public Function GetPriorHref(ByVal table As MSHTML.HTMLTable) As Variant
    Dim i As Long, html As MSHTML.HTMLDocument

    Set html = New MSHTML.HTMLDocument

    Select Case True
    Case table Is Nothing
        GetPriorHref = Null ' "Null"
    Case table.getElementsByTagName("b").Length <> 1
        GetPriorHref = Null
    Case Else
        Dim r As MSHTML.HTMLTableRow

        For Each r In table.rows
            html.body.innerHTML = r.outerHTML

            If html.querySelectorAll("b").Length > 0 Then
                Select Case i
                Case 0
                    GetPriorHref = Null '"Null"
                Case Is > 0
                    Dim anchorList As Object

                    html.body.innerHTML = table.rows(i - 1).outerHTML
                    Set anchorList = html.querySelectorAll("[href]")

                    If anchorList.Length <> 1 Then
                        GetPriorHref = Null ' "Null"
                    Else
                        GetPriorHref = anchorList(0).href
                    End If
                End Select
            End If
            i = i + 1
        Next
    End Select
End Function

Обязательные ссылки (VBE> Инструменты> Ссылки):

  1. Microsoft Inte rnet Элементы управления
  2. Microsoft HTML Библиотека объектов
0 голосов
/ 13 апреля 2020

Если имеется несколько таблиц серий и вам нужны все ссылки, вам нужно l oop через все серии (что вы уже сделали), а затем l oop через все ссылки в каждой серии, как это

Set my_data = .Document.getElementsByClassName("series")
Dim all_links, link
Dim i As Long: i = 2
For Each elem In my_data
    Set all_links = elem.getElementsByTagName("a")
    For Each link In all_links
        'copy the data to the excel sheet
        Debug.Print link.href
        Debug.Print link.innerText
        i = i + 1
    Next
Next
...