如何在 vba 中获取网页上的下一个元素
How do you get the next element on the webpage in vba
我正在尝试构建一个 VBA 宏以从 http://stt.wiki website. Specifically, I'm starting on the page 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 项目直到找到一个没有 class)
无论如何,如果下一个元素在各个方面都是不同的类型(并且我尝试了 FirstChild。它返回了一个错误。),我将如何继续下降到下一个元素。
Web-scraping 本质上是脆弱的。 APIs 是接收内容的最佳方式。
在没有 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§ion=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 我找到了 this within the html for the url you gave. I then skimmed through the related documentation here。
我正在尝试构建一个 VBA 宏以从 http://stt.wiki website. Specifically, I'm starting on the page 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 项目直到找到一个没有 class)
无论如何,如果下一个元素在各个方面都是不同的类型(并且我尝试了 FirstChild。它返回了一个错误。),我将如何继续下降到下一个元素。
Web-scraping 本质上是脆弱的。 APIs 是接收内容的最佳方式。
在没有 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§ion=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 我找到了 this within the html for the url you gave. I then skimmed through the related documentation here。