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

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

新規登録して質問してみよう
ただいま回答率
85.48%
スクレイピング

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

Perl

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

XPath(XML Path)

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

プログラミング言語

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

Q&A

4回答

5409閲覧

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

dlrowolleh

総合スコア120

スクレイピング

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

Perl

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

XPath(XML Path)

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

プログラミング言語

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

0グッド

0クリップ

投稿2017/01/16 13:39

編集2017/01/17 07:39

###実現したいこと
オライリー・ジャパンから出版されている書籍の一覧を読み込み、木構造を作成するようなプログラムを作成しています。
オライリー・ジャパン発行書籍一覧
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

Perl

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

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

Perl

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

として

$ 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.

となったので

Perl

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

にして

$ 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/では
本のタイトル、値段等の情報は見られませんでしたが、
このプログラムは正しく動作するのでしょうか?

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

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ikedas

2017/01/17 07:55

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

回答4

0

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

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

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

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

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

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

投稿2017/01/17 09:59

ikedas

総合スコア4333

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

perl

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

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

投稿2017/10/01 03:47

KojiDoi

総合スコア13671

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

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

perl

1use LWP::Simple; 2use HTML::TreeBuilder; 3use utf8; 4use Encode; 5 6 7#$page = decode('utf-8', $page); 8

投稿2017/01/22 01:54

A.Ichi

総合スコア4070

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

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

投稿2017/01/17 08:41

koji9412

総合スコア158

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問