假设我们有以下文件:
的test.html
<!DOCTYPE html>
<html>
<head>
<title>Евгений Онегин</title>
<meta charset="utf-8">
</head>
<body>
<p><cite>Евгений Онегин</cite></p>
<pre>
Не мысля гордый свет забавить,
Вниманье дружбы возлюбя,
Хотел бы я тебе представить
Залог достойнее тебя,
</pre>
</body>
</html>
我想用HTML格式获取body标签的内容,使用解析器:
<p><cite>Евгений Онегин</cite></p>
<pre>
Не мысля гордый свет забавить,
Вниманье дружбы возлюбя,
Хотел бы я тебе представить
Залог достойнее тебя,
</pre>
parser.pl
#!/usr/bin/env perl
use strict;
use warnings;
use 5.010;
use utf8;
use HTML::TreeBuilder;
my $root = HTML::TreeBuilder->new;
$root->parse_file('test.html');
my $body = $root->find('body');
print $body->as_HTML;
当我将输出保存到HTML文件并在浏览器中以Unicode格式观看时,编码被破坏:而不是“ЕвгенийОнегин”我得到“ЕвгÐμнийОнÐμгин”。
当HTML存储在Perl文件中时,它可以正常工作:
#!/usr/bin/env perl
use strict;
use warnings;
use 5.010;
use utf8;
use Data::Dumper;
use HTML::TreeBuilder;
my $root = HTML::TreeBuilder->new;
$root->parse_file(\*DATA);
my $body = $root->find('body');
print $body->as_HTML;
__END__
<!DOCTYPE html>
<html>
<head>
<title>Евгений Онегин</title>
<meta charset="utf-8">
</head>
<body>
<p><cite>Евгений Онегин</cite></p>
<pre>
Не мысля гордый свет забавить,
Вниманье дружбы возлюбя,
Хотел бы я тебе представить
Залог достойнее тебя,
</pre>
</body>
</html>
因此,当HTML :: TreeBuilder从文件中读取时,会发生错误。
问题:
Е
。是否可以将其保存为角色Е
?答案 0 :(得分:4)
parse_file
方法将采用文件名或文件句柄,因此最简单的解决方案是使用open
作为模式通过:utf8
调用打开文件,然后传递要解析的文件句柄。
看起来像这样。我只使用了new_from_file
构造函数,因为它保存了一个语句。它与您自己的代码具有完全相同的效果。
#!/usr/bin/env perl
use strict;
use warnings;
use 5.010;
use utf8;
use HTML::TreeBuilder;
my $file = 'test.html';
open my $fh, '<:utf8', $file or die qq{Unable to open "$file" for parsing: $!};
my $root = HTML::TreeBuilder->new_from_file($fh);
my $body = $root->find('body');
print $body->as_HTML;
至于将实体更改为字母,我不清楚你的意思。您是否只想删除所有十六进制实体并用等效字符替换它们?您可能会从HTML::Entities
模块中获得一些里程数。
答案 1 :(得分:3)
您可以使用man HTML::TreeBuilder
中记录的字符集自动检测。
当您将文件名传递给
parse_file
时,HTML::Parser
会以二进制模式打开它,这意味着它被解释为Latin-1(ISO-8859-1
)。如果文件采用其他编码方式,例如UTF-8
或UTF-16
,则无法做到正确。一种解决方案是使用正确的
:encoding
图层自行打开文件,并将文件句柄传递给parse_file
。您可以使用html_file
inIO::HTML
自动完成此过程,IO::HTML
将使用HTML5
编码嗅探算法自动确定正确的:encoding
图层并应用它。在
HTML-Tree
的下一个主要版本中,我计划让它自动使用IO::HTML
。如果您确实希望以二进制模式打开文件,则应自行打开并将文件句柄传递给parse_file
。
因此,使用https://stackoverflow.com/a/24577042/2139766自动检测已打开文件的字符集。
use HTML::TreeBuilder;
use IO::HTML; # exports html_file by default
my $root = HTML::TreeBuilder->new;
$root->parse_file(html_file('test.html'));
{{3}}