Thread I/O Operations: Pfade übertragen auf einen HTML-Parser (17 answers)
Opened by lin at 2010-10-03 13:29

lin
 2010-10-05 07:51
#141723 #141723
User since
2010-09-26
35 Artikel
BenutzerIn
[default_avatar]
Hi Topac, guten Morgen!

Du hast den Code - ich vergleiche das jetzt mal und geh den Code durch. Zeile für Zeile...

Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#!/usr/bin/perl

use strict;            # alles muss definiert sein
use warnings;          # wenn etwas nicht so ganz richtig ist warnen
use diagnostics;       # wenn etwas nicht passt ist warnen
use File::Find::Rule;  # finde Dateien/Verzeichnisse anhand von Regeln
use HTML::TokeParser;  # parse HTML-Dateien zum leichten auslesen von Daten

# Array in der alle Schulen mit ihren Daten gespeichert werden sollen
my @schools;

# Das Verzeichnis im dem gesucht werden soll
my $search_dir='.'; # ist das aktuelle Arbeitsverzeichnis

# die Datei in die alles gespeichert werden soll
my $out_file='./output.xml';

# Suche nach bestimmten Dateinamen
my @files= File::Find::Rule->file()            # suche eine Datei
                ->name('einzelergebnis*.html') # die mit "einzelergebnis" (alles klein geschieben!) beginnt und mit ".html" endet
                ->in($search_dir);              # suche in dem Verzeichnis


#gehe alle gefundenen Dateien durch
for my $file (@files)
{
  # Ausgabe, damit man weiß waw passiert.
  print "Bearbeite nun datei: $file!\n";

  # Speichrort für die Schuldaten in dieser Datei
  my %school;

  # starte seine neue Parser-Instanz mit der Datei als Quelle
  my $p = HTML::TokeParser->new($file) or die "Can't open $file: ($!)";

  #solange ein Tag von Typ 'div' gefunden wird
  while (my $tag = $p->get_tag('div', '/html'))
  {
    # first move to the right div that contains the information
    last if $tag->[0] eq '/html';
    next unless exists $tag->[1]{'id'} and $tag->[1]{'id'} eq 'inhalt_large';

    $p->get_tag('h1');
    $school{'location'} = $p->get_text('/h1');

    while (my $tag = $p->get_tag('div'))
    {
      last if exists $tag->[1]{'id'} and $tag->[1]{'id'} eq 'fusszeile';

      # get the school name from the heading
      next unless exists $tag->[1]{'class'} and $tag->[1]{'class'} eq 'fm_linkeSpalte';
      $p->get_tag('h2');
      $school{'name'} = $p->get_text('/h2');

      # verify format for school type
      $tag = $p->get_tag('span');
      unless (exists $tag->[1]{'class'} and $tag->[1]{'class'} eq 'schulart_text')
      {
        warn "unexpected format: parsing stopped";
        last;
      }

      $school{'type'} = $p->get_text('/span');

      # verify format for address
      $tag = $p->get_tag('p');
      unless (exists $tag->[1]{'class'} and $tag->[1]{'class'} eq 'einzel_text')
      {
        warn "unexpected format: parsing stopped";
        last;
      }
      $school{'address'} = clean_address($p->get_text('/p'));

      # find the description
      $tag = $p->get_tag('p');
      $school{'description'} = $p->get_text('/p');
    }
  }

  # speichere eine refenz auf den Hash mit den Daten der aktuellen Schule im Array mit allen Schulen
  push(@schools,\%school);
}

# Ausgabe in eine Datei als einfaches "XML" formatiert:
open(my $fh, '>', $out_file) or die("Error open $out_file ($!)\n");
print $fh "<schools>\n";
for my $school (@schools)
{
  print $fh "  <school>\n";
  print $fh "    <name>$school->{name}</name>\n";
  print $fh "    <location>$school->{location}</location>\n";
  print $fh "    <type>$school->{type}<type>\n";
  print $fh "    <address>\n";
  for my $address (@{$school->{address}})
  {
    print $fh "      <entry>$address</entry>\n";
  }
  print $fh "    </address>\n";
  print $fh "    <description>$school->{description}</description>\n";
  print $fh "  </school>\n";
}
print $fh "</schools>\n";
close($fh);

##########################################################################

# Funktion um die Adressen von unnötigen Zeichen zu befreihen
# und als Array jede Zeile zurück zu liefern
sub clean_address
{
my $text = shift;
my @lines = split "\n", $text;
for (@lines)
{
s/^s+//;
s/s+$//;
}
return \@lines;
}


Danke - eine wertvolle Chance zu lernen am praktischen code!


2010-10-04T22:25:48 topeg
Kannst du dir wenigstens vorstellen woher die nicht definierten Werte kommen? Warum die Warnung "unexpected format: parsing stopped at perl_script_six.pl line 59." auftauchte und was dir "diagnostic" im zweiten Quote sagen will. Ich übernehme nicht deine Arbeit. Lernen musst du schon selber. :-)


Da ist was im Format anders gewesen. Es gab ein Einzelergebnis das den Parser gestoppt hat. Gute Moeglichkeit zu lernen!

ich schau mir das heute Abend genauer an!

Meld mich später wieder!

lg
lin


nebenbei: neu sind von dir [u.a.]

Z9 - 10: # Array in der alle Schulen mit ihren Daten gespeichert werden sollen
my @schools;


Z 31 -32: # Speichrort für die Schuldaten in dieser Datei
my %school;

Frage: was ist hier denn der Unterschied!? Ich frag mich warum du das Array eingebaut hast. Werde dem mal heute nachgehen. Das hat das Originalscript nicht. Du hast es - so läuft es. Ich überleg mir mal warum du das drinnehast!!??



und ferner hast du noch:

z. 81 # speichere eine refenz auf den Hash mit den Daten der aktuellen Schule im Array mit allen Schulen
push(@schools,\%school);
}


Darüber hinaus am Ende des Scripts noch einige - sehr sehr gute & nützliche Dinge:...ich werd mal schauen, was die Zeilen machen!!

Grüße
Lin;-)




mod-edit pq: BITTE KEINE TEILBÄUME FÜR KOMMENTARE VERWENDEN. JETZT NEHME ICH DEN KOMMENTAR ZUM ZWEITEN MAL RAUS!


Last edited: 2010-10-05 14:20:24 +0200 (CEST)

View full thread I/O Operations: Pfade übertragen auf einen HTML-Parser