Почему LWP в Perl дает мне другую кодировку, чем на оригинальном сайте?

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

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

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

Через 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 ответа

Решение

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

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

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

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

Все это ручное кодирование и декодирование не требуется. 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 как это уже было декодировано один раз.

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

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

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

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

Другие вопросы по тегам