Parsear código HTML en Vb.net

Iniciado por #Aitor, 12 Mayo 2014, 18:08 PM

0 Miembros y 1 Visitante están viendo este tema.

#Aitor

Hola buenas, acostumbrado de PHP y su forma de parsear código.

Código (php) [Seleccionar]
preg_match_all('<b>Ejemplo de parsear, este numero es variante (.*) </b>', $ejemplo, $ejemplo1);

con el (.*) se obtenia el valor que se encontraba ahí. No encuentro una manera eficiente de hacerlo en VB.net

Mejor dicho no encuentro nada de información sobre cómo hacerlo en Vb.net, y la única solución que encuentro es haciéndolo de forma muy absurda.

Código (vb.net) [Seleccionar]
Dim valor as integer = InStr(codigo_html.Text, "<b>Ejemplo de parsear, este numero es variante")

y a partir de ahí guardar la última posición en un entero (valor) y recorrer un for hasta que encuentre un "<" y salga de éste, como digo, me parece muy ineficiente y absurda.

¿Existe alguna 'mejor' forma, más cómoda de parsear?
Mi algoritmo en PHP (estupideces y más).
Código (php) [Seleccionar]
while($Se_feliz){
  Piensa_un_OBJETIVO(); // Sin excusas!
  if($Tienes_un_objetivo){
    Suspira(); // Sé paciente.
    if($Consigues_el_objetivo){ echo "¡Felicidades #Aitor!";return;
      //RETURN; ¿O volvemos a empezar?
    }else{
      Inténtalo_de_nuevo();
    }
  }
}

.:Weeds:.

Tal vez esto sea lo que buscas.

http://htmlagilitypack.codeplex.com/

Hay muchos tutoriales en google sobre como usarlo.

Saludos.


Eleкtro

He leido en un post tuyo más reciente que comentabas la falta de atención a este post, lo digo porque de lo contrario no respondería a un post de antiguedad por no ser un buen ejemplo...




Para ser sinceros, el compañero @.:Weeds:.te ha sugerido la mejor opción que hay, pero es una librería demasiado completa y amplia para tus necesidades, lo cual resolverías descargando el source y usando un simple RegEx.

De todas formas, te dejo un ejemplo que escribí hace tiempo sobre el uso de dicha librería, espero que te sirva en algo:

Código (vbnet) [Seleccionar]
Public Class Form1

    Private ReadOnly html As String =
        <a><![CDATA[
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<body>

<div class="infolinks"><input type="hidden" name="IL_IN_TAG" value="1"/></div><div id="main">

<div class="music">

<h2 class="boxtitle">New releases \ <small>
<a href="/newalbums" title="New releases mp3 downloads" rel="bookmark">see all</a></small>
</h2>

<div class="item">

    <div class="thumb">
<a href="http://www.mp3crank.com/curt-smith/deceptively-heavy-121861" rel="bookmark" lang="en" title="Curt Smith - Deceptively Heavy album downloads"><img width="100" height="100" alt="Mp3 downloads Curt Smith - Deceptively Heavy" title="Free mp3 downloads Curt Smith - Deceptively Heavy" src="http://www.mp3crank.com/cover-album/Curt-Smith-Deceptively-Heavy-400x400.jpg"/></a>
    </div>

<div class="release">
<h3>Curt Smith</h3>
<h4>
<a href="http://www.mp3crank.com/curt-smith/deceptively-heavy-121861" title="Mp3 downloads Curt Smith - Deceptively Heavy">Deceptively Heavy</a>
</h4>
<script src="/ads/button.js"></script>
</div>

<div class="release-year">
<p>Year</p>
<span>2013</span>
</div>

<div class="genre">
<p>Genre</p>
<a href="http://www.mp3crank.com/genre/indie" rel="tag">Indie</a><a href="http://www.mp3crank.com/genre/pop" rel="tag">Pop</a>
</div>

</div>

<div class="item">

    <div class="thumb">
<a href="http://www.mp3crank.com/wolf-eyes/lower-demos-121866" rel="bookmark" lang="en" title="Wolf Eyes - Lower Demos album downloads"><img width="100" height="100" alt="Mp3 downloads Wolf Eyes - Lower Demos" title="Free mp3 downloads Wolf Eyes - Lower Demos" src="http://www.mp3crank.com/cover-album/Wolf-Eyes-–-Lower-Demos.jpg" /></a>
    </div>

<div class="release">
<h3>Wolf Eyes</h3>
<h4>
<a href="http://www.mp3crank.com/wolf-eyes/lower-demos-121866" title="Mp3 downloads Wolf Eyes - Lower Demos">Lower Demos</a>
</h4>
<script src="/ads/button.js"></script>
</div>

<div class="release-year">
<p>Year</p>
<span>2013</span>
</div>

<div class="genre">
<p>Genre</p>
<a href="http://www.mp3crank.com/genre/rock" rel="tag">Rock</a>
</div>

</div>

</div>

</div>

</body>
</html>
]]$cdataend$</a>.Value

    Private sb As New System.Text.StringBuilder

    Private htmldoc As HtmlAgilityPack.HtmlDocument = New HtmlAgilityPack.HtmlDocument
    Private htmlnodes As HtmlAgilityPack.HtmlNodeCollection = Nothing

    Private Title As String = String.Empty
    Private Cover As String = String.Empty
    Private Year As String = String.Empty
    Private Genres As String() = {String.Empty}
    Private URL As String = String.Empty

    Private Sub Test() Handles MyBase.Shown

        ' Load the html document.
        htmldoc.LoadHtml(html)

        ' Select the (10 items) nodes.
        ' All "SelectSingleNode" below will use this DIV element as a starting point.
        htmlnodes = htmldoc.DocumentNode.SelectNodes("//div[@class='item']")

        ' Loop trough the nodes.
        For Each node As HtmlAgilityPack.HtmlNode In htmlnodes

             ' Set the values:
            Title = node.SelectSingleNode(".//div[@class='release']/h4/a[@title]").GetAttributeValue("title", "Unknown Title")
            Cover = node.SelectSingleNode(".//div[@class='thumb']/a/img[@src]").GetAttributeValue("src", String.Empty)
            Year = node.SelectSingleNode(".//div[@class='release-year']/span").InnerText
            Genres = (From genre In node.SelectNodes(".//div[@class='genre']/a") Select genre.InnerText).ToArray
            URL = node.SelectSingleNode(".//div[@class='release']/h4/a[@href]").GetAttributeValue("href", "Unknown URL")

            ' Display the values:
            sb.Clear()
            sb.AppendLine(String.Format("Title : {0}", Title))
            sb.AppendLine(String.Format("Cover : {0}", Cover))
            sb.AppendLine(String.Format("Year  : {0}", Year))
            sb.AppendLine(String.Format("Genres: {0}", String.Join(", ", Genres)))
            sb.AppendLine(String.Format("URL   : {0}", URL))
            MsgBox(sb.ToString)

        Next node

    End Sub

End Class



+ Como descargar el source de una página:

Código (vbnet) [Seleccionar]
    ' Get SourcePage Array
    ' ( By Elektro )
    '
    ' Usage Examples:
    ' Dim SourceLines As String() = GetSourcePageArray("http://www.ElHacker.net", TrimLines:=True)
    ' For Each Line As String In SourceLines : MsgBox(Line) : Next Line
    '
    ''' <summary>
    ''' Gets a web source page.
    ''' </summary>
    ''' <param name="URL">Indicates the source page URL to get.</param>
    ''' <param name="TrimLines">Indicates whether to trim the lines.</param>
    ''' <param name="SplitOptions">Indicates the split options.</param>
    ''' <returns>System.String[][].</returns>
    ''' <exception cref="Exception"></exception>
    Private Function GetSourcePageArray(ByVal URL As String,
                                        Optional ByVal TrimLines As Boolean = False,
                                        Optional ByVal SplitOptions As StringSplitOptions =
                                                       StringSplitOptions.None) As String()

        Try

            Using StrReader As New IO.StreamReader(Net.HttpWebRequest.Create(URL).GetResponse().GetResponseStream)

                If TrimLines Then

                    Return (From Line As String
                           In StrReader.ReadToEnd.Split({Environment.NewLine}, SplitOptions)
                           Select Line.Trim).ToArray

                Else
                    Return StrReader.ReadToEnd.Split({Environment.NewLine}, SplitOptions)

                End If

            End Using

        Catch ex As Exception
            Throw New Exception(ex.Message)
            Return Nothing

        End Try

    End Function


+ Un breve ejemplo de la utilización de un RegEx:

Código (vbnet) [Seleccionar]
#Region " RegEx Match Tag "

    ' [ RegEx Match Tag Function ]
    '
    ' // By Elektro H@cker
    '
    ' Examples :
    ' Dim str As String = <a><![CDATA[href=>Drifter - In Search of Something More [EP] (2013)</a>]]></a>.Value
    ' MsgBox(RegEx_Match_Tag(str, 1)) ' Result: Drifter - In Search of Something More [EP] (2013)

    Private Function RegEx_Match_Tag(ByVal str As String, Optional ByVal Group As Int32 = 0) As String

        ' Match criteria:
        '
        ' >Text<

        Dim RegEx As New System.Text.RegularExpressions.Regex( _
        <a><![CDATA[>([^<]+?)<]]$cdataend$</a>.Value)

        Return RegEx.Match(str).Groups(Group).ToString
       
    End Function

#End Region



Saludos