如何在vba中获取网页上的下一个元素

时间:2019-02-22 16:45:27

标签: vba element webpage

我正在尝试构建VBA宏以从http://stt.wiki网站中提取大量数据。具体来说,我从页面https://stt.wiki/wiki/Galaxy_Event开始,我想下拉至以“ Galaxy Events”开头的部分,并将每个项目从其下方的列表中拉出。

所以,我有以下内容:

Dim IE As New InternetExplorer
IE.Visible = True
IE.navigate "https://stt.wiki/wiki/Galaxy_Event"
Do
    DoEvents
Loop Until IE.readyState = READYSTATE_COMPLETE
Dim Doc As HTMLDocument
Set Doc = IE.document
Dim sH2 As String

我知道我能做     sH2 = Trim(Doc.getElementsByClassName(“ mw-headline”)(0).innerText)

查看等同于“ Galaxy Events”的元素,但是我找不到找到下一个元素的方法,因为它不是与Galaxy Events共享任何属性的元素。我犹豫用LI(Doc.getElementsByTagName(“ li”)(9))来定位它,因为该网站可能会更改并破坏我正在做的所有事情(尽管我想我可以遍历LI项,直到找到一个没有类的项)

无论如何,当它在各个方面都是不同的类型时,我将如何直接跳到下一个元素(我尝试了FirstChild。这返回了错误。)

1 个答案:

答案 0 :(得分:1)

网络抓取本质上是脆弱的。 API是接收内容的最佳方法。

在没有API的情况下,我将收集该部分中的链接列表,并在查找特定标题时循环

Option Explicit
'VBE > Tools > References:
' Microsoft Internet Controls
Public Sub GetData()
    Dim ie As New InternetExplorer, i As Long
    With ie
        .Visible = True
        .Navigate2 "https://stt.wiki/wiki/Galaxy_Event"
        While .Busy Or .readyState < 4: DoEvents: Wend

        Dim galaxyEvents As Object
        Set galaxyEvents = .document.querySelectorAll("ol li > a[title]")
        For i = 0 To galaxyEvents.Length - 1
            Debug.Print galaxyEvents.item(i).Title
            'Or any comparison required here then Exit For if found
        Next
        .Quit
    End With
End Sub

看起来您可以尝试使用存在的API,尽管我不得不通过相关的Wiki API语法来破解自己的方式。需要先jsonconverter.bas添加到项目,然后再添加VBE>工具>引用>添加对Microsoft脚本运行时的引用。

Option Explicit
Public Sub GetInfo()
    Dim json As Object, dict As Object, link As String
    Const BASE_URL As String = "https://stt.wiki/wiki/"

    With CreateObject("MSXML2.XMLHTTP")
        .Open "GET", "https://stt.wiki/w/api.php?action=parse&format=json&page=Galaxy_Event&section=1", False
        .send
        Set json = JsonConverter.ParseJson(.responseText)("parse")("links") '<==Will include references links
        For Each dict In json
            link = dict("*")
            Debug.Print link
            Debug.Print BASE_URL & Replace$(link, Chr$(32), Chr$(95))
        Next
    End With
End Sub

对于API,我在html中找到了您提供的URL的this。然后,我浏览了相关文档here