Метод VBA GetElementsById "Переменная объекта не установлена" - PullRequest
0 голосов
/ 28 сентября 2018

Я пытаюсь выбрать идентификатор главного меню этой страницы http://greyhoundstats.co.uk/index.php с пометкой ("menu_wholesome"), чтобы позже получить их гиперссылки.В HTML-документе есть два тега с этим идентификатором: <div> и его дочерний элемент <ul>, но когда я ищу их с помощью приведенного ниже кода, я получаю сообщение об ошибке «переменная объекта не установлена».

Option Explicit

Public Const MenuPage As String = "http://greyhoundstats.co.uk/index.php"

Sub BrowseMenus()

Dim XMLHTTPReq As New MSXML2.XMLHTTP60
Dim HTMLDoc As New MSHTML.HTMLDocument

Dim MainMenuList As MSHTML.IHTMLElement
Dim aElement As MSHTML.IHTMLElementCollection
Dim ulElement As MSHTML.IHTMLUListElement
Dim liElement As MSHTML.IHTMLLIElement

XMLHTTPReq.Open "GET", MenuPage, False
XMLHTTPReq.send

HTMLDoc.body.innerText = XMLHTTPReq.responseText

    Set MainMenuList = HTMLDoc.getElementById("menu_wholesome")(0) '<-- error happens here

End Sub

Кто-нибудь знает, почему getElementsById не может найти ссылочный идентификатор, хотя он является частью набора документов HTML? Я знаю, что этот метод должен возвращать уникальный идентификатор, но когда у нас такой жессылаясь на другие теги, я также знаю, что верну первый найденный идентификатор, который должен быть <div id="menu_wholesome"> частью запрашиваемой HTML-страницы.

Ответы [ 2 ]

0 голосов
/ 28 сентября 2018

Во-первых: вы хотите работать и установить innerHTML так, как вы собираетесь проходить документ DOM.

Во-вторых: эта строка

Set MainMenuList = HTMLDoc.getElementById("menu_wholesome")(0)

Это неверно.getElementById возвращает один элемент, в который нельзя индексировать.Вы индексируете в коллекцию.

Обратите внимание: и div, и ul ведут к одному и тому же содержимому.

Если вы хотите выбрать их отдельно, используйте querySelector

HTMLDoc.querySelector("div#menu_wholesome")
HTMLDoc.querySelector("ul#menu_wholesome")

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

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

HTMLDoc.querySelectorAll("#menu_wholesome")

Затем вы можете индексировать в список узлов, например,

HTMLDoc.querySelectorAll("#menu_wholesome").item(0)

VBA:

Option Explicit

Public Const MenuPage As String = "http://greyhoundstats.co.uk/index.php"
Sub BrowseMenus()
    Dim sResponse As String, HTMLDoc As New MSHTML.HTMLDocument
    Dim MainMenuList As Object, div As Object, ul As Object

    With CreateObject("MSXML2.XMLHTTP")
        .Open "GET", MenuPage, False
        .setRequestHeader "If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT"
        .send
        sResponse = StrConv(.responseBody, vbUnicode)
    End With

    sResponse = Mid$(sResponse, InStr(1, sResponse, "<!DOCTYPE "))
    HTMLDoc.body.innerHTML = sResponse

    Set MainMenuList = HTMLDoc.querySelectorAll("#menu_wholesome")

    Debug.Print MainMenuList.Length

    Set div = HTMLDoc.querySelector("div#menu_wholesome")
    Set ul = HTMLDoc.querySelector("ul#menu_wholesome")

    Debug.Print div.outerHTML
    Debug.Print ul.outerHTML

End Sub
0 голосов
/ 28 сентября 2018

Неясно, чего вы пытаетесь достичь.Я только что исправил текущую проблему, с которой вы столкнулись в данный момент. .getElementById () имеет дело с отдельным элементом, поэтому, когда вы рассматриваете его как коллекцию элементов, он выдаст эту ошибку.Если вы заметили эту часть getElementBy и getElementsBy , вы можете увидеть вариант того, какой из них является набором элементов (нене замечать с ).Вы можете использовать (0) или что-то подобное, когда используете getElementsBy .

Вы должны делать отступ в своем коде правильным образом, чтобы другие могли его прочитатьбез проблем:

Sub BrowseMenus()
    Const MenuPage$ = "http://greyhoundstats.co.uk/index.php"
    Dim HTTPReq As New XMLHTTP60, HTMLDoc As New HTMLDocument
    Dim MainMenuList As Object

    With HTTPReq
        .Open "GET", MenuPage, False
        .send
        HTMLDoc.body.innerHTML = .responseText
    End With

    Set MainMenuList = HTMLDoc.getElementById("menu_wholesome")
End Sub
...