Thomas Haller: Daten aus einer HTML-Seite auslesen

Hallo!

Wer kann mir bei meinem vorhaben bitte helfen?
Folgendes Problem:
Ich habe eine HTML-Seite, welche ich lokal speichere und dann mit einem Perl-Skript nach bestimmten
Wörtern durchsuchen möchte, und die zugehörige Info.
HTML-Code sieht wie folgt aus:

######  Begin ######

<td width='115'><div class='left'>LIBRO AG</div></td>
<td width='70'><div class='left'>München<br>928974</div></td>
<td width='50'><div class='right'><b>63.00</b><br>100</div></td>
<td width='50'><div class='center'><font color=#009900>0.00<br>0.00</font></div></td>
<td width='50'><div class='center'>63.00<br>63.00</div></td>
<td width='55'><div class='center'>14:12<br>07.03.00</div></td>
<td width='50'><center>

EOF

so nun, sollte das so funktionieren.
der Skript findet: 928974
dazu soll er aber auch den Wert auslesen "63.00" auslesen, den ich aber vorher nicht kenne.
Jemand eine idee wie ich die Sache realisieren könnte?

Schon mal vielen Dank im Voraus für jede Hilfe!

mfg thomas

  1. Hallo thomas,

    bei Perl ist ein modul namens HTML::Parser dabei.
    Lese dir mal die Perl-Docu durch.
    Das steht das beschrieben.

    Tschüs

    Daniel

    1. bei Perl ist ein modul namens HTML::Parser dabei.
      Lese dir mal die Perl-Docu durch.

      Hi!

      Habe ich mir durchgelsen, nur mir ist noch nicht ganz klar, wie ich wenn ich den text auslese an
      die gewünschten daten komme.
      kann zwar den text extrahieren, aber wie dann weiter?

      mfg thomas

  2. Ääh...Information einfach nur so aus HTML Quellcode auszulesen ist nicht gerade die feine Art. Wenn es schon sein muss, dann versuch doch mal ein Muster zu bestimmen, anhand dessen du auf jeden Fall deinen gesuchten Wert findest..wie Z.b. 3 Zeilen tiefer zwischen > und < oder sowas.

    Aber es wäre viel eleganter und zuverlässiger diesen Wert schon von vornherein abzufangen. Wiekommt denn der Wert in die Seite hinein? Kannst du nicht die Daten direkt vom Script, das die Seite generiert übergeben?
    Wenn nicht, dann solltest du es so einrichten, daß das Script das die Seite generiert irgendwo einen eindeutigen String reinschreibt, den du auf jeden Fall wiederfindest. Also sowas wie

    <!--%%%928974=63.00%%%-->

    Gruß
    Cruz

    1. Ääh...Information einfach nur so aus HTML Quellcode auszulesen ist nicht gerade die feine Art.

      Hi!

      Wie würdest du daten auslesen/bekommen die nicht auf einer seite stehen, die von einem script generiert worden ist?
      (Börsenkurse)
      Bin wie schon geschriebn für jede hilfe dankbar.

      mfg thomas

      1. Wie würdest du daten auslesen/bekommen die nicht auf einer seite stehen, die von einem script generiert worden ist?

        Oh oh..wenn die Seite per Hand erstellt wird kannst du es eigentlich vergessen, denn dann gibt es kein festes Muster was bis in die unendlichkeit gelich bleibt. Der Typ muss nur eine Zeile mehr dazwischen schieben, oder mal mit mal ohne Anführungszeichen einen value angeben, was auch immer...das alles in einem Script abzufangen.....

        Aber dafür kannst du ihn bitten dir jedes Mal ein eindeutiges Zeichen wie z.b. <!--%%%name=value%%%--> in den Quellcode zu schreiben. :)

  3. Ich habe eine HTML-Seite, welche ich lokal speichere und dann mit einem Perl-Skript nach bestimmten
    Wörtern durchsuchen möchte, und die zugehörige Info.
    HTML-Code sieht wie folgt aus:

    Also wie bereits erwähnt, kommst Du an Perl nicht vorbei. Wenn die Seite allerdings so wie Dein Muster aussieht, wirst Du ein wirkliches Problem haben.
    Du mußt gewisse Muster im Text haben und über regular expressions danach suchen und die Daten auslesen.

    z.B. lt. der Text:  " <title>Ein Titel</title>"

    dann kannst Du "Ein Titel" folgendermaßen extrahieren:

    $t= ... enthält obigen Text

    $t =~ /<title>(.*)</title/;

    und $1 enthält dann "Ein Titel".

    Ich gebe zu, ein primitives Beispiel - aber sollt ein Ansatz sein.

    Gruß
    Timothy

    1. Hallo Timothy,

      reguläre Ausdrücke zu verwenden, ist sehr schlecht, da das bei komlizierten HTML-Dateien in die hose gehen kann.

      <!-- <TAG>text</TAG> -->
      <TAG param="<TAG>">

      Man muß die HTML-Datei parsen.

      Daniel

      1. reguläre Ausdrücke zu verwenden, ist sehr schlecht, da das bei komlizierten HTML-Dateien in die hose gehen kann.
        <!-- <TAG>text</TAG> -->
        <TAG param="<TAG>">
        Man muß die HTML-Datei parsen.

        ???? Und zwar womit, wenn nicht mit regulären Ausdrücken?

        Das Verbindungs-Skript http://www.teamone.de/cgi-local/haupt.pl parst die Hauptdatei dieses Forums mit einem einzigen regulären Ausdruck für Posting-Zeilen. Zugegeben, die sind dann *etwas* länger, etwa in der Art:

        if ($zeile =~ /^<!--top: (\d+)-->.*<img.*> <a href=[^>]+>(.+)</a> von <b>(.+)</b>, (\d+).(\d+).(\d+), (\d+):(\d+) Uhr<br>$/i)

        und das Austesten ist keine wirkliche Freude, aber der Parser wird sagenhaft kurz dabei ...

        1. Hallo Michael,

          Das ist die perfekte Lösung.
          Das Programm parsed eine HTML-Datei mit Hilfe von HTML::TokeParser und gibt dann informationen
          über deren Aufbau aus.

          use strict;
          require HTML::TokeParser;

          my $file = "parse.html";
          my $p = HTML::TokeParser->new($file);
          while(my $token = $p->get_token())
          {
          if($token->[0] eq "S")
          {
            start($token->[1],$token->[2],$token->[3],$token->[4]);
          }
          elsif($token->[0] eq "E")
          {
            end($token->[1],$token->[2]);
          }
          elsif($token->[0] eq "T")
          {
            text($token->[1]);
          }
          elsif($token->[0] eq "C")
          {
            comment($token->[1]);
          }
          elsif($token->[0] eq "D")
          {
            declaration($token->[1]);
          }
          }

          sub declaration
          {
          my $decl = $_[0];
          print("Decl: $decl\n");
          }

          sub start
          {
          my $tag = $_[0];
          my  %attr = %{$_[1]};
          my  $attrseq = $_[2];
          my  $origtext = $_[3];
          print("STag: $tag (\n");
          print(map {"$_ => $attr{$_}\n"} keys %attr);
          print(")\n");
          }

          sub end
          {
          my $tag = $_[0];
          print("ETag: $tag\n");
          }

          sub text
          {
          my $text = $_[0];
          print("Text: {\n$text\n}\n");
          }

          sub comment
          {
          my $comment = $_[0];
          print("Comment: {\n$comment\n}\n");
          }

          Die Fuktionen decleration, start, end, text und comment muß man nur noch nach belieben abändern.
          Das sollte bei allen HTML-Files fuktionieren.

          Tschüs

          Daniel

          1. Das ist die perfekte Lösung.
            Das Programm parsed eine HTML-Datei mit Hilfe von HTML::TokeParser und gibt dann informationen
            über deren Aufbau aus.

            Aber mit der konkreten Aufgabenstellung, aus einer
            auf eine ganz bestimmte Weise aufgebauten HTML-Datei
            ganz bestimmte Informationen zu extrahieren, hat sie
            so gut wie nichts zu tun.

            1. Hi!

              Aber mit der konkreten Aufgabenstellung, aus einer
              auf eine ganz bestimmte Weise aufgebauten HTML-Datei
              ganz bestimmte Informationen zu extrahieren, hat sie
              so gut wie nichts zu tun.

              Das ist ja so auch wieder nicht war. Man kann jetzt innerhalb der Funktion start davon ausgehen, wirklich nur start-Tags vor der Nase zu haben.
              Dort wartet man auf ein bestimmtes Tag bzw. einen bestimmten Inhalt - kann dann ein Flag setzten, welches besagt, daß an anderer Stelle nach den Zielinhalt geschaut werden soll:

              $drin = '' # entspricht 'false'
              $scan-left = ''
              $scan-right = ''
              sub start {
              wenn Tag = div und in den Attributen class = left, dann $scan-left=true
              wenn Tag = div und in den Attributen class = right, dann $scan-right=true
              }

              sub end {
              wenn Tag = div $scan-left = '' und scan-right = ''
              }

              sub text {
              wenn $scan-right und $drin, dann $wert = Text und $drin = ''  # GEFUNDEN
              wenn $scan-left und der Text enthält WKN dann $drin = true
              }

              Nur so als grober Ansatz. Wirkt relativ umständlich! Insbesondere im Vergleich zu einer RegExp. Aber dafür ist es "Tag-Konform" um bekommt keine Probleme, wie bei dem Kommentar-Beispiel ...

              Gruß,
                 Jörk