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
コメントする