質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.53%

  • プログラミング言語

    741questions

    プログラミング言語はパソコン上で実行することができるソースコードを記述する為に扱う言語の総称です。

  • Perl

    492questions

    Perlは多目的に使用される実用性が高い動的プログラミング言語のひとつです。

  • スクレイピング

    448questions

    スクレイピングとは、公開されているWebサイトからページ内の情報を抽出する技術です。

  • XPath(XML Path)

    90questions

    XML Path Language (XPath; XMLパス言語)は、マークアップ言語 XML に準拠した文書の特定の部分を指定する言語構文の事をいいます。XPathはXMLとは別の構文を使用します。XMLドキュメントの抽象、論理ストラクチャ上で動作します。

Perl 明示的なパッケージ名が必要とはどういう意味でしょうか

受付中

回答 4

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 969

dlrowolleh

score 112

実現したいこと

オライリー・ジャパンから出版されている書籍の一覧を読み込み、木構造を作成するようなプログラムを作成しています。
オライリー・ジャパン発行書籍一覧
HTML::TreeBuilderを用い、実行しようとした際に以下のエラーメッセージが発生しました。

発生している問題・エラーメッセージ

$ perl oreilly_catalog.pl 

と実行すると

Cannot decode string with wide characters at /usr/lib/perl/5.18/Encode.pm line 176.

と表示されます。

該当のソースコード

oreilly_catalog.pl 

  1 #!/usr/bin/perl -w
    2 use strict;
    3 use LWP::Simple;
    4 use HTML::TreeBuilder;
    5 use Encode;
    6 #use encoding 'utf-8';# 使用しているプラットフォームにあわせてください。
    7 #binmode(STDERR, ':raw :encoding(utf-8)');# 同上
    8 use utf8;
    9 binmode(STDOUT, ':utf8');
   10 binmode(STDERR, ':utf8');
   11 
   12 my $url = 'http://www.oreilly.co.jp/catalog/';
   13 my $page = get( $url ) or die $!;
   14 $page = decode('utf-8', $page);
   15 my $p = HTML::TreeBuilder->new_from_content( $page );
   16 
   17 my @links = $p->look_down(
   18 _tag => 'a',
   19 href => qr{^ \Qhttp://www.oreilly.co.jp/BOOK/\E \w+ / $}x
   20 );
   21 
   22 my @rows = map { $_->parent->parent } @links;
   23 
   24 my @books;
   25 for my $row (@rows) {
   26 my %book;
   27 my @cells = $row->look_down( _tag => 'td' );
   28 next if ($#cells != 2);
   29 $book{isbn}= $cells[0]->as_trimmed_text;
   30 $book{title}= decode('utf8', $cells[1]->as_trimmed_text);
   31 $book{price}= $cells[2]->as_trimmed_text;
   32 $book{price}=~ s/^\\//;
   33 $book{price}=~ s/,//g;
   34 
   35 $book{url}= get_url( $cells[1] );
   36 push @books, \%book;
   37 }
   38 
   39 sub get_url {
   40 my $node = shift;
   41 my @hrefs = $node->look_down( _tag => 'a');
   42 return unless @hrefs;
   43 my $url = $hrefs[0]->attr('href');
   44 $url =~ s/\s+$//;
   45 return $url;
   46 }
   47 
   48 $p = $p->delete; # $pはもう要らない
   49 
   50 {
   51 my $count = 1;
   52 my @perlbooks = sort { $a->{price} <=> $b->{price} }
   53   grep { $_->{title} =~ /perl/i } @books;
   54 print $count++, "\t", $_->{price}, "\t", $_->{title},"\n" for @perlbooks;
   55 }
   56 
   57 {
   58 my @perlbooks = grep { $_->{title} =~ /perl/i } @books;
   59 my @javabooks = grep { $_->{title} =~ /java/i } @books;
   60 my $diff = @javabooks - @perlbooks;
   61 print "Perl本は" . @perlbooks . "冊あり、Java本は" . @javabooks .
   62   "冊あります。 Perl本よりもJava本の方が" . $diff . "冊多いです。\n";
   63 }
   64 
   65 
   66 
   67 for my $book ( @books ) {
   68 next unless $book->{title} =~ /Google Hacks/; # Google Hacksのみ処理する。
   69 my $url = $book->{url};
   70 my $page = get( $url );
   71 $page = decode('utf-8', $page);
   72 my $tree = HTML::TreeBuilder->new_from_content( $page );
   73 my ($pubinfo) = $tree->look_down( _tag => 'b' );# タイトルの<b>タグを検索する。
   74 $pubinfo = $pubinfo->parent->parent; # 書籍情報の取得
   75 my $info = decode('utf8', $pubinfo->as_trimmed_text);
   76 my ($pages) = $info =~ /(\d+)ページ/;
   77 my ($original) = $info =~ /原書:(.+)$/;
   78 my ($date) = $info =~ /(\d+年\d+月)発行/;
   79 
   80 print "\nページ数:$pages\n原書タイトル:$original\n発行年月:$date\n";
   81 
   82 my ($dummy, $img_node) = $tree->look_down( _tag => 'img' );
   83 my $img_url = $url . $img_node->attr('src');
   84 my $cover = get( $img_url );
   85 # ここで$coverをファイルに保存します。
   86 open(OFH, ">cover.gif");
   87 binmode(OFH);
   88 print OFH $cover;
   89 close(OFH);
   90 $tree = $tree->delete;
   91 }

試したこと

Cannot decode string with wide characters の直し方 – 放置演算子
を参考に、

〜〜省略〜〜
    9 binmode(STDOUT, ':utf8');
   10 binmode(STDERR, ':utf8');
   11 $string = Encode::_utf8_off($string);
〜〜省略〜〜


として

$ perl oreilly_catalog.pl 

と実行すると

Global symbol "$string" requires explicit package name at oreilly_catalog.pl line 11.
Global symbol "$string" requires explicit package name at oreilly_catalog.pl line 11.
Execution of oreilly_catalog.pl aborted due to compilation errors.

となったので

〜〜省略〜〜
    9 binmode(STDOUT, ':utf8');
   10 binmode(STDERR, ':utf8');
   11 my $string = Encode::_utf8_off($string);
〜〜省略〜〜


にして

$ perl oreilly_catalog.pl 

と実行すると

Global symbol "$string" requires explicit package name at oreilly_catalog.pl line 11.
Execution of oreilly_catalog.pl aborted due to compilation errors.

となりました。
翻訳すると

明示的なパッケージ名が必要

とのことだそうですが、具体的にどうすればいいのか分かりません。

補足情報(言語/FW/ツール等のバージョンなど)

$ perl -v

とすると

This is perl 5, version 18, subversion 2 (v5.18.2) built for x86_64-linux-gnu-thread-multi
(with 44 registered patches, see perl -V for more detail)
Copyright 1987-2013, Larry Wall
Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5 source kit.
Complete documentation for Perl, including FAQ lists, should be found on
this system using "man perl" or "perldoc perl".  If you have access to the
Internet, point your browser at http://www.perl.org/, the Perl Home Page.

です。

余談

Ctrl+Uでサイトを見た結果
view-source:http://www.oreilly.co.jp/catalog/では
本のタイトル、値段等の情報は見られませんでしたが、
このプログラムは正しく動作するのでしょうか?

何卒よろしくお願いします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • ikedas

    2017/01/17 16:55

    oreilly_catalog.plはご自分で「作成」しているのですか? 元のスクリプトの出所 (URL) を明記してください。

    キャンセル

  • dlrowolleh

    2017/01/17 17:05

    失礼しました。書籍のサンプルコードをダウンロードしたものです。https://www.oreilly.co.jp/books/4873111870/ また、http://maruzou.sakura.ne.jp/spiderhks/hack019/oreilly_catalog.plと同じコードのようです。何かとよろしくお願いします。

    キャンセル

回答 4

+1

Global symbol "$string" requires explicit package name at oreilly_catalog.pl line 11. 

「$stringなどという変数を使うとは聞いていない」と言われています。

他人の説明を意味もわからずコピペしても、プログラミングの勉強にはなりません。もちろん、プログラムを正しく動作させることができるようにもなりません。

また、コンピュータ関係の書籍で、10年以上も前のものは役に立たないと思ったほうがいいでしょう (初版が古くても、近年に改訂版が出ているというのなら問題ないですが)。

以上をまとめると、つぎのことをお勧めします。

オライリー・ジャパン発行書籍一覧」のページで、「Filter」の欄に「Perl」と入力して、出てくる本を読んでいくといいでしょう。まずは『初めてのPerl 第6版』から。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

perlの内部コードをUTF8として、decodeをコメントアウトするとよいのでは。

use LWP::Simple;
use HTML::TreeBuilder;
use utf8;
use Encode;


#$page = decode('utf-8', $page);

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

my $string = Encode::_utf8_off($string);

この時点では定義されていない$stringを右辺で使おうとしているので、そんな変数は知らんとなっています。そもそも、utf変換をしようとしているということは、それ以前のどこかで$stringに値を代入しようとしているはず。その時点で必要な手当てをせず、ここで表面上つじつまを合わせようとしてもダメです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

-1

こちらが足らない可能性はありますか?
language-pack-ja-base

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

同じタグがついた質問を見る

  • プログラミング言語

    741questions

    プログラミング言語はパソコン上で実行することができるソースコードを記述する為に扱う言語の総称です。

  • Perl

    492questions

    Perlは多目的に使用される実用性が高い動的プログラミング言語のひとつです。

  • スクレイピング

    448questions

    スクレイピングとは、公開されているWebサイトからページ内の情報を抽出する技術です。

  • XPath(XML Path)

    90questions

    XML Path Language (XPath; XMLパス言語)は、マークアップ言語 XML に準拠した文書の特定の部分を指定する言語構文の事をいいます。XPathはXMLとは別の構文を使用します。XMLドキュメントの抽象、論理ストラクチャ上で動作します。