Почему Perl LWP дает мне другую кодировку, чем оригинальный сайт? - PullRequest
3 голосов
/ 26 февраля 2010

Допустим, у меня есть этот код:

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), но мой собственный статический текст выглядит как «× ×», «× 1017 *

Еще одна вещь, которую я протестировал, это ...

Через Perl:

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

Я получаю кодировку utf8.

Через Баш:

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 ]

8 голосов
/ 26 февраля 2010

Все это ручное кодирование и декодирование не требуется. HTML обманывает вас, когда он говорит, что страница закодирована в windows-1255; сервер говорит, что обслуживает UTF-8, и это так. Во всем виноваты инструменты HTML-генерации Microsoft.

В любом случае, поскольку сервер возвращает правильную кодировку, это работает:

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

$content теперь строка символов perl, готовая сделать все, что вам нужно. Если вы хотите преобразовать его в какую-то другую кодировку, тогда вызовите Encode::encode для него; не используйте Encode::decode, поскольку он уже был декодирован один раз.

5 голосов
/ 26 февраля 2010

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). Возможно, вы захотите кодировать / декодировать ваших строк.

3 голосов
/ 26 февраля 2010

Во-первых, обратите внимание, что вы должны импортировать get из LWP :: Simple . Во-вторых, все отлично работает с:

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

, который указывает мне, что проблема заключается в кодировке дескриптора файла, которому вы отправляете вывод.

2 голосов
/ 26 февраля 2010

Строка с введенными вами шестнадцатеричными значениями выглядит как кодировка UTF-8. Вы получаете это, потому что Perl «любит» использовать UTF-8, когда имеет дело со строками. Метод LWP::Simple->get() автоматически декодирует контент с сервера, который включает в себя отмену любой кодировки контента, а также преобразование в UTF-8.

Вы можете покопаться во внутренних органах и получить версию, которая изменяет кодировку символов (см. HTTP :: Message's decoded_content , который используется HTTP :: Response's decoded_content , который вы можете получить от LWP :: UserAgent's get ). Но может быть проще перекодировать данные в желаемую кодировку, например,

use Encode; 
...; 
$cp1255_bytes = encode('CP1255', decode('UTF_8', $utf8_bytes));

Смешанные читаемые / мусорные символы, которые вы видите, происходят из-за смешивания нескольких несовместимых кодировок в одном потоке. Возможно, поток помечен как UTF-8, но вы помещаете в него символы в кодировке CP1255. Либо нужно пометить поток как CP1255 и поместить в него только данные в кодировке CP1255, либо пометить его как UTF-8 и поместить в него только данные в кодировке UTF-8. Напомните себе, что байты не являются символами, и соответствующим образом преобразуйте их.

...