HTML parsen



  • Ich möchte Webeseiten runterladen (das funtioniert schon mal) und den Inhalt der Seite bezüglich der darin enthaltenen Links auswerten. Da die Regeln für Links auf Webseiten extrem vielfältig sind würde, ich es mir gerne einfach machen und eine fertige Bibliothek benutzen.
    Ich hab mir da zur schon selber Routinen geschrieben, aber damit wird nicht jeder Link korrekt erkannt. Ich kenne eben auch nicht jeden Sonderfall wie Links aufgebaut sein können.

    Kennt da jemand was passendes?



  • Welche Sonderfälle?

    Es gibt sicher Bibliotheken, um HTML zu parsen. Hab noch keine für C++ benutzt, aber es wird ganz sicher welche geben, brauchst nur googeln. Aber einen einfach Parser, der <a Tags erkennt, kann man auch selber leicht schreiben. Die Frage wäre immer noch, was du alles erkennen willst. Irgendwelche JS, das dynamisch wieder JS Code erzeugt, der Links erzeugt, wird dir keine Bibliothek erkennen können.



  • Mechanics schrieb:

    Welche Sonderfälle?

    Ich vermute er meint die ganzen Sachen die man korrekt implementieren muss wenn man "zu Fuss" HTML parsen will. Bzw. halt zumindest die href Attribute aus a Elementen rausparsen.
    So Sachen wie Encoding, Kommentare, Entities, ...

    @Oxigen
    Eine Möglichkeit wäre...
    Lass den HTML Source erstmal durch "HTML Tidy" laufen:
    http://tidy.sourceforge.net/

    Dann hast du (hoffentlich) valides XHTML, das du einem XML Parser deiner Wahl füttern kannst. Den Output dieses Parsers gehst du durch und guckst da drinnen einfach nach <a> Tags.

    Möglichkeit 2: Du guckst ob du einen HTML Parser findest der auch mit nicht-XHTML-konformen HTML Seiten klar kommt.

    Möglichkeit 3: Du verzichtest darauf nicht-XHTML-konforme HTML Seiten zu verarbeiten. In dem Fall kannst du das HTML gleich einem XML Parser füttern.

    Möglichkeit 4: Du guckst dir die nötigen Teile des HTML Standards an und schreibst deinen eigenen minimalen Parser. Da du nur an <a> Tags interessiert bist sollte das nichtmal SO viel Aufwand sein. Einfach nur ins Blaue raten ist aber vermutlich zu wenig, dich hinsetzen und die relevanten Stellen der relevanten Standards lesen solltest du schon wenn du möchtest dass dabei 'was brauchbares rauskommt.



  • Mechanics schrieb:

    Die Frage wäre immer noch, was du alles erkennen willst. Irgendwelche JS, das dynamisch wieder JS Code erzeugt, der Links erzeugt, wird dir keine Bibliothek erkennen können.

    Nach Möglichkeit alle verlinkten Objekte einer Webpage
    z.B.auch sowas hier:

    <head>
    <base target="Hauptframe">
    <title></title>
    </head>
    
    <script type="text/javascript">
    <!--
    Up1 = new Image();
    Up1.src = "buttons/status.gif";
    Down1 = new Image();
    Down1.src = "buttons/status_over.gif";
    Highlight1 = new Image();
    Highlight1.src = "buttons/status_over.gif";
    function Bildwechsel(Bildnr,Bildobjekt) {
     window.document.images[Bildnr].src = Bildobjekt.src;
    }
    //-->
    </script>
    
    <body background="cliparts/background.jpg" link="#000000" vlink="#000000" alink="#000000">
    <div align="left">
      <table border="0" cellspacing="0" width="139">
        <tr>
          <td width="135"><font face="Arial">
    <a href="middle.html" onMouseOver="Bildwechsel(0,Highlight1)" onMouseDown="Bildwechsel(0,Down1)" onMouseUp="Bildwechsel(0,Highlight1)" onMouseOut="Bildwechsel(0,Up1)" target="main"><img border="0" src="buttons/status.gif" height="21"></a></font></td>
    

    hustbaer schrieb:

    @Oxigen
    Eine Möglichkeit wäre...
    Lass den HTML Source erstmal durch "HTML Tidy" laufen:
    http://tidy.sourceforge.net/

    Dann hast du (hoffentlich) valides XHTML, das du einem XML Parser deiner Wahl füttern kannst. Den Output dieses Parsers gehst du durch und guckst da drinnen einfach nach <a> Tags.

    über HTML Tidy bin ich auch gestolpert beim googlen und hatte die gleiche Idee wie du.

    hustbaer schrieb:

    Möglichkeit 2: Du guckst ob du einen HTML Parser findest der auch mit nicht-XHTML-konformen HTML Seiten klar kommt.

    Wäre auch ok.

    hustbaer schrieb:

    Möglichkeit 3: Du verzichtest darauf nicht-XHTML-konforme HTML Seiten zu verarbeiten. In dem Fall kannst du das HTML gleich einem XML Parser füttern.

    Möchte ich vermeiden.

    hustbaer schrieb:

    Möglichkeit 4: Du guckst dir die nötigen Teile des HTML Standards an und schreibst deinen eigenen minimalen Parser. Da du nur an <a> Tags interessiert bist sollte das nichtmal SO viel Aufwand sein. Einfach nur ins Blaue raten ist aber vermutlich zu wenig, dich hinsetzen und die relevanten Stellen der relevanten Standards lesen solltest du schon wenn du möchtest dass dabei 'was brauchbares rauskommt.

    Ja ich verlase mich am liebsten auch erstmal auf meinem eigenen Code. Aber es geht ja nicht nur um "<a href=...>" Objekte. Sondern alle verlinkten Objekte einer Webpage z.B. "<frame name ....>" oder "<img ...>" usw.

    Mir jetzt die entsprechenden Kenntnisse in HTML anzueigen die notwendig sind um das Vorhaben zu realisieren, ist mir auf den ersten Blick zu mühselig. Ich hab ja schon einen Parser geschrieben der "<a ...>" verarbeitet und da gibt ja schon zig Möglichkeiten dort verlinkte Objekte unterzubringen.

    Ich sehs so: wenn ich Dateien zippen möchte schreib ich mir die zip-Funktionen ja auch nicht neu, sondern benutze die zlib-Bibliothek und die mini-zip Funktionen. Und das war damit auch schon genug Aufwand um meine eigene zip/unzip Bibliothek zu schreiben. So versuche ich es in diesem Fall genauso zu halten.



  • Oxigen schrieb:

    Nach Möglichkeit alle verlinkten Objekte einer Webpage
    z.B.auch sowas hier:

    <head>
    <base target="Hauptframe">
    <title></title>
    </head>
    
    <script type="text/javascript">
    <!--
    Up1 = new Image();
    Up1.src = "buttons/status.gif";
    Down1 = new Image();
    Down1.src = "buttons/status_over.gif";
    Highlight1 = new Image();
    Highlight1.src = "buttons/status_over.gif";
    function Bildwechsel(Bildnr,Bildobjekt) {
     window.document.images[Bildnr].src = Bildobjekt.src;
    }
    //-->
    </script>
    
    <body background="cliparts/background.jpg" link="#000000" vlink="#000000" alink="#000000">
    <div align="left">
      <table border="0" cellspacing="0" width="139">
        <tr>
          <td width="135"><font face="Arial">
    <a href="middle.html" onMouseOver="Bildwechsel(0,Highlight1)" onMouseDown="Bildwechsel(0,Down1)" onMouseUp="Bildwechsel(0,Highlight1)" onMouseOut="Bildwechsel(0,Up1)" target="main"><img border="0" src="buttons/status.gif" height="21"></a></font></td>
    

    Was hier?



  • ich rate mal 🕶
    alle links die da drauf sind...
    zB. Zeile 9, 11, 13, 20, 25

    Ich denke du wirst nicht drumrum kommen, dich mit einzelnen HTML Elementen und deren Attributen auseinander zu setzten. Außerdem sind das gar nicht so viele
    wenn du nur auf die links scharf bist.
    Es gibt zwar mehrer unterschiedliche HTML Elemente, die links beinhalten können, aber bei sehr vielen dieser Elemente sind die Attribut Namen alle gleich.

    folgende Seite hat mir auch sehr viel dabei geholfen.
    SelfHtml Wiki



  • Zeilen 20 und 25 sind kein Problem.

    Zeilen 9, 11 und 13 dagegen schon, weil das keine "HTML Links" sind. Sondern Strings in einem JavaScript Programm, die dann irgendwann, wenn die Seite in einem Browser mit JavaScript-Unterstützung läuft, und der User entsprechend agiert, vielleicht mal als (relative) URL interpretiert werden.
    Also genau das was Mechanics geschrieben hat.

    Man kann jetzt versuchen sich eine Heuristik dafür zu basteln, aber 100% wird die nie werden.
    Wenn man mit etlichen false-positives sowie false-negatives leben kann, dann OK. Wenn nicht, dann lautet die Antwort mMn. einfach nur: geht nicht.



  • unter dem HTML Element <base href=> steht idr. der Rest zu den linkkürzeln, sonst wüste auch keine scriptsprache der welt wo es langgeht. bzw. müsste man es für jedes script explizit angeben.

    um sich das zu ersparen setzt man das Attribut href im base Element.

    man kann also davon ausgehen, dass wenn auf der Elternseite oder einer untergeordneten Kindseite unter dem HTML Element base ein href Attribut auftaucht und ein wert zugewiesen wird, passt die Pfadangabe, die man sich aus beiden Fragmenten zusammenstückeln kann.



  • Ja, die Basisurl wird man schon irgendwie hinbekommen.
    Bloss welche Strings sind relative URLs und welche nicht?
    Und was machst du wenn das JavaScript Teil die Strings nicht "fertig" drinnen stehen hat sondern irgendwie zusammenstoppelt?

    Deswegen hab ich ja geschrieben

    hustbaer schrieb:

    Man kann jetzt versuchen sich eine Heuristik dafür zu basteln, aber 100% wird die nie werden.
    Wenn man mit etlichen false-positives sowie false-negatives leben kann, dann OK. Wenn nicht, dann lautet die Antwort mMn. einfach nur: geht nicht.



  • LowFly schrieb:

    ich rate mal 🕶
    alle links die da drauf sind...
    zB. Zeile 9, 11, 13, 20, 25

    So ist es.

    LowFly schrieb:

    um sich das zu ersparen setzt man das Attribut href im base Element.

    man kann also davon ausgehen, dass wenn auf der Elternseite oder einer untergeordneten Kindseite unter dem HTML Element base ein href Attribut auftaucht und ein wert zugewiesen wird, passt die Pfadangabe, die man sich aus beiden Fragmenten zusammenstückeln kann.

    "<base ...>" wird so gut wie nie gesetzt. Das Zusammenbasteln der Links kann man sich meiner Erfahrung nach auch sparen, das macht der Server für mich wenn ich im die Anfoderung schicke.

    Beispiel:
    Ich bin hier:
    www.beispiel.de/ebene1a/ebene2b/index.html

    und in meiner HTML Datei steht folgender Link:
    ../../ebene1b/ebene2a/bild.jpg

    dann kann ich das schicken:
    www.beispiel.de/ebene1a/ebene2b/../../ebene1b/ebene2a/bild.jpg

    um folgendes zu erhalten:
    www.beispiel.de/ebene1b/ebene2a/bild.jpg

    Ich hatte mir mit meiner Frage hier erhofft, dass jemand sagt: da gibt's was, das kenn ich, hab ich auch schon benutzt und hat funktioniert.

    Ich denke ich werde mir den gumbo parser und tidy mal anschauen, vieleicht ist das was brauchbares.





  • Thx Mr C,

    aber für HTML5 macht gumbo genau das was ich suche. Ob ich mir die Auswertung auf Java-Code antue überlege ich mir später.


Log in to reply