HTML zerlegen

  • VB.NET

Es gibt 11 Antworten in diesem Thema. Der letzte Beitrag () ist von faxe1008.

    HTML zerlegen

    Hallo,

    ich würde gerne ein Programm erstellen mit dem man die Angebote auf Rebuy abrufen kann. Zuerst sollte man ja den HTML-Quelltext über den Webclienten downloaden und in einem String speichern. Dann müsste ich das ganze nach Preis, Name, Bild etc. zerlegen.

    Beispiel Aufbau:
    Suchergebnis: 1 - 19 von 19 Ergebnissen
    </div>
    </div>
    <ul class="products">
    <li>
    <a href="/i,1782274/blu-ray-disc/ich-einfach-unverbesserlich-inkl-digital-copy" class="productConversion">
    <img src="https://dksw3hw5iu1be.cloudfront.net/1782274/thumbs/110.gif" class="cover" alt=""/>
    </a>

    <h2>
    <a href="/i,1782274/blu-ray-disc/ich-einfach-unverbesserlich-inkl-digital-copy" class="inverse productConversion">
    Ich - Einfach unverbesserlich [Inkl. Digital Copy] </a>
    <p class="usk 0"><label>Altersfreigabe:</label> freigegeben ohne Altersbeschränkung (<span class="link">?</span>)</p> <p class="category-icon category-cd">Blu-ray Disc</p> </h2>

    <div class="data">
    <p class="availability green">sofort lieferbar</p>

    <p class="price">
    Nur
    <span class="alpha">
    <strong>5,39 €</strong>
    </span>
    </p>

    <p class="vat">
    Preise sind Endpreise (kein USt-Ausweis gem. §25a UStG)<br/> zzgl.
    <a href="/s/agb#versandkosten" class="deliveryCostsTooltip">
    Versandkosten</a>
    (Standardversand: 3,99 €)
    </p>

    Für die Kosten muss ich bei der Seite immer nur das filtern das zwischen <strong></strong> steht. Wie müsste der RegEx-Pattern dazu aussehen? (Probier jetzt schon ziemlich lange dran rum...)
    Und gibt es einen einfacheren Weg als das Bild dann mit dem Link runterzuladen zwischen zuspeichern und dann einzulesen?

    Edit by hal2000:
    - Die Farbe ROT ist der Moderation vorbehalten.

    8-) faxe1008 8-)

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „hal2000“ ()

    Mir fällt mit bestem Willen absolut kein Plattern ein, der das bewältigen könnte. Dein String ist außerdem untypisch lang. Du könntest deiner Form einen WebBroser hinzufügen und versuchen, den Inhalt des HTML Tags strong auzulesen. Problem dabei ist, dass es auf der Seite der Suchergebnisse mehrer Tags dieser Art gibt. Die vermutlich beste Lösung wäre, einfach dem User die Webseite mit den Suchergebnissen anzuzeigen.
    RegEx. Das ist einfach genial wenn man es kann.
    Guck dir die Struktur bei mehreren Artikeln an und überleg dir erstmal nur wie du ohne Programmierung danach suchen würdest.
    Dann kannst du dir ein Pattern schreiben, was diese Aufgabe erledigt. Das ist sicher nicht unmöglich. Da wirst du dann vielleicht viel mit "|", also "ODER"
    arbeiten müssen :)
    Naja wäre eine Option aber eigentlich wollte ich mich mehr mit RegEx auseinandersetzen. Wenn ich ein einen Webbrowser verwende steckt da ca. 1 Zeile selbst geschriebener Code drin :/

    Ist das wirklich so problematisch längere Texte zu "Regexen"? Hat jemand falls es nur schwer möglich ist eine andere Idee?

    EDIT: verdammt @LaMiy: hab deinen Post übersehen. Bin an meinem "Handy"....

    Hier noch ein Beispiel für den typischen Aufbau:
    Spoiler anzeigen

    Suchergebnis: 1 - 20 von 999 Ergebnissen
    </div>
    </div>
    <ul class="products">
    <li>
    <a href="/i,2495607/dvd/harry-potter-und-die-heiligtuemer-des-todes-teil-2" class="productConversion">
    <img src="https://dksw3hw5iu1be.cloudfront.net/2495607/thumbs/110.gif" class="cover" alt=""/>
    </a>

    <h2>
    <a href="/i,2495607/dvd/harry-potter-und-die-heiligtuemer-des-todes-teil-2" class="inverse productConversion">
    Harry Potter und die Heiligtümer des Todes - Teil 2 </a>
    <p class="usk 12"><label>Altersfreigabe:</label> frei ab 12 Jahren (<span class="link">?</span>)</p> <p class="category-icon category-cd">DVD</p> </h2>

    <div class="data">
    <p class="availability green">sofort lieferbar</p>

    <p class="price">
    Nur
    <span class="alpha">
    <strong>10,39 €</strong>
    </span>
    </p>

    <p class="vat">
    Preise sind Endpreise (kein USt-Ausweis gem. §25a UStG)<br/> zzgl.
    <a href="/s/agb#versandkosten" class="deliveryCostsTooltip">
    Versandkosten</a>
    (Standardversand: 3,99 €)
    </p>

    <form accept-charset="utf-8" method="post" action="/cart/add-item" class="productConversion">
    <input type="hidden" name="id" value="2495607"/>
    <button class="button medium orange add-to-button" title="In den Warenkorb" data-webtrekk-quickbuy="enabled" data-webtrekk-product-id="2495607" data-webtrekk-product-cost="10.39" data-webtrekk-action-buy="enabled" type="submit"><span class="button-container" style="width:160px;"><span class="button label " style="width:127px;">In den Warenkorb</span><span class="button arrow background "><span class="button arrow foreground "></span></span></span></button> </form>

    <form accept-charset="utf-8" data-login-required="1" method="post" action="/mein-konto/watchlist/add" class="productConversion">
    <input type="hidden" name="id" value="2495607"/>
    <input type="hidden" name="redirect" value="/kaufen/suchen?q=Harry+Potter&amp;submit-search=Suche&amp;dt=1&amp;page=1" />
    <button type="submit" class="watchlist" data-webtrekk-action-watchlist="enabled">Auf den Merkzettel</button>
    </form>
    </div>
    </li>
    <li>
    <a href="/i,1856592/dvd/harry-potter-und-die-heiligtuemer-des-todes-teil-1" class="productConversion">
    <img src="https://dksw3hw5iu1be.cloudfront.net/1856592/thumbs/110.gif" class="cover" alt=""/>
    </a>

    <h2>
    <a href="/i,1856592/dvd/harry-potter-und-die-heiligtuemer-des-todes-teil-1" class="inverse productConversion">
    Harry Potter und die Heiligtümer des Todes - Teil 1 </a>
    <p class="usk 12"><label>Altersfreigabe:</label> frei ab 12 Jahren (<span class="link">?</span>)</p> <p class="category-icon category-cd">DVD</p> </h2>

    <div class="data">
    <p class="availability">
    Der Artikel ist nicht verfügbar.<br />
    <span class="normal">Lassen Sie sich benachrichtigen, sobald der Artikel wieder erhältlich ist.</span>
    </p>

    <p class="price">
    Voraussichtlicher Preis:
    3,29 € </p>

    <p class="vat">
    Preise sind Endpreise (kein USt-Ausweis gem. §25a UStG)<br/> zzgl.
    <a href="/s/agb#versandkosten" class="deliveryCostsTooltip">
    Versandkosten</a>
    (Standardversand: 3,99 €)
    </p>

    <form accept-charset="utf-8" data-login-required="1" method="get" action="/sale/product/availability-alert" class="productConversion">
    <input type="hidden" name="id" value="1856592"/>
    <input type="hidden" name="redirect" value="/kaufen/suchen?dt=1&amp;page=1&amp;q=Harry+Potter&amp;submit-search=Suche"/>
    <button id="button" class="button medium blue add-to-button" title="Lassen Sie sich benachrichtigen, sobald der Artikel wieder erhältlich ist" data-webtrekk-action-buyalert="enabled" type="submit"><span class="button-container" style="width:160px;"><span class="button label " style="width:127px;">Kaufalarm setzen</span><span class="button arrow background "><span class="button arrow foreground "></span></span></span></button> </form>

    <p class="disableAlerts">
    Deaktivierung der Alarmbenachrichtigungen im
    <a data-login-required="1" href="/mein-konto/availability-alert">Alarm-Manager</a> möglich.
    </p>
    </div>
    </li>
    <li>
    <a href="/i,1162637/buecher/harry-potter-und-die-kammer-des-schreckens-band-2-joanne-k.-rowling" class="productConversion">
    <img src="https://dksw3hw5iu1be.cloudfront.net/1162637/thumbs/110.gif" class="cover" alt=""/>
    </a>

    <h2>
    <a href="/i,1162637/buecher/harry-potter-und-die-kammer-des-schreckens-band-2-joanne-k.-rowling" class="inverse productConversion">
    Harry Potter und die Kammer des Schreckens (Band 2) - Joanne K. Rowling </a>
    <p class="category-icon category-book">Bücher</p> </h2>

    <div class="data">
    <p class="availability green">sofort lieferbar</p>

    <p class="price">
    Nur
    <span class="alpha">
    <strong>3,39 €</strong>
    </span>
    </p>

    <p class="vat">
    Preise sind Endpreise (kein USt-Ausweis gem. §25a UStG)<br/> zzgl.
    <a href="/s/agb#versandkosten" class="deliveryCostsTooltip">
    Versandkosten</a>
    (Standardversand: 3,99 €)
    </p>

    <form accept-charset="utf-8" method="post" action="/cart/add-item" class="productConversion">
    <input type="hidden" name="id" value="1162637"/>
    <button class="button medium orange add-to-button" title="In den Warenkorb" data-webtrekk-quickbuy="enabled" data-webtrekk-product-id="1162637" data-webtrekk-product-cost="3.39" data-webtrekk-action-buy="enabled" type="submit"><span class="button-container" style="width:160px;"><span class="button label " style="width:127px;">In den Warenkorb</span><span class="button arrow background "><span class="button arrow foreground "></span></span></span></button> </form>

    <form accept-charset="utf-8" data-login-required="1" method="post" action="/mein-konto/watchlist/add" class="productConversion">
    <input type="hidden" name="id" value="1162637"/>
    <input type="hidden" name="redirect" value="/kaufen/suchen?q=Harry+Potter&amp;submit-search=Suche&amp;dt=1&amp;page=1" />
    <button type="submit" class="watchlist" data-webtrekk-action-watchlist="enabled">Auf den Merkzettel</button>
    </form>
    </div>
    </li>
    <li>
    <a href="/i,2492373/dvd/harry-potter-komplettbox-16-dvds" class="productConversion">
    <img src="https://dksw3hw5iu1be.cloudfront.net/2492373/thumbs/110.gif" class="cover" alt=""/>
    </a>

    <h2>
    <a href="/i,2492373/dvd/harry-potter-komplettbox-16-dvds" class="inverse productConversion">
    Harry Potter [Komplettbox, 16 DVD´s] </a>
    <p class="usk 12"><label>Altersfreigabe:</label> frei ab 12 Jahren (<span class="link">?</span>)</p> <p class="category-icon category-cd">DVD</p> </h2>

    <div class="data">
    <p class="availability">
    Der Artikel ist nicht verfügbar.<br />
    <span class="normal">Lassen Sie sich benachrichtigen, sobald der Artikel wieder erhältlich ist.</span>
    </p>

    <p class="price">
    Voraussichtlicher Preis:
    43,69 € </p>

    <p class="vat">
    Preise sind Endpreise (kein USt-Ausweis gem. §25a UStG)<br/> zzgl.
    <a href="/s/agb#versandkosten" class="deliveryCostsTooltip">
    Versandkosten</a>
    (Standardversand: 3,99 €)
    </p>

    <form accept-charset="utf-8" data-login-required="1" method="get" action="/sale/product/availability-alert" class="productConversion">
    <input type="hidden" name="id" value="2492373"/>
    <input type="hidden" name="redirect" value="/kaufen/suchen?dt=1&amp;page=1&amp;q=Harry+Potter&amp;submit-search=Suche"/>
    <button id="button" class="button medium blue add-to-button" title="Lassen Sie sich benachrichtigen, sobald der Artikel wieder erhältlich ist" data-webtrekk-action-buyalert="enabled" type="submit"><span class="button-container" style="width:160px;"><span class="button label " style="width:127px;">Kaufalarm setzen</span><span class="button arrow background "><span class="button arrow foreground "></span></span></span></button> </form>

    <p class="disableAlerts">
    Deaktivierung der Alarmbenachrichtigungen im
    <a data-login-required="1" href="/mein-konto/availability-alert">Alarm-Manager</a> möglich.
    </p>
    </div>
    </li>
    <li>
    <a href="/i,1162617/buecher/harry-potter-und-der-stein-der-weisen-joanne-k-rowling-band-1" class="productConversion">
    <img src="https://dksw3hw5iu1be.cloudfront.net/1162617/thumbs/110.gif" class="cover" alt=""/>
    </a>

    <h2>
    <a href="/i,1162617/buecher/harry-potter-und-der-stein-der-weisen-joanne-k-rowling-band-1" class="inverse productConversion">
    Harry Potter und der Stein der Weisen - Joanne K. Rowling [Band 1] </a>
    <p class="category-icon category-book">Bücher</p> </h2>

    <div class="data">
    <p class="availability green">sofort lieferbar</p>

    <p class="price">
    Nur
    <span class="alpha">
    <strong>3,79 €</strong>
    </span>
    </p>

    <p class="vat">
    Preise sind Endpreise (kein USt-Ausweis gem. §25a UStG)<br/> zzgl.
    <a href="/s/agb#versandkosten" class="deliveryCostsTooltip">
    Versandkosten</a>
    (Standardversand: 3,99 €)
    </p>



    Hab jetzt auch mal die Stellen makiert auf dies ankommt.
    Vielleicht könnten die RegEx Pros mir mal ein wenig auf die Sprünge helfen...

    Edit by hal2000:
    - Die Farbe ROT ist der Moderation vorbehalten.

    8-) faxe1008 8-)

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „hal2000“ ()

    faxe1008 schrieb:

    Vielleicht könnten die RegEx Pros mir mal ein wenig auf die Sprünge helfen...
    Ich dachte Du wolltest Dich selber mehr mit Regex auseiandersetzten ?

    Regex ist ein mächtiges Tool um Texte zu analysieren, allerdings berücksichtigt es keine Baumstrukturen, so wie sie bei XML/HTML vorliegen. Für komplexes HTTP würde ich daher eher eine Library wie das Html Agility Pack verwenden, welches HTML Texte in ein HtmlDocument konvertiert.

    Wenn Du mit Regex an Deinen Text rangehen möchtest, so mach das in 2 Schritten:
    - auslesen eines 'Product' Teils zwischen den Tags <li> und </li>
    - danach zerlegst Du die einzelnen Products mit Regex in die von Dir gewünschte Komponenten
    LINQ to XML funktioniert auch ganz gut, sofern man vorher die HTML-Besonderheiten entfernt. Je nach Auftreten ändert man per String.Replace alles, worüber der XML-Parser meckert, z.B. &auml; in ä oder <br> (ohne /) in <br></br>. Danach kann man ein XDocument erstellen, in dem man mit LINQ-Syntax bequem navigieren kann.
    Gruß
    hal2000
    hal2000: Entschuldigung wegen dem Rot.

    Habe jetzt mal folgendes Versucht, um den oberen unnötigen Teil zu entfernen:

    VB.NET-Quellcode

    1. Dim seitenquelltext As String = ""
    2. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    3. Dim weber As New WebClient
    4. seitenquelltext = weber.DownloadString("http://www.rebuy.de/kaufen/suchen?q=" + TextBox1.Text.Replace(" ", "+") + "&submit-search=Suche")
    5. Dim stelle As Integer
    6. For u = 0 To seitenquelltext.Length - 1
    7. If seitenquelltext.Substring(u, 12) = "Suchergebnis" Then
    8. stelle = u
    9. End If
    10. Next
    11. Dim zuersetzten As String = seitenquelltext.Substring(0, stelle)
    12. seitenquelltext = seitenquelltext.Replace(zuersetzten, "")
    13. MsgBox(seitenquelltext)
    14. End Sub


    Bekomme aber dabei folgende Fehlermeldung:
    Der Index und die Länge müssen sich auf eine Position in der Zeichenfolge beziehen. Parametername: length

    Das ist vermutlich ein Überlauf oder?
    Kennt jemand eine Alternative?

    8-) faxe1008 8-)

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „faxe1008“ ()

    Ok so funkts:

    VB.NET-Quellcode

    1. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    2. Dim weber As New WebClient
    3. seitenquelltext = weber.DownloadString("http://www.rebuy.de/kaufen/suchen?q=" + TextBox1.Text.Replace(" ", "+") + "&submit-search=Suche")
    4. Dim stelle As Integer
    5. For u = 0 To seitenquelltext.Length - 1
    6. If u + 12 < seitenquelltext.Length Then
    7. If seitenquelltext.Substring(u, 12) = "Suchergebnis" Then
    8. stelle = u
    9. End If
    10. End If
    11. Next
    12. Dim zuersetzten As String = seitenquelltext.Substring(0, stelle)
    13. seitenquelltext = seitenquelltext.Replace(zuersetzten, "")
    14. MsgBox(seitenquelltext)
    15. End Sub


    Das Abtrennen funktioniert auch so (warum komplizierter als nötig?), der Rest muss nun in RegEx erfolgen.

    8-) faxe1008 8-)
    Das bedeutet:
    Man kann mit IndexOf die Position des <strong> finden und dann einfach den substring ab der gefundenen stelle+8 bis das Euro zeichen drin ist raussplitten oder?

    Aber wie kann ich das bei unspezifischen Sachen machen die nichts besonderes Voranstehen haben:

    Quellcode

    1. <a href="/i,1856592/dvd/harry-potter-und-die-heiligtuemer-des-todes-teil-1" class="productConversion">
    2. <img src="https://dksw3hw5iu1be.cloudfront.net/1856592/thumbs/110.gif" class="cover" alt=""/>
    3. </a>
    4. <h2>
    5. <a href="/i,1856592/dvd/harry-potter-und-die-heiligtuemer-des-todes-teil-1" class="inverse productConversion">
    6. Harry Potter und die Heiligtümer des Todes - Teil 1 </a>
    7. <p class="usk 12"><label>Altersfreigabe:</label> frei ab 12 Jahren (<span class="link">?</span>)</p> <p class="category-icon category-cd">DVD</p> </h2>
    8. <div class="data">
    9. <p class="availability">
    10. Der Artikel ist nicht verfügbar.<br />

    8-) faxe1008 8-)
    So habe den HTML-Code weiter zerlegt auf das Minimum:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Dim seitenquelltext As String = ""
    2. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    3. Dim weber As New WebClient
    4. seitenquelltext = weber.DownloadString("http://www.rebuy.de/kaufen/suchen?q=" + TextBox1.Text.Replace(" ", "+") + "&submit-search=Suche")
    5. Dim stelle As Integer
    6. For u = 0 To seitenquelltext.Length - 1
    7. If u + 12 < seitenquelltext.Length Then
    8. If seitenquelltext.Substring(u, 12) = "Suchergebnis" Then
    9. stelle = u
    10. End If
    11. End If
    12. Next
    13. Dim zuersetzten As String = seitenquelltext.Substring(0, stelle)
    14. seitenquelltext = seitenquelltext.Replace(zuersetzten, "")
    15. Dim zeichen As String = "Artikel pro Seite"
    16. Dim stelle2 As Integer
    17. For u = 0 To seitenquelltext.Length - zeichen.Length
    18. If seitenquelltext.Substring(u, zeichen.Length) = zeichen Then
    19. stelle2 = u
    20. End If
    21. Next
    22. seitenquelltext = seitenquelltext.Remove(stelle2, CInt(seitenquelltext.Length - stelle2 - 1))
    23. MsgBox(seitenquelltext)
    24. My.Computer.Clipboard.SetText(seitenquelltext)
    25. End Sub
    26. End Class


    Bekomme das hier dabei raus:
    Test.txt.txt

    Hätte es gerne hier gepostet allerdings sind das mehr als 15000 Zeichen ;( .

    Wie Kann ich jetzt die makierten Teile rausholen?
    Spoiler anzeigen
    <a href="/i,1162637/buecher/harry-potter-und-die-kammer-des-schreckens-band-2-joanne-k.-rowling" class="productConversion">
    <img src="https://dksw3hw5iu1be.cloudfront.net/1162637/thumbs/110.gif" class="cover" alt=""/>
    </a>

    <h2>
    <a href="/i,1162637/buecher/harry-potter-und-die-kammer-des-schreckens-band-2-joanne-k.-rowling" class="inverse productConversion">
    Harry Potter und die Kammer des Schreckens (Band 2) - Joanne K. Rowling </a>
    <p class="category-icon category-book">Bücher</p> </h2>

    <div class="data">
    <p class="availability green">sofort lieferbar</p>

    <p class="price">
    Nur
    <span class="alpha">
    <strong>3,39 €</strong>
    </span>
    </p>

    <p class="vat">
    Preise sind Endpreise (kein USt-Ausweis gem. §25a UStG)<br/> zzgl.
    <a href="/s/agb#versandkosten" class="deliveryCostsTooltip">
    Versandkosten</a>
    (Standardversand: 3,99 €)
    </p>


    Und kann man mit IndexOf mehrere male die u. Position ermitteln?

    EDIT:\\ Probier jetzt schon ewig rum das Indexof auch String sucht aber es zeigt mir immer falsch an.....

    HA!!!!
    Ich habs hingekriegt. Aber der Code ist nicht undbedingt der sauberste........
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    2. '' Downloaden des HTMl-Codes
    3. Dim weber As New WebClient
    4. seitenquelltext = weber.DownloadString("http://www.rebuy.de/kaufen/suchen?q=" + TextBox1.Text.Replace(" ", "+") + "&submit-search=Suche")
    5. Dim stelle As Integer
    6. For u = 0 To seitenquelltext.Length - 1
    7. If u + 12 < seitenquelltext.Length Then
    8. If seitenquelltext.Substring(u, 12) = "Suchergebnis" Then
    9. stelle = u
    10. End If
    11. End If
    12. Next
    13. Dim zuersetzten As String = seitenquelltext.Substring(0, stelle)
    14. seitenquelltext = seitenquelltext.Replace(zuersetzten, "")
    15. Dim zeichen As String = "Artikel pro Seite"
    16. Dim stelle2 As Integer
    17. For u = 0 To seitenquelltext.Length - zeichen.Length
    18. If seitenquelltext.Substring(u, zeichen.Length) = zeichen Then
    19. stelle2 = u
    20. End If
    21. Next
    22. seitenquelltext = seitenquelltext.Remove(stelle2, CInt(seitenquelltext.Length - stelle2 - 1))
    23. Dim start As Integer
    24. Dim ende As Integer
    25. For u = 0 To seitenquelltext.Length - 11
    26. If seitenquelltext.Substring(u, 9) = "<img src=" Then
    27. start = u + 9
    28. For o = start To start + 65
    29. If seitenquelltext.Substring(o, 6) = "class=" Then
    30. ende = o
    31. Exit For
    32. End If
    33. Next
    34. Try
    35. Dim zeilen_arr As String() = seitenquelltext.Substring(start, ende).Split("class=")
    36. Dim zu_adden As String = zeilen_arr(0).ToString + "c" + zeilen_arr(1).ToString
    37. If zu_adden <> "" Then
    38. links.Add(zu_adden.Substring(1, zu_adden.Length - 3))
    39. 'ListView1.Items.Add(New ListViewItem(New String() {zu_adden.Substring(1, zu_adden.Length - 3), "2Spalte", "3Spalte", "4Spalte"}))
    40. End If
    41. Catch ex As Exception
    42. End Try
    43. End If
    44. Next
    45. End Sub

    8-) faxe1008 8-)

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „faxe1008“ ()