【问题标题】:Wide character print even with utf8 encoding即使使用 utf8 编码也能打印宽字符
【发布时间】:2016-03-17 05:07:03
【问题描述】:

即使编码设置为utf8,我也会收到"Wide character in print" 警告:

use WWW::Mechanize;
$mech = new WWW::Mechanize;
$mech->get("http://www.ilo.org/dyn/triblex/triblexmain.fullText?p_lang=en&p_judgment_no=88&p_language_code=FR");
$mech->save_content("output.html", binmode => ':encoding(UTF-8)');

这个问题的解决方法是什么?

【问题讨论】:

  • 你确定是这条线发出警告吗?我不明白这怎么可能
  • 你是说因为binmode => ':encoding(UTF-8)'而不可能吗?警告位于 Mechanize 中的一行。
  • 请提供一个最小的、可运行的问题演示。

标签: perl utf-8 character-encoding mechanize


【解决方案1】:

看起来:encoding(UTF-8) 没有被正确理解。

$mech->save_content($filename, binmode => ':raw:utf8');

应该有效

UPD:有关 binmode 指令(Perl IO 层)的信息可以在这里找到:http://perldoc.perl.org/PerlIO.html

【讨论】:

  • binmode 可以使用哪些选项?
  • “所有选项”是什么意思?当您使用“binmode”时,您对 Perl 解释器说将文件句柄视为二进制而不是文本,而您提到的“选项”实际上是关于如何处理此特定文件句柄上的行尾、字符编码等的指令
  • 那么您可以使用哪些指令?你提到了:raw:utf8。还有哪些可以用?
  • 它们也被称为 I/O 层,它们在 AFAIK 中的记录很差。可以在以下位置找到一些东西:perldoc.perl.org/PerlIO.html
  • :encoding(UTF-8) 已在此处列出。如果:raw:utf8 是,为什么不理解?
【解决方案2】:

我无法重现您收到的警告。如果我按原样运行您显示的代码,我根本不会收到任何警告。但该网站似乎确实有问题。我编写了这个程序,它使用LWP 并完全跳过WWW::Mechanize

use strict;
use warnings 'all';

binmode STDOUT, ':utf8';

use LWP;

use constant URL => 'http://www.ilo.org/dyn/triblex/triblexmain.fullText?p_lang=en&p_judgment_no=88&p_language_code=FR';

my $ua = LWP::UserAgent->new;

my $res = $ua->get(URL);

print $res->headers_as_string, "\n";

my $n = 0;
for my $chr ( unpack '(A1)*', $res->decoded_content ) {
    my $ord = ord $chr;
    printf "%4d: %04x\n", ++$n, $ord if $ord >= 0x7f;
}

响应具有完全合理的标头,但响应正文中所有带重音的非 ASCII 字符都是 Unicode FFFD REPLACEMENT CHARACTER

这不应该导致 Wide character in print 错误,但它肯定是错误的。请检查您是否拥有最新版本的LWPWWW::Mechanize

Connection: Keep-Alive
Date: Thu, 17 Mar 2016 23:15:12 GMT
Via: 1.1 www.ilo.org
Server: Oracle-Application-Server-10g/10.1.3.5.0 Oracle-HTTP-Server
Vary: Accept-Encoding,User-Agent
Content-Length: 10132
Content-Type: text/html; charset=UTF-8
Client-Date: Thu, 17 Mar 2016 23:15:12 GMT
Client-Peer: 193.134.195.36:80
Client-Response-Num: 1
Keep-Alive: timeout=5, max=98
Title: Jugement No 88 (TAOIT) - Tribunal administratif

   1: fffd
   2: fffd
   3: fffd
   4: fffd
   5: fffd
   6: fffd
   7: fffd
   8: fffd
   9: fffd
  10: fffd
... etc. to
 316: fffd
 317: fffd
 318: fffd
 319: fffd
 320: fffd
 321: fffd

【讨论】:

  • 可能是perlMechanize的版本。这是我收到的警告:Wide character in print at /usr/local/lib/perl5/site_perl/5.16.3/WWW/Mechanize.pm line 2044.
  • 是的。正如我所说,请检查WWW::MechanizeLWP 的版本。您可能还想查看Encode。您可以通过perl -MEncode -E"say $Encode::VERSION" 等查询。您运行的是什么版本的 Perl?
  • perl 5, 版本 16, subversion 3 (v5.16.3) 为 sun4-solaris 构建
  • 我在 Perl v5.22.1 for Windows 上进行测试,有Encode v2.78 LWP v6.15 和WWW::Mechanize v1.75
  • 但请记住,通过修复此问题,您将得到的只是警告将消失。 www.ilo.org Web 服务器正在发送无用的 Unicode 字符,必须修复
【解决方案3】:

我在下载 .xlsx 文件(使用 Mechanize)并随后使用 Spreadsheet::ParseXLSX 读取它们时遇到了类似的问题。我在 $mech->save_content() 期间收到“宽字符”警告,随后收到 ParseXLSX 读取错误(“格式错误:签名错误”和“无法将文件作为 zip 文件打开”错误)。 Mechanize 文档说,在 save_content 方法中添加 'binary -> 1' 选项是确保逐字节复制内容的“最安全”方式。我试过了,它奏效了!这里提到的 binmode 选项不起作用。

【讨论】:

    猜你喜欢
    • 2021-08-21
    • 2021-08-02
    • 1970-01-01
    • 2016-12-29
    • 1970-01-01
    • 2020-07-15
    • 2013-06-25
    • 1970-01-01
    • 2023-03-23
    相关资源
    最近更新 更多