Использование Html Agility Pack для захвата текстового содержимого - PullRequest
1 голос
/ 26 июля 2011

Я сделаю все возможное, чтобы конкретные. В основном работает на гусеничном шасси в vb.net, благодаря чему меня больше интересует извлечение текстового содержимого страницы. Мое текущее приложение загружает текст источника HTML в текстовое поле с помощью элемента управления веб-браузера следующим образом:

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

С этого момента textbox2 состоит из ненужного html, который содержит href, img, ads, script и т. Д., Но мне нужно чтобы получить все эти метаданные и захватить простой текст.

Я мог бы применить свойства регулярных выражений для проверки всех аномалий, но я думаю, что HAP гораздо больше подходит для html-парсера.

Поиск здесь привел меня на эту страницу, где обсуждается использование белого списка техники, упомянутой 'Meltdown'

HTML-теги полосы Agility Pack НЕ В белом списке

Но как мне применить это в vb.net, как это кажется отличной идеей?

Пожалуйста, добавьте, ребята ..........

РЕДАКТИРОВАТЬ: Я нашел версию кода vb.net, показанную ниже, но, похоже, ошибка в

If i IsNot DeletableNodesXpath.Count - 1 Then

Ошибки: для IsNot требуется операнд, имеющий ссылочные типы, но этот операнд имеет целочисленный тип значения

Вот код:

Открытый NotInheritable Класс HtmlSanitizer Private Sub New () End Sub Закрытый общий доступ только для чтения, белый список как IDictionary (Of String, String ()) Частные общие разделяемые узлыXpath как новый список (из строки) ()

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

Пожалуйста, кто-нибудь может помочь ??????

1 Ответ

0 голосов
/ 26 июля 2012

Вместо использования IsNot, просто используйте <>.Поскольку вы проверяете, что значение целого числа не равно значению другого целого числа - 1.

Я считаю, что IsNot нельзя использовать с целыми числами.edit: Я только что заметил, что это супер супер старый.Только что увидела дату 26 июля!

...