Uso de Html Agility Pack para capturar contenido de texto

html html-agility-pack vb.net

Pregunta

Voy a hacer mi mejor esfuerzo para especifico. Básicamente, estoy trabajando en un rastreador en vb.net, por lo que estoy más interesado en extraer el contenido de texto de la página. Mi aplicación actual descarga el cuerpo de la fuente html en un cuadro de texto usando un control de navegador web de la siguiente manera:

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)   Handles Button1.Click
    Dim url As String = "<url>"
    WebBrowser1.Navigate(url)
End Sub

Private Sub WebBrowser1_DocumentCompleted(ByVal sender As System.Object, ByVal e As    System.Windows.Forms.WebBrowserDocumentCompletedEventArgs) Handles WebBrowser1.DocumentCompleted
    TextBox2.Text = WebBrowser1.Document.Body.OuterHtml
End Sub

Ahora, de aquí en adelante, textbox2 se compone de html no deseado que contiene href, img, anuncios, scripts, etc., pero necesito aprovechar todos estos metadatos y capturar el texto sin formato.

Podría aplicar propiedades regex para evitar todas las anomalías, pero creo que HAP es mucho más apropiado para el analizador html.

La búsqueda aquí me llevó a esta página en la que se discute el uso de la técnica de lista blanca mencionada por 'Meltdown'

Etiquetas de tiras HTML Agility Pack NO EN la lista blanca

Pero, ¿cómo lo aplico en vb.net, ya que me parece una gran idea?

Por favor, adivce chicos ..........

EDITAR: Encontré una versión vb.net del código que se muestra a continuación, pero parece que hay un error en

If i IsNot DeletableNodesXpath.Count - 1 Then

Errores: IsNot requiere un operando que tenga tipos de referencia, pero este operando tiene el tipo de valor entero

Aquí está el código:

Public NotInheritable Class HtmlSanitizer Private Sub New () End Sub Private Shared ReadOnly Whitelist como IDictionary (Of String, String ()) Private Shared DeletableNodesXpath Como nueva lista (Of String) ()

Shared Sub New()
    Whitelist = New Dictionary(Of String, String())() From { _
        {"a", New () {"href"}}, _
        {"strong", Nothing}, _
        {"em", Nothing}, _
        {"blockquote", Nothing}, _
        {"b", Nothing}, _
        {"p", Nothing}, _
        {"ul", Nothing}, _
        {"ol", Nothing}, _
        {"li", Nothing}, _
        {"div", New () {"align"}}, _
        {"strike", Nothing}, _
        {"u", Nothing}, _
        {"sub", Nothing}, _
        {"sup", Nothing}, _
        {"table", Nothing}, _
        {"tr", Nothing}, _
        {"td", Nothing}, _
        {"th", Nothing} _
    }
End Sub

Public Shared Function Sanitize(input As String) As String
    If input.Trim().Length < 1 Then
        Return String.Empty
    End If
    Dim htmlDocument = New HtmlDocument()

    htmldocument.LoadHtml(input)
    SanitizeNode(htmldocument.DocumentNode)
    Dim xPath As String = HtmlSanitizer.CreateXPath()

    Return StripHtml(htmldocument.DocumentNode.WriteTo().Trim(), xPath)
End Function

Private Shared Sub SanitizeChildren(parentNode As HtmlNode)
    For i As Integer = parentNode.ChildNodes.Count - 1 To 0 Step -1
        SanitizeNode(parentNode.ChildNodes(i))
    Next
End Sub

Private Shared Sub SanitizeNode(node As HtmlNode)
    If node.NodeType = HtmlNodeType.Element Then
        If Not Whitelist.ContainsKey(node.Name) Then
            If Not DeletableNodesXpath.Contains(node.Name) Then
                'DeletableNodesXpath.Add(node.Name.Replace("?",""));
                node.Name = "removeableNode"
                DeletableNodesXpath.Add(node.Name)
            End If
            If node.HasChildNodes Then
                SanitizeChildren(node)
            End If

            Return
        End If

        If node.HasAttributes Then
            For i As Integer = node.Attributes.Count - 1 To 0 Step -1
                Dim currentAttribute As HtmlAttribute = node.Attributes(i)
                Dim allowedAttributes As String() = Whitelist(node.Name)
                If allowedAttributes IsNot Nothing Then
                    If Not allowedAttributes.Contains(currentAttribute.Name) Then
                        node.Attributes.Remove(currentAttribute)
                    End If
                Else
                    node.Attributes.Remove(currentAttribute)
                End If
            Next
        End If
    End If

    If node.HasChildNodes Then
        SanitizeChildren(node)
    End If
End Sub

Private Shared Function StripHtml(html As String, xPath As String) As String
    Dim htmlDoc As New HtmlDocument()
    htmlDoc.LoadHtml(html)
    If xPath.Length > 0 Then
        Dim invalidNodes As HtmlNodeCollection = htmlDoc.DocumentNode.SelectNodes(xPath)
        For Each node As HtmlNode In invalidNodes
            node.ParentNode.RemoveChild(node, True)
        Next
    End If
    Return htmlDoc.DocumentNode.WriteContentTo()


End Function

Private Shared Function CreateXPath() As String
    Dim _xPath As String = String.Empty
    For i As Integer = 0 To DeletableNodesXpath.Count - 1
        If i IsNot DeletableNodesXpath.Count - 1 Then
            _xPath += String.Format("//{0}|", DeletableNodesXpath(i).ToString())
        Else
            _xPath += String.Format("//{0}", DeletableNodesXpath(i).ToString())
        End If
    Next
    Return _xPath
End Function
End Class

Por favor alguien puede ayudar ??????

Respuesta popular

En lugar de usar IsNot , simplemente use <> . Como está comprobando básicamente, el valor de un entero no es igual al valor de otro entero - 1.

Creo que IsNot no se puede utilizar en enteros.

Editar: Acabo de notar que esto es super super viejo. Acabo de ver la fecha del 26 de julio!



Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué