• 締切済み

UTF-8で書かれたHTMLファイルをShift-JISのファイルに変換できない

#!/usr/bin/perl -w =begin comment OS: Windows XP Perl: Active Perl v5.8.8 スクリプトは「Shift-JIS」で書いています。 日本語処理関係で参考にしているのはもっぱらオライリージャパンの「Spidering Hacks」の付録の翻訳者 による日本語処理の解説です。 http://oshiete1.goo.ne.jp/qa3716434.html の回答に従い、use encoding 'shiftjis'; から use encoding 'cp932'; へ変更している以外は そこに書かれているやり方に従っていると思います。 UTF-8で書かれたHTMLファイルを「LWP::UserAgent」で取得し、それを Shift-JISコードで出力したいと思い以下のコードを実行したのですが、 以下のエラーが出てしまいました。 Parsing of undecoded UTF-8 will give garbage when decoding entities at C:/usr/local/site/lib/LWP/Protocol.pm line 114. このエラーは何が原因なのでしょうか? =end comment =cut use strict; use LWP 5.64; use Encode; use encoding 'cp932'; # http://oshiete1.goo.ne.jp/qa3716434.html の回答に従い、'shiftjis'から'cp932'へ変更。 #use encoding 'shiftjis'; binmode(STDERR, ':raw :encoding(shiftjis)'); my $url = "http://www.audiounion.jp/bin/products/used/A0/-/-/"; my $browser = LWP::UserAgent->new; my $response = $browser->get( $url ); die "cannot get $url:", $response->status_line unless $response->is_success; my $content = Encode::decode('utf8', $response->content); print $content;

  • Perl
  • 回答数3
  • ありがとう数1

みんなの回答

  • YkazubonY
  • ベストアンサー率30% (26/86)
回答No.3

garbageというぐらいだから、(株)とかのゴミ文字(一文字)が変換できないという意味では? だとすると、黙って変換してくれるJcodeの方が良いと思う。 ゴミ文字は、黙って??になるべ。 (例) use Jcode; Jcode:convert(\$str, $ocode, $icode);

  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.2

Spidering Hacksにあったサンプルスクリプトで、LWP(やそのほかのモジュール)と use encoding を組み合わせて使っているものってありましたっけ? encoding::warnings - Warn on implicit encoding conversions - search.cpan.org http://search.cpan.org/~audreyt/encoding-warnings-0.11/lib/encoding/warnings.pm に In other words, do not use encoding unless you are certain that the program will not deal with any raw, 8-bit binary data at all. ってあるように、このプラグマを使うのは非常に面倒が伴います。 出力をShiftJIS(cp932)にするのは自前でやるか、binmode を使って設定すればよいと思います。 スクリプトをShiftJISで書くのはオススメできないんですけどねえ。 スクリプトの中のリテラル文字列としてダメ文字が現れないのなら いっそ無指定でもいいと思います。

  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.1

use encoding 'xxx' というのは、外部から入力があったときに 自動的に 'xxx' という文字コードから内部表現(フラグつきUTF-8)に 変換してくれるというものです。 ですから、想定している 'xxx' (今回の例ではcp932 (or shiftjis))以外の 文字コードが来ると、とんでもない変換をかますという結果になります。 また、自分のスクリプトで行った use encoding の影響はそこで取り込んでいる モジュールにも及びます。 その結果、モジュールの作り手の想定外の状況になる可能性があります。 質問にあるスクリプトを見る限りではuse encoding をする必要は ないような気がするのですがなぜしているのでしょうか?

gle_gle
質問者

補足

ご回答ありがとうございます。 「use encoding 'cp932';」 としているのは、 「print $content;」 で標準出力に出力する際に UTF-8 から Shift-JIS に変換 するため、 また、スクリプトを Shift-JIS で書いているためです。 「Spidering Hacks」という本の翻訳書の付録の村上雅章 さんの日本語処理の解説に従いました。

関連するQ&A

  • HTTP::Request::Common qw(POST);時にソフト表だとエラーになる

    お世話になります。 HTTP::Request::Common qw(POST);を使ってPOSTする際、aaa=> 'あいう',などの日本語はPOST後、データが渡っている事が確認できるのですが、'ソフト表'等の文字列をあえて送ろうとすると、エラーになってしまいます。 記述はShift_JISで行っています。 先生方、ご教授ねがえませんでしょうか。 #!/usr/bin/perl BEGIN{ $| = 1; print "Content-type: text/html\n\n"; open(STDERR, ">&STDOUT"); } use HTTP::Request::Common qw(POST); use LWP::UserAgent; #use open IN => ":utf8"; # 入力をUTF8とする #use open OUT => ":shiftjis"; #use open ":std"; #use Encode; use encoding 'shiftjis', STDIN=>'utf8', STDOUT=>'shiftjis'; #binmode STDOUT, ":encoding(utf-8)"; #binmode STDOUT, ":encoding(shiftjis)"; #use open ":encoding(shiftjis)"; #require './jcode.pl'; my $ua = LWP::UserAgent->new; #タイムアウトを設定 $ua->timeout(10); my $req1 = POST 'http://domain.com/test.cgi', [ aaa => 'www1', bbb => "ソフト表" ,#bbb=> 'あいう',だとエラーになりません ]; print $ua->request($req1)->as_string;

    • ベストアンサー
    • Perl
  • HTML::TreeBuilderについてです

    perlで特定のhtmlタグの情報を抜き出そうとしてHTML::TreeBuilderを使おうとしているのですが、インストールして実行してもlook_downメソッドがないといわれます。 しっかりとインストールはしているのであるはずなのですが・・・ どうすればよいか皆目見当もつかないのでどうぞよろしくお願いします。 ちなみにコードは以下の通りです↓ use strict; use warnings; use LWP::UserAgent; use HTML::TreeBuilder; use HTML::Element; use Encode; # urlを指定する my $url = 'http://www.nikkansports.com/'; # IE8のフリをする my $user_agent = "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0)"; # LWPを使ってサイトにアクセスし、HTMLの内容を取得する my $ua = LWP::UserAgent->new; my $res = $ua->get($url); my $content = $res->content; # HTML::TreeBuilderで解析する my $tree = HTML::TreeBuilder->new; $tree->parse($content); $tree = decode("UTF-8",$tree); $tree = encode("Shift_JIS",$tree); # DOM操作してトピックの部分だけ抜き出す。 # <div id='topicsfb'><ul><li>....の部分を抽出する my @items = $tree->look_down('id', 'sideRanking')->find('li'); print $_->as_text."\n" for @items;

    • ベストアンサー
    • Perl
  • 文字コードの変換(Shift-JISからUTF8)

    文字コードがShift-JISのCSVファイルを読み込み、UTF-8のテキストファイルに出力するのに プログラムの中で変更しようとしているのですが、うまくいきません。出力ファイルの文字コードを 確認するとShift-JISのままです。 どなたか教えていただけないでしょうか? ActivePerl v5.16.0を使用し、Encodeモジュールのfrom_toを使用しています。 #!/usr/bin/perl use strict; use warnings; use utf8; use Encode; my $input_file="input.csv"; my $output_file="output.txt"; open (IN, $input_file) or die "$!"; open (OUT, ">$output_file") or die "$!"; while (<IN>){ chomp ($_); my @data=split(/,/,$_); for(my $i=0;$i<@data;$i++){ $data[$i]=Encode::from_to($data[$i],'shiftjis','utf8'); #Shift-JISからUTF-8に変換 $data[$i]=~s/\s+//g; print OUT $_; } print OUT "\n"; } close (IN); close (OUT);

    • ベストアンサー
    • Perl
  • perlのLWPがページによって、正常に作動しません?

    下記コードを書いたのですが、ページのソースを取得することができません。 どのように変えれば、取得することができますでしょうか? 因みに、URL部分を、 http://www.amazon.co.jp/gp/product/B000H9I0F6 とした場合は正常に取得できました。 お分かりになる方、何卒、宜しくお願い致します。 #!/usr/bin/perl print "Content-Type: text/plain\n\n"; use LWP; use HTTP::Cookies; $url="http://www.amazon.co.jp/gp/product/B000GPEXX4"; $file="cookies.txt"; $browser = LWP::UserAgent->new; $browser->cookie_jar({file =>$file, autosave=>1 }); $response = $browser->get($url); print $response->{_content}; exit;

    • ベストアンサー
    • CGI
  • utf8使用時のフォーム入力文字コード

    use utf8; binmode(STDIN,":encoding(shiftjis)"); をすると、入力時に内部変換がかかり、UTF-8として扱える という認識で使っていたのですが、下記のコードを実行してみると 入力した文字は普通に sjisで表示されます。 binmode(STDIN~ はどのような意味を持つのでしょうか。 http://www.lr.pi.titech.ac.jp/~abekawa/perl/perl_unicode.html http://www.hikoboshi.org/perl/doc/encode.html 他、いろいろなサイトで調べてみたのですが、いまひとつ 納得する回答を得ることができません。 //////////////////////////////////////////////////// use utf8; use open 'encoding(utf8)'; binmode(STDIN,":encoding(shiftjis)"); use CGI; print "content-type:text/html; charset=Shift_JIS \n\n"; print <<"EOM"; <form action="xxx.cgi"> <input type="text" name="hoe"> <input type="submit"> </form> ここは UTF-8文字列なので化ける<br> EOM $cgi = CGI->new; print $cgi->param('hoe'); //////////////////////////////////////////////////// 現在は下記のコードで自前で UTF-8に変換しています //////////////////////////////////////////////////// foreach( $cgi->param() ){ my $str = $cgi->param($_); $str = Encode::encode('utf-8', Encode::decode('shiftjis', $str)); $cgi->param( -name=>$_, -value=>$str ); }

    • ベストアンサー
    • Perl
  • ファイル出力をUTF8NではなくてUTF8で行いたい

    おせわになります。 Shift-JISで記述したPerlで、ファイル出力をしようとしています。 ------------------------------------ #!/usr/local/bin/perl use encoding 'shiftjis'; $hoge="ほげ" open(OUT,">file.txt") binmode OUT; print OUT $hoge; close(OUT); ------------------------------------ 希望はUTF8での出力なのですが、UTF8Nで出力されてしまいます。 どのようにすればいいのかご教授よろしくお願いします。

    • ベストアンサー
    • Perl
  • perl で 画像を取得したい

    下記perlのコードを書いたのですが、なぜか、画像を取得することができません。 メモ帳で開くと、画像データっぽい文字列はあるのですが、普通に見ることができません。 なぜでしょうか?また、どのように改良すれば取得できますか? ご存知の方教えていただけないでしょうか? 宜しくお願い致します。 $source = &GetImg('http://www.goo.ne.jp/img/logo/gootop_logo.gif'); $FileOut = "tmp.gif"; open(OUT, ">$FileOut"); print OUT $source; close (OUT); sub GetImg() { my($url) = @_; use LWP::UserAgent; my $browser = LWP::UserAgent->new; my $response = $browser->get($url,'User-Agent' => 'Mozilla/5.0 (Windows; U; Win98; en-US; rv:1.5) Gecko/20031007'); my $img_file = $response->content; return $img_file; }

    • ベストアンサー
    • Perl
  • PerlでRSS取得 ~ 文字化け ~ utf8→ShifJIS変換できない

    XML::RSSを使用してRSSのタイトルを取得するPerlスクリプトを作っています。 DBCSの場合、文字化けするので、以下のようにfrom_toを使用してutf8をShiftJISに変換しようとしましたが、エラーが出ます。 SBCSでは問題無いのですが。 Encode::Guessで調べるとutf8が返ってくるので、「from_to( $title, 'utf8','shiftjis' )」でutf8をShift-JISに変換すればよいのかと思ったのですが。 ■環境 ・perl v5.8.3 built for MSWin32-x86-multi-thread ・Windows2000(SP4) ■エラーメッセージ Cannot decode string with wide characters at c:/Perl/lib/Encode.pm line 184. ■ソース #!/usr/bin/perl BEGIN { use CGI::Carp qw(carpout fatalsToBrowser); carpout(STDOUT); } use Encode qw/ from_to /; use LWP::Simple 'get'; use XML::RSS ; print"Content-type: text/html\n\n"; print"<HTML>\n"; print"<HEAD><meta http-equiv=\"Content-Type\" content=\"text/html;charset=Shift-JIS\"></HEAD>\n"; print"<BODY>\n"; my $rss = new XML::RSS; eval {   # $rss->parse( get('http://slashdot.org/slashdot.rdf') );    $rss->parse( get('http://oshiete1.goo.ne.jp/rss/oshiete_goo.xml') ); }; exit if $@; foreach my $ref( @{$rss->{items}} ) {   $title = $ref->{'title'};   $link = $ref->{'link'};   from_to( $title, 'utf8','shiftjis' );   print"[title] $title<br>\n";   print"[link] <a href=\"$link\" target=\"_blank\">$link</a><br>\n";   ----------------------------<br><br>\n"; } print"</BODY></HTML>\n"; RSSの取得方法はここを参考にしました。 http://www.rfs.jp/sb/perl/10/rss01.html 宜しくお願いします。

    • ベストアンサー
    • Perl
  • [PERL-CGI] LWPを使った際リダイレクトされたか否かを知る方法について

    下記のように、任意のホームページを取得してそれを出力するプログラムがあるのですが、リダイレクトで引越しされたホームページにアクセスしても、特に問題なく表示されます。 できれば、リダイレクトされた場合であれば、次から本当のURLにアクセスしたいためそのホームページを記録したいのですが何か良い方法は無いでしょうか? ご存知の方、教えていただけ無いでしょうか? 宜しくお願い致します。 -CGI---------------------------------------------------- #!/usr/bin/perl print "Content-Type: text/plain\n\n"; $url = 'http://URLを入れる'; use LWP; use HTTP::Cookies; $file = "cookies.txt"; $browser = LWP::UserAgent->new; $browser->cookie_jar({file =>$file, autosave=>1 }); $response = $browser->get($url); print $response->{_content}; __END__ if(リダイレクトされたならば){ open (OUT,">>RedirectLog.txt"); print OUT $url."\n"; close(OUT); } -CGI----------------------------------------------------

    • ベストアンサー
    • CGI
  • web文書を取得するプログラムのサイト内での不具合について

    perl初心者です。 自分のwebサイトのコードを取得するプログラムをつくろう と思っているのですが、下のコード -------------------------------------------------------- #!/usr/local/bin/perl use LWP::UserAgent; use HTTP::Request; use HTTP::Response; our $URL = 'http://www.google.co.jp/'; # アクセスする URL my $proxy = new LWP::UserAgent; my $req = HTTP::Request->new('POST' => $URL); # HTTP リクエストを作成 my $res = $proxy->request($req); # $res に HTTP レスポンスが返ってくる print $res->content; # HTML を表示 1; --------------------------------------------------------------- でターゲットのurlが上のgoogleだと取得できるんですが 自サイトのurl'http://○○.××.△△.com/'だと 500 Internal Server Errorとなってしまいます。 因みにレンタルサーバーを利用しています。 サーバーでは技術的な質問は受け付けてないとの事なので、 スクリプトの質問とは少しズレますが分る方がいましたら ご教えていただきたく質問いたしました。