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

topeg
 2010-10-03 23:47
#141669 #141669
User since
2006-07-10
2611 Artikel
BenutzerIn

user image
Ich habe den Code mal lauffähig gemacht. Schau ihn dir an und versuche ihn zu verstehen. Ich hoffe die Kommentare helfen

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
120
#!/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;
}

Last edited: 2010-10-03 23:50:31 +0200 (CEST)

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