【问题标题】:HTMLDocument object missing methods in Visual Studio [duplicate]Visual Studio中的HTMLDocument对象缺少方法[重复]
【发布时间】:2018-01-05 15:43:24
【问题描述】:

我对编程比较陌生,并且在 VBA 中编写了一个网络爬虫,我正在尝试在 Visual Studio 上的 VB.Net 中重新创建它。我正在使用我在 vba 中使用的相同对象(mshtml.HTMLDocument),但由于某种原因,在 Visual Studio 中,它似乎缺少对我的程序至关重要的 .getElementsByClassName 方法。我只是不明白为什么如果我使用与在 VBA 中创建时相同的参考库和相同的对象,它会在 Visual Studio 上的 VB.net 中丢失。

是不是我做错了什么?

VBA Intellisense & Reference Library

Visual Studio VB.Net Intellisense, Reference Library, & Error

【问题讨论】:

  • @TnTinMin 我不认为 IHMTLDocument6 或 7 在 Visual Studio 中是一个选项。它似乎只上升到 IHTMLDocument5。但是,当我在 VBA 中查看它时,它确实显示了 IHMTLDocument6 和 IHMTLDocument7。
  • 您是否阅读、理解并实施了我指出的答案?您需要为计算机上安装的当前版本的 MsHtml 创建一个基于类型库的互操作程序集,然后引用该互操作库;不是 GAC 中的那个。
  • 对不起,一开始我误解了你的意思。我只是按照链接中所说的做了,现在它正在工作。谢谢!

标签: vb.net vba visual-studio


【解决方案1】:

System.Windows.Forms.HtmlDocument(在 VB.NET 中)不是 mshtml.HtmlDocument(在 VBA 中)。没有看到相关代码,我不能确定你没有用前者。

您可以编写自己的方法来获取具有特定类名的元素,而不是通过额外的步骤来获取后者,例如

Public Class Form1

    Dim wb As WebBrowser

    Function GetElementsHavingClassName(doc As HtmlDocument, className As String) As List(Of HtmlElement)
        Dim elems As New List(Of HtmlElement)

        For Each elem As HtmlElement In doc.All
            Dim classes = elem.GetAttribute("className")
            If classes.Split(" "c).Any(Function(c) c = className) Then
                elems.Add(elem)
            End If
        Next

        Return elems

    End Function

    Sub ExtractElements(sender As Object, e As WebBrowserDocumentCompletedEventArgs)
        Dim wb = DirectCast(sender, WebBrowser)
        Dim flintstones = GetElementsHavingClassName(wb.Document, "flintstone")

        If flintstones.Count > 0 Then
            For Each fs In flintstones
                ' do something with the element
                TextBox1.AppendText(fs.InnerText & vbCrLf)
            Next
        Else
            TextBox1.Text = "Not found."
        End If

    End Sub

    Sub DoStuff()
        If wb Is Nothing Then
            wb = New WebBrowser
        End If

        RemoveHandler wb.DocumentCompleted, AddressOf ExtractElements ' don't leave any old ones lying around
        AddHandler wb.DocumentCompleted, AddressOf ExtractElements

        Dim loc = "file:///c:\temp\somehtml.html"

        Try
            wb.Navigate(loc)
        Catch ex As Exception
            'TODO: handle the problem gracefully.
            MsgBox(ex.Message)
        End Try

    End Sub

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        DoStuff()

    End Sub

    Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles MyBase.FormClosing
        If wb IsNot Nothing Then
            RemoveHandler wb.DocumentCompleted, AddressOf ExtractElements
            wb.Dispose()
        End If

    End Sub

End Class

根据 HTML

<!DOCTYPE html>
<html>
<head><title></title></head>
<body>
<div class="fred flintstone">Fred</div>
<div class="wilma flintstone">Wilma</div>
<div class="not-a-flintstone">Barney</div>
</body>
</html>

输出

弗雷德
威尔玛

【讨论】:

  • 我用 Dim HtmlDoc As New mshtml.HTMLDocument 声明它,这与我在 VBA 代码中声明它的方式相同,它们都使用同一个库。另外,自定义函数最终不会变慢吗?
  • @Devan382 TnTinMn 建议的副本似乎可以解释如果您别无选择该怎么办,但请注意,这将是一个脆弱的解决方案。自定义方法不一定会更慢 - 并且程序的其他部分可能会被加速而不是弥补它。例如,您甚至可能不需要浏览器来花时间渲染页面,而是可以使用HtmlAgilityPack。但是,我建议你先让它工作,然后看看是否真的需要任何改进;)
  • 我只是查看了 TntinMin 建议的内容,但在 Visual Studio 中没有看到 IHMTLDocument6 或 7 作为选项。它似乎只上升到 IHTMLDocument5。但是,当我在 VBA 中查看它时,它确实显示了 IHMTLDocument6 和 IHMTLDocument7。
  • 如果必须,我将使用您提供的自定义函数,但我想了解为什么 MSHTML 在 VBA 和 Visual Studio 中显示不同的对象/方法?
  • 我没有使用浏览器或呈现页面。我正在使用 MSXML2.ServerXMLHTTP60 发出请求。我不熟悉 HtmlAgilityPack,那会比我目前使用的更快吗?
猜你喜欢
  • 2020-03-24
  • 1970-01-01
  • 2016-06-15
  • 2014-05-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多