WWW::MechanizeやWeb::Scraperはmetaタグを見てデコードするが、charset=Shift_JISのコンテンツって実際にはCP932なので化けるのを防ぐEncode::Alias
スポンサードリンク
WWW::MechanizeというPerlのウェブブラウザになりきるモジュールで、2006年9月の、バージョン1.21_01から、自動的にHTML文書のmetaタグなどからエンコーディングを取得して、デコードしてくれるのだけれども、オンライン上にあるほとんどのShift_JIS指定のHTML文書のほとんどが実際にはCP932(シフトJISのMicrosoft拡張)になっているために、文字化けしちゃうっていう問題があって、どうすれバインダー(未解決)っていうのを以前やりました。
M.C.P.C.: WWW::Mechanizeはmetaタグを見てデコードするが、charset=Shift_JISのコンテンツって実際にはCP932なので化けるじゃねえか問題
んで、おととい、東北電力の計画停電予定を公表するページのHTMLをYAMLに変換するやつを作ったのですけれども、
M.C.P.C.: 東北電力の計画停電予定告知ページのHTMLからYAMLに変換するPerlスクリプト
その際利用した、Web::Scraperでも同じ問題があったので、ちょっと調べてみたら、解決する方法を見つけました。
問題は、HTML文書がCP932で規定された範囲の文字(髙橋の「髙」、山﨑の「﨑」など)が使われているのに、metaタグでは、<meta http-equiv="content-type" content="text/html; charset=Shift_JIS">とかしなくちゃいけないので、metaタグを真面目に参照すると、文字化けが起こるっていうことです。
これを解決するには、
cp932 vs. shift_jis - Bulknews::Subtech - subtech [g.hatena.ne.jp]
この手の話はよくみるけど、cp932 のほうがうれしいということであれば単純に
use Encode::Alias; define_alias( qr/shift.*jis$/i => '"cp932"' ); define_alias( qr/sjis$/i => '"cp932"' );としてShift_JISを cp932 のエイリアスにしちゃえばいいんじゃないのかなあ? ていうかこの例は perldoc Encode::Alias にでてくる。
ということで、Encode::Aliasを使って、他の場所でShift_JISをエンコーディングに指定しても、実際にはCP932を指定している、ということにしてしまえばいいのですね。
こうなります。
Filename: sjis.html(シフトJISで保存)
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=Shift_JIS" />
<title>髙橋~山﨑 テスト</title>
</head>
<body>
<p>髙橋</p>
<p>~</p>
<p>山﨑</p>
</body>
</html>
これを、前回のコード
use strict;
use warnings;
use utf8;
use WWW::Mechanize;
binmode STDOUT => ':utf8';
my $mech = WWW::Mechanize->new();
$mech->agent('Windows IE 6');
$mech->get('http://www.example.com/sjis.html');
print $mech->content();
exit;
__END__
で取得すると……
$ perl sjis.pl
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=Shift_JIS" />
<title>��橋〜山�ア テスト</title>
</head>
<body>
<p>��橋</p>
<p>〜</p>
<p>山�ア</p>
</body>
</html>$
となってしまうのですが、
こういうコード
use strict;
use warnings;
use utf8;
use WWW::Mechanize;
binmode STDOUT => ':utf8';
use Encode::Alias;
define_alias( qr/shift.*jis$/i => '"cp932"' );
define_alias( qr/sjis$/i => '"cp932"' );
my $mech = WWW::Mechanize->new();
$mech->agent('Windows IE 6');
$mech->get('http://www.example.com/sjis.html');
print $mech->content();
exit;
__END__
で取得すると、
$ perl sjis.pl
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=Shift_JIS" />
<title>髙橋~山﨑 テスト</title>
</head>
<body>
<p>髙橋</p>
<p>~</p>
<p>山﨑</p>
</body>
</html>
$
と平気です。
Encode::Aliasは、Shift_JIS(実際にはCP932)のHTMLをマニピュレートしなくてはいけない場合に必須っぽいですね!
スポンサードリンク
トラックバック(0)
トラックバックURL: http://blog.dtpwiki.jp/MTOS/mt-tb.cgi/3538





![: Amazon.co.jp: プラスティック・メモリーズ 1【完全生産限定版】(イベントチケット優先販売申込券付) [Blu-ray]](/lists/_9/B00VWX66E8.jpg)
![: Amazon.co.jp: プラスティック・メモリーズ 2【完全生産限定版】[Blu-ray]](/lists/_9/B00VWX66K2.jpg)
![: Amazon.co.jp: プラスティック・メモリーズ 3【完全生産限定版】[Blu-ray]](/lists/_9/B00VWX6MV0.jpg)
![: Amazon.co.jp: プラスティック・メモリーズ 4【完全生産限定版】[Blu-ray]](/lists/_9/B00VWX66IO.jpg)
![: Amazon.co.jp: プラスティック・メモリーズ 5【完全生産限定版】[Blu-ray]](/lists/_9/B00VWX6Y0E.jpg)
![: Amazon.co.jp: プラスティック・メモリーズ 6【完全生産限定版】[Blu-ray]](/lists/_9/B00VWX69D6.jpg)


コメントする