2010-02-26 9 views
3

내가이 코드가 있다고 가정하자 :왜 Perl의 LWP가 원본 웹 사이트와 다른 인코딩을 제공합니까?

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" 같은 표시를하는 나는 그것을 ~~16이라고 추측하고 있나?

웹 사이트의 인코딩은

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

가 왜 이러한 문자는 Windows-1255의 문자를 표시하지 함께?

첫 번째 서버 반환 CP1255의 문자와 나는 단순히 UTF8, 로 변환 할 수 있으며 현재 서버 나에게 이러한 문자를주고 내가 할 수 없습니다

그리고, 또 다른 이상한 것은 내가 두 서버를 가지고있다 그것으로 무엇이든 ...

인코딩을 엉망으로 만드는 apache/perl/module의 구성 파일이 있습니까? 강제로 ...?

두 번째 서버에서 내 웹 사이트에있는 결과는 perl 파일과 헤더가 모두 utf8이므로 영어 문자가 아닌 텍스트를 작성하면 위 예제의 내용이 ok로 표시됩니다. 그것은 이상한 UTF의 문자를입니다)하지만 내 자신의 정적 텍스트는 "×× ¡ '××× ¨ ×× :"같이하는

내가이 시험을 한 가지 더 ... 펄을 통해

:

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

utf8 인코딩이 있습니다.

배쉬를 통해

: 내가 bash는 스크립트를 실행할 때

또한, 이

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

여기에 내가 얻을 CP1255 (윈도우 1255) 인코딩 ... -이 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); 

답변

2

입력 한 16 진수 값이있는 문자열은 UTF-8 인코딩으로 보입니다. Perl은 문자열을 다룰 때 UTF-8을 사용하기를 좋아하기 때문에 이것을 얻고 있습니다. LWP::Simple->get() 메서드는 콘텐츠 인코딩을 취소하고 UTF-8로 변환하는 작업을 포함하여 서버에서 콘텐츠를 자동으로 해독합니다.

내부를 들여다가 문자 인코딩을 변경하는 버전을 얻을 수 있습니다 (HTTP::Response's decoded_content에 의해 사용되는 HTTP::Message'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로 인코딩 된 데이터 만 UTF-8로 인코딩해야합니다. 바이트는 문자가 아니며 적절하게 변환해야 함을 상기시킵니다.

+0

"넓은 문자로 문자열을 디코딩 할 수 없습니다." –

+0

정확히 답이 아니지만 귀하의 조언을 받아 들였습니다. Text :: Iconv 사용 ; \t my $ converter = Text :: Iconv-> new ("utf8", "CP1255"); \t $ content = $ converter-> convert ($ content); \t \t my $ converter = Text :: Iconv-> new ("CP1255", "utf8"); \t $ content = $ converter-> convert ($ content); 문제가 해결되었습니다 .... 예! –

+0

"넓은 문자가 포함 된 문자열을 디코딩 할 수 없습니다."라는 오류는 문자열이 이미 디코딩되었음을 나타냅니다. Perl의 내부 인코딩이 UTF-8이기 때문에'Text :: Iconv'의 UTF-8-> CP1255-> UTF-8 변환 만 사용됩니다. 원래'$ content'는 (디코드에서 얻은 에러 메시지에 따라) 문자열이지만'byte' 문자열을'convert'에 전달해야합니다. 원하는 경우'encode ('UTF-8', $ content)'를 사용하여 UTF-8 바이트 문자열을 얻을 수 있습니다. –

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 할 수 있습니다.

+0

응답 해 주셔서 감사합니다.하지만 msn.co.il을 예로 들었습니다. 보기 : http://www.anglo-saxon.co.il/ –

3

먼저 getLWP::Simple에서 가져와야합니다. 문제는 출력을 보낼 수있는 파일 핸들의 인코딩을 나에게 나타내는

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

: 둘째, 모든과 함께 잘 작동합니다.

8

이 모든 수동 인코딩 및 디코딩은 필요하지 않습니다. 페이지가 Windows-1255로 인코딩되었다고 말하면 HTML이 거짓말합니다. 서버는 UTF-8 서비스를 제공한다고 말합니다. Microsoft HTML 생성 도구를 비난하십시오. 서버 가 올바른 인코딩을 반환 않기 때문에

어쨌든,이 작품 :

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

$content 지금 당신이 필요로하는 무엇이든 할 준비가 펄 문자열입니다. 다른 인코딩으로 변환하려면 Encode::encode을 호출하는 것이 적절합니다. 이 아닌을 사용하면 Encode::decode이 이미 한 번 해독되었습니다.