Почему не работает «Получить элементы по имени»? - PullRequest
2 голосов
/ 09 апреля 2019

Я довольно новичок в программировании.Может кто-то помочь мне с этим?Он всегда вылетает в строке getElementsByName, не могу понять почему ..

Option Explicit
Public Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As LongPtr) 'For 64 Bit Systems


Sub getVerb()
    Dim IE As Object ', objShellWindows As Object
    Dim verb As String, strWebPath As String

    strWebPath = "http://www.conjugation.org/"

    verb = "querer"

    'Navigate to page
    '----------------
    Set IE = CreateObject("InternetExplorer.Application")
    With IE
        .Visible = True
        .Navigate strWebPath
    End With

    'Wait for page
    Do While IE.Busy
        Sleep 250
        DoEvents
    Loop

    'Fill out
    '---------
    'Enter verb
    '<input type="text" size="25" name="word">
    IE.document.getElementsByName("word")(0).Value = verb

    'Set to List
    '<input type="radio" name="rb1" value="list">
    IE.document.getElementsByName("rb1")(0).Value = "list"

    'Press Button Conjugate
    '<input type="submit" name="B1" value="Conjugate">
    IE.document.getElementByName("B1").Click

    'TODO: extract info

    'Exit IE
    '--------
    IE.Quit
    Set IE = Nothing

End Sub

Ответы [ 2 ]

1 голос
/ 09 апреля 2019

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

[x=y] например [value=list] являются attribute = value selectors. input является селектором type . Эти селекторы применяются с помощью querySelector метода объекта HTMLDocument и возвращают первое совпадение в DOM для указанного селектора CSS.

Option Explicit

'VBE > Tools > References:
' Microsoft Internet Controls
Public Sub EnterInfo()
    Dim ie As New InternetExplorer
    Const VERB As String = "querer"

    With ie
        .Visible = True
        .Navigate2 "http://www.conjugation.org/"

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

        With .document
            .querySelector("input").Value = VERB 'first input tag element
            .querySelector("[value=list]").Click '<  first element with value attribute having value of list
            .querySelector("[value=Conjugate]").Click '<  first element with value attribute having value of Conjugate
        End With

        Stop '<= delete me later
        .Quit
    End With
End Sub

Изучение селекторов CSS в вашем браузере (показан Chrome):

enter image description here


Практикующие css-селекторы:

https://flukeout.github.io/

0 голосов
/ 09 апреля 2019

Когда я работаю с иерархической структурой данных, такой как HTML (или JSON в этом отношении), я легко путаюсь, предполагая, над каким элементом данных я работаю.Это особенно верно, если я начну собирать многоуровневые ссылки, как вы сделали (и я видел и сделал гораздо более глубокие уровни, что это).

Поэтому я чаще всего включаю раннее связывание: в этом случае перейдите в Инструменты -> Ссылки и убедитесь, что Библиотека объектов Microsoft HTML отмечена.

Затем,Я распаковываю уровни в промежуточные объекты:

Dim nodeList As IHTMLElementCollection
Set nodeList = IE.document.getElementsByName("word")
nodeList.Item(0).Value = verb

Таким образом, я могу использовать отладчик VBE, исследовать структуры данных и обрести уверенность в том, что я работаю с точным элементом данных и элементом списка (и суб-элемент и т. д.), который я хотел.

Я смог внести следующие изменения в ваш код и заставить его работать на меня:

Option Explicit

Public Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As LongPtr) 'For 64 Bit Systems

Sub getVerb()
    Dim IE As Object                             ', objShellWindows As Object
    Dim verb As String, strWebPath As String

    strWebPath = "http://www.conjugation.org/"

    verb = "querer"

    'Navigate to page
    '----------------
    Set IE = CreateObject("InternetExplorer.Application")
    With IE
        .Visible = True
        .Navigate strWebPath
    End With

    'Wait for page
    Do While IE.Busy
        Sleep 250
        DoEvents
    Loop

    'Fill out
    '---------
    'Enter verb
    '<input type="text" size="25" name="word">
    Dim nodeList As IHTMLElementCollection
    Set nodeList = IE.document.getElementsByName("word")
    nodeList.Item(0).Value = verb

    'Set to List
    '<input type="radio" name="rb1" value="list">
    Set nodeList = IE.document.getElementsByName("rb1")
    nodeList.Item(0).Value = "list"

    'Press Button Conjugate
    '<input type="submit" name="B1" value="Conjugate">
    Set nodeList = IE.document.getElementsByName("B1")
    nodeList.Item(0).Click

    'TODO: extract info

    'Exit IE
    '--------
    IE.Quit
    Set IE = Nothing

End Sub
...