Thread UTF-8 Encode HTML::Parser DBI (3 answers)
Opened by kristian at 2009-10-13 22:22

kristian
 2009-10-13 22:22
#126947 #126947
User since
2005-04-14
684 Artikel
BenutzerIn
[Homepage] [default_avatar]
Hallo

Ich stehe gerade völlig auf dem Schlauch.
Die Situation: Ich lese via LWP Webseiten aus, ermittele das Charset will das Ganze nach UTF wandeln, dann HTML::Parser drüberschicken und das Ergebnis des Parsers in ein MySQL-DB schreiben.
Folgender Code macht mir Schwierigkeiten:

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
    my $content = '';

    if($data->{'content'} && $data->{'charset'}){
        if($data->{'charset'} eq 'utf-8'){
            $data->{'content'} = decode("utf-8",$data->{'content'});       # make perl characters, Encode.pm
            $data->{'content'} = decode_entities($data->{'content'});      # add signs from HTML::Entities
            $content = encode("utf-8",$data->{'content'});                 # make octets for disk-writing, Encode.pm
        }else{
            my $length = from_to($data->{'content'}, find_encoding($data->{'charset'}), "utf-8");
            if($length){
                $data->{'content'} = decode("utf-8",$data->{'content'});        # make perl characters, Encode.pm
                $data->{'content'} = decode_entities($data->{'content'});       # add signs from HTML::Entities     
                $content = encode("utf-8",$data->{'content'});                  # make octets for disk-writing, Encode.pm               
            }else{
                _log_message("Charset $data->{'charset'} not supported", 1);
            }
        }
    }

    if(length($content)){
        $p->parse($content); # HTML::Parser (  can('utf8_mode') && $p->utf8_mode(1) )
    }


Wenn ich es so mache sind die Daten für den Parser problemlos.
Mache ich es so:
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
    my $content = '';

    if($data->{'content'} && $data->{'charset'}){
        if($data->{'charset'} eq 'utf-8'){
            $data->{'content'} = decode("utf-8",$data->{'content'});       # make perl characters, Encode.pm
            $data->{'content'} = decode_entities($data->{'content'});      # add signs from HTML::Entities
            $content = $data->{'content'};
        }else{
            my $length = from_to($data->{'content'}, find_encoding($data->{'charset'}), "utf-8");
            if($length){
                $data->{'content'} = decode("utf-8",$data->{'content'});        # make perl characters, Encode.pm
                $data->{'content'} = decode_entities($data->{'content'});       # add signs from HTML::Entities     
                $content = $data->{'content'};          
            }else{
                _log_message("Charset $data->{'charset'} not supported", 1);
            }
        }
    }

    if(length($content)){
        $p->parse($content); # HTML::Parser (  can('utf8_mode') && $p->utf8_mode(1) )
    }

bekomme ich die nette Meldung:
Quote
Wide character in subroutine entry at ./crawler line 156 (#1)
(W utf8) Perl met a wide character (>255) when it wasn't expecting
one. This warning is by default on for I/O (like print). The easiest
way to quiet this warning is simply to add the :utf8 layer to the
output, e.g. binmode STDOUT, ':utf8'. Another way to turn off the
warning is to add no warnings 'utf8'; but that is often closer to
cheating. In general, you are supposed to explicitly mark the
filehandle with an encoding, see open and perlfunc/binmode.

Uncaught exception from user code:
Wide character in subroutine entry at ./crawler line 156.
at ./crawler line 155

Zeile 155 ist $p->parse, der mag das also nicht.

Soweit so gut. Das wäre ja nicht tragisch aber wenn ich die Daten in die DB schreiben will staune ich.

Sowohl
Code (perl): (dl )
$sql_res = $sth_1->execute($data->{'url'}, $title, $keywords, $description, "@all_words") or die($sth_1->errstr());

als auch:
Code (perl): (dl )
$sql_res = $sth_1->execute(decode("utf-8",$data->{'url'}), decode("utf-8",$title), decode("utf-8",$keywords), decode("utf-8",$description), decode("utf-8","@all_words")) or die($sth_1->errstr());

ergibt in der DB die netten ü, ä usw.
Einzig wenn ich die Daten im oberen Code, zweiter Eintrag nich encode bleibt das, was versehentlich durch den Parser geht, heile und es stehen die richtigen Umlaute in der DB.

Habe ich da irgendwo nen groben Denkfehler?
Es kann doch nicht sein, daß ich etwas das ich encode nicht zurück decoden kann?

Gruß
Kristian
Last edited: 2009-10-13 22:24:13 +0200 (CEST)

View full thread UTF-8 Encode HTML::Parser DBI