假设,我们有以下文件:
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>
解析器.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 从文件中读取时,会发生错误。
问题:
- 如何解决编码问题?
- 该模块将每个俄语字符编码为一个实体:
Е
。是否可以保存为字符Е
?
最佳答案
parse_file
方法将采用文件名或文件句柄,因此最简单的解决方案是使用 :utf8 通过
作为模式,然后传递要解析的文件句柄。open
调用打开文件
看起来像这样。我使用 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
中受益匪浅模块。
关于perl - 使用 HTML::TreeBuilder as_HTML 后编码损坏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25364248/