为什么Perl的LWP给我的编码与原始网站不同?

时间:2010-02-26 11:15:15

标签: perl content-encoding lwp windows-1255

假设我有这段代码:

use strict;
use LWP qw ( get );

my $content = get ( "http://www.msn.co.il" );

print STDERR $content;

错误日志显示类似“\ xd7 \ x9c \ xd7 \ x94 \ xd7 \ x93 \ xd7 \ xa4 \ xd7 \ xa1 \ xd7 \ x94” 我猜它是utf-16?

网站的编码是

<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1255">

那么为什么会出现这些字符而不是windows-1255字符呢?

而另一个奇怪的事情是我有两台服务器:

第一台服务器返回CP1255字符,我只需将其转换为utf8, 并且当前的服务器给了我这些字符,我无法用它做任何事情......

apache / perl / module中是否有任何配置文件搞乱了编码? 强迫某事......?

我的网站在第二台服务器上的结果是perl文件和标题都是utf8,所以当我写的文字不是英文字符时,上面例子中的内容显示正常(即使它是奇怪的utf chars)但我自己的静态文本看起来像“×ס××ר××:”

我测试的另一件事是......

通过perl:

my $content = `curl "http://www.anglo-saxon.co.il"`;    

我得到utf8编码。

通过Bash:

curl "http://www.anglo-saxon.co.il"

在这里我得到CP1255(Windows-1255)编码......

另外, 当我在bash中运行脚本时 - 它给出了CP1255,当它通过网络运行时 - 然后它又是utf8 ......

通过将内容从utf8改为 - 应该是什么来解决问题,然后再回到utf8:

use Text::Iconv;

my $converter = Text::Iconv->new("utf8", "CP1255");
   $content=$converter->convert($content);

my $converter = Text::Iconv->new("CP1255", "utf8");
   $content=$converter->convert($content);

4 个答案:

答案 0 :(得分:8)

所有这些手动编码和解码都是不必要的。当HTML表示页面在windows-1255中编码时,HTML就在骗你;服务器说它正在服务UTF-8,它确实如此。归咎于Microsoft HTML生成工具。

无论如何,由于服务器 返回正确的编码,因此有效:

my $response = LWP::UserAgent->new->get("http://www.msn.co.il/");
my $content = $res->decoded_content;

$content现在是一个perl字符串,随时可以随心所欲。如果要将其转换为其他编码,则在其上调用Encode::encode是合适的; 使用Encode::decode因为它已被解码一次。

答案 1 :(得分:5)

http://www.msn.co.il是UTF-8,表示正确。字符串“\ xd7 \ x9c \ xd7 \ x94 \ xd7 \ x93 \ xd7 \ xa4 \ xd7 \ xa1 \ xd7 \ x94”也是正确的UTF-8(להדפסה)。我没有看到问题。

我认为您的第二个问题是由于您混合了不同的编码(UTF-8和Windows-1252)。您可能需要encode/decode正确的字符串。

答案 2 :(得分:3)

首先,请注意您应从LWP::Simple导入get。其次,一切正常:

#!/usr/bin/perl
use strict; use warnings;
use LWP::Simple qw ( getstore );
getstore 'http://www.msn.co.il', 'test.html';

它向我表明问题是您要向其发送输出的文件句柄的编码。

答案 3 :(得分:2)

您提供的十六进制值的字符串似乎是UTF-8编码。你得到这个是因为Perl'喜欢'在处理字符串时使用UTF-8。 LWP::Simple->get()方法自动解码服务器中的内容,包括撤消任何内容编码以及转换为UTF-8。

您可以深入了解内部并获得一个确实会更改字符编码的版本(请参阅HTTP::Message's decoded_contentHTTP::Response's decoded_content使用LWP::UserAgent's get,您可以从{{3}}获取该版本。但是使用类似

之类的东西重新编码所需编码中的数据可能更容易
use Encode; 
...; 
$cp1255_bytes = encode('CP1255', decode('UTF_8', $utf8_bytes));

您看到的混合可读/垃圾字符是由于在同一个流中混合了多个不兼容的编码。该流可能标记为UTF-8,但您将CP1255编码的字符放入其中。您需要将流标记为CP1255并仅将CP1255编码的数据放入其中,或将其标记为UTF-8并仅将UTF-8编码的数据放入其中。提醒自己字节不是字符,并在它们之间进行适当的转换。