perl - 使用 HTML::TreeBuilder as_HTML 后编码损坏

标签 perl encoding html-parsing

假设,我们有以下文件:

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 从文件中读取时,会发生错误。

问题:

  1. 如何解决编码问题?
  2. 该模块将每个俄语字符编码为一个实体:Е。是否可以保存为字符Е

最佳答案

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/

相关文章:

bash - 在嵌套的单引号、反引号和引号中转义美元符号

perl - 错误 : 500 Can't connect to foo. com:443(未知错误错误:140773F2:SSL 例程:SSL23_GET_SERVER_HELLO:sslv3)

javascript - 什么 perl 正则表达式可以正确匹配 javascript 关联数组?

python - BeautifulSoup 中的 .descendants 似乎没有按预期工作

perl - 使用 perl 以毫秒为单位获取 unix 时间戳

python 3 : Read UTF-8 file containing German umlaut

json - 如何在 swift 中使用 utf-8 解码 json 文件 3/4

java - Java 编程语言中的编码

python - 如何通过bs4传递搜索键并获取结果

android - 如何检查在android中的Jsoup html解析器中是否存在标签