【问题标题】:What is the best way to retrieve specific elements from an HTML page in VBA?从 VBA 中的 HTML 页面检索特定元素的最佳方法是什么?
【发布时间】:2018-07-24 13:39:58
【问题描述】:

我有一个带有一些 URL 的 Excel 工作表,我正在尝试编写一个宏来使用 Fortigate 的 Web 过滤器填充网站类别。例如,工作表上的一个单元格可能包含“www.google.com”,网站将其归类为 URL https://fortiguard.com/webfilter?q=google.com 的“搜索引擎和门户网站”。

我很难尝试解析 HTML 以获取类别。 HTML 看起来像:

<DIV class=sidebar-content>
<H4>WF Rating History</H4>
<P><SPAN style="FONT-SIZE: 10px"><EM>Jun 10th, 2008 @ 17:45:24 PDT</EM></SPAN><BR>added as <STRONG>Search Engines and Portals</STRONG></P>
<DIV><A href="about://forticlient.com/" target=_blank><IMG src="about:/static/images/forticlient_share_button.png?v=5"></A> </DIV></DIV>

我用来获取的代码如下(我只是在尝试一个站点,并假设它位于工作表上的 A1 上):

    Sub siteCatgories()

    Dim xhr As MSXML2.XMLHTTP60
    Dim doc As MSHTML.HTMLDocument

    Set xhr = New MSXML2.XMLHTTP60

    Url = Cells(1, 1).Value

    With xhr
    .Open "GET", "https://fortiguard.com/webfilter?q=" & Url, False
    .send

    If .readyState = 4 And .Status = 200 Then
        Set doc = New MSHTML.HTMLDocument
        doc.body.innerHTML = .responseText
    End If
    End With

    'retrieve relevant HTML
    Debug.Print doc.getElementsByClassName("sidebar-content").toString

    End Sub

上面的调试语句只返回[Object]。 任何有关如何在 VBA 中解析网站 HTML 的帮助将不胜感激!

【问题讨论】:

  • 您能详细说明一下吗?您到底想从网页中提取什么。?您要提取哪些字段?
  • Debug.Print doc.getElementsByClassName("sidebar-content")(0).toStringgetElementsByClassName 是复数;即一个集合)

标签: html excel vba xmlhttprequest


【解决方案1】:

这种简单的解析可以使用Split()而不是HTMLDocument来完成:

Sub Test()

    MsgBox Join(GetData("google.com"), vbCrLf)

End Sub

Function GetData(sUrl)

    Dim tmp

    With CreateObject("MSXML2.XMLHTTP")
        .Open "GET", "https://fortiguard.com/webfilter?q=" & sUrl, False, "u051772", "fy17janr"
        .Send
        tmp = .ResponseText
    End With
    tmp = Split(tmp, "WF Rating History", 2)(1)
    tmp = Split(tmp, "<em>", 2)(1)
    tmp = Split(tmp, "</strong>", 2)(0)
    tmp = Split(tmp, "</em>", 2)
    tmp(1) = Split(tmp(1), "<strong>", 2)(1)
    GetData = tmp

End Function

输出:

【讨论】:

  • 我想我担心,由于缺乏经验,这种方法有多强大?您是否会根据网页布局的“稳定性”程度(即您对其布局/格式随时间的一致性的印象)来确定它的适当性?我可以阅读有关如何决定在抓取时使用哪种方法的任何参考资料?顺便说一句,我认为有用但很感兴趣。
【解决方案2】:

试试这个怎么样:

Sub Fetch_Data()
    Dim http As New ServerXMLHTTP60, HTML As New HTMLDocument
    Dim post As Object

    With http
        .Open "GET", "https://fortiguard.com/webfilter?q=google.com", False
        .send
        HTML.body.innerHTML = .responseText
    End With

    For Each post In HTML.getElementsByClassName("sidebar-content")
        With post.getElementsByTagName("em")
            If .Length Then Row = Row + 1: Cells(Row, 1) = .Item(0).innerText
        End With
        With post.getElementsByTagName("strong")
            If .Length Then Cells(Row, 2) = .Item(0).innerText
        End With
    Next post
End Sub

输出:

Jun 10th, 2008 @ 17:45:24 PDT
Search Engines and Portals

添加到库的参考:

1.Microsoft Html Object Library
2.Microsoft XML, V6.0  

【讨论】:

    猜你喜欢
    • 2011-01-02
    • 2014-05-12
    • 1970-01-01
    • 1970-01-01
    • 2011-09-15
    • 1970-01-01
    • 2011-06-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多