• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:PerlのWeb::Scraperと正規表現について教えてください。)

PerlのWeb::Scraperと正規表現について教えてください。

このQ&Aのポイント
  • PerlのWeb::Scraperと正規表現について教えてください。具体的な質問内容や困っていることを記載してください。
  • 質問者はPerlのWeb::Scraperを使用して特定のウェブページからデータをスクレイピングしようとしています。現在のスクリプトでは、取得したデータをYAML形式で出力していますが、CSV形式で取り出したいとのことです。
  • 質問者はCSV形式で取り出すために正規表現を使用する必要があると考えており、試行錯誤していますが成功していません。正規表現に関する知識や具体的な試みについても述べています。指導をお願いしています。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.1

もうちょっと、シンプルに書けると思うけど、とりあえず #!/usr/bin/perl use warnings; use strict; use Encode; use URI; use Web::Scraper; my $uri_str = shift || 'http://table.yahoo.co.jp/t?s=9503.t&a=5&b=13&c=2009&d=8&e=14&f=2009%22%20%3B%22#6197153243450676860'; my $uri = new URI($uri_str) || die "$uri_str:$!"; my $scraper = scraper { process 'table tr[bgcolor="#ffffff"]', 'records[]' => scraper { process 'small', 'items[]' => 'TEXT'; }; }; my $res = $scraper->scrape($uri) || die "$!"; binmode STDOUT, ":encoding(shift-jis)"; foreach my $record ( @{ $res->{records} } ) { foreach my $item ( @{ $record->{items} } ) { $item =~ tr/,//d; print $item, ','; } print "\n"; }

sinzy0925
質問者

お礼

上記補足は誤りでした。 思ったとおりの結果が出ました。 ありがとうございます。 ロジックの中身について、追加で教えて欲しいのですが、 スクレイピングしたいURLの後ろ2009のあとの部分は どういう意味があるのでしょうか? ↓ 2009" ;"#6197153243450676860'; お時間のあるときでけっこうですので、よろしくお願いします。

sinzy0925
質問者

補足

忙しいところ、ありがとうございます。 早速試してみたのですが、以下のエラーが出ます。 どうすればよいでしょうか? ご指導お願いします。 エラー syntax error at bbb.pl line 10, near "my " Global symbol "$uri" requires explicit package name at bbb.pl line 10. Global symbol "$uri_str" requires explicit package name at bbb.pl line 10. Global symbol "$uri_str" requires explicit package name at bbb.pl line 10. Global symbol "$uri" requires explicit package name at bbb.pl line 18. Execution of bbb.pl aborted due to compilation errors.

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (1)

回答No.2

投稿されたコードのURIをマウスオーバすると、 リンク情報が http://....2009); と表示されて、コピベしたときに2009以降にゴミがついたのでしょう。それ でも開けてしまうのは、yahooがf=2009以降のクエリーをつかっていないから だと思われます。 なので、2009" ;"#6197153243450676860';の2009以降は意味がなくて、 正しいURIを指定すればOKということです。

sinzy0925
質問者

お礼

いろいろと教えてもらって、ありがとうございます。 非常に助かりました。 後は、ファイルの読み込みとか、書き込みとか自分で 勉強してみます。 ダメだったら、また質問させてもらいますので、 機会があれば、よろしくお願いします。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • Web::Scraperの使い方で

    PerllのWeb::Scraperを使って商品の情報を取得するみたいなことをしたいのですが、下のコードでなぜかブランドと製造販売元が取得することができません。 http://www.kenko.com/product/item/itm_6521067072.htmlのソースを見てみると、<div class="ltxt brand">にブランド情報が、<div class="ltxt">に製造販売元の情報が書かれています。それなので、process "div.ltxt", "maker" => "TEXT";とすれば製造販売元の情報(文字列)が取得されるはずなのですが、なぜかブランド情報(process "div.ltxt.brand", "brand" => "TEXT";として得られるはず?)が得られてます。これはなぜでしょうか? またこのスクリプトWeb::Scraperでは基本的にclass="***"のようにクラスの定義がされていないものについては情報を取得できないのでしょうか?例えば、同ページのソースコードにある<div>内容量:250ml</div>や<div itemprop="identifier" content="upc:4987222787413">JANコード: 4987222787413</div>から内容量とJANコードの情報を得ることはできないでしょうか? #!usr/bin/perl use strict; use warnings; use Encode; use Web::Scraper; use URI; use utf8; binmode STDOUT, ":encoding(shiftjis)"; #scraperオブジェクトを作成 my $shinkan = scraper{ #processメソッドで抽出する要素と展開方法を指定 process "div.mainBox","fil_list[]"=> scraper{ #scraperメソッドを渡して,"td.c-table01"要素をさらに展開する process "h1.fn", "goods" => "TEXT"; # 商品名 process "div.ltxt.brand", "brand" => "TEXT"; # ブランド process "div.ltxt", "maker" => "TEXT"; # メーカー process "span.price" => "price" => "TEXT"; # 価格 }; }; #scrapeメソッドでスクレイピングを実行 my $res = $shinkan->scrape(URI->new("http://www.kenko.com/product/item/itm_6521067072.html")); foreach my $dat(@{$res->{fil_list}}){ #undefの場合は、""を代入する。 unless(defined($dat->{goods})) {$dat->{goods} = ""}; unless(defined($dat->{brand})){$dat->{brand} = ""}; unless(defined($dat->{maker})) {$dat->{maker} = ""}; unless(defined($dat->{price})){$dat->{price} = ""}; print "goods = ", $dat->{goods}, "\n"; print "brand = ", $dat->{brand}, "\n"; print "maker = ", $dat->{maker}, "\n"; print "price = ", $dat->{price}, "\n"; };

    • ベストアンサー
    • Perl
  • Amazon サイトからhtmlを取得すると文字化

    すみません。素人です。 Amazon サイトからhtmlを取得すると文字化けしてしまいます。 方法ってないでしょうか? *************** use strict; use warnings; use Web::Scraper; use URI; use Encode qw/encode_utf8/; my $scraper = scraper { process('div', 'title' => 'TEXT'); }; my $url = URI->new('https://www.amazon.co.jp/s/ref=nb_sb_noss?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&url=search-alias%3Daps&field-keywords=test'); my $res = $scraper->scrape($url); print encode_utf8($res->{title}) . "\n"; ******************

    • ベストアンサー
    • Perl
  • WWW::Mixi::Scraper

    はじめまして。Perl初心者です。 このたび、WWW::Mixi::Scraperを使ってみようと思い、 http://search.cpan.org/~ishigaki/WWW-Mixi-Scraper-0.11/lib/WWW/Mixi/Scraper/Mech.pm の、 SYNOPSISに書いてあるソースを実行してみたのですが、 Use of uninitialized value in concatenation (.) or string at [パス]/WWW/Mixi/Scraper/Mech.pm line 18. logged in to mixi at [パス]/WWW/Mixi/Scraper/Mech.pm line 44. Undefined subroutine &WWW::Mixi::Scraper::Mech::_uri called at [パス]/WWW/Mixi/Scraper/Mech.pm line 72. と、エラーが出てしまいました。 ちなみに、foo@~のところとpasswordには自分のmixiにログインするパスを入れています。 他に追記が必要なのかとも思いましたがまったくわかりません…。 どなたかご教授いただければ幸いです。

  • Parallel::ForkManager(2)

    前回の投稿で完全に書き間違えた部分がありそのままではよくわからないものになってしまっていたのですが、投稿し直しなどができなかったので再度投稿させてもらいます。 プログラムは use Web::Scraper; use WWW::Mechanize::Firefox; use Parallel::ForkManager; use URI; binmode STDOUT,":utf8"; sub func ; ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(); $year += 1900 ; $mon += 1 ; $File = "yuma-$year:$mon:$mday:$hour.txt" ; open (file,"> $File") or die 'fail to open file\n'; print "HOW MUCH PAGE\n" ; my $page = <STDIN> ; print "WITEING...\n" ; my $MAX_PROCESSES = 5; my $pm = new Parallel::ForkManager($MAX_PROCESSES); for ($i = 1;$i <= $page;$i++) { $pm->start and next; my $uri = URI -> new ("www.目的とするURL$i.html"); my $mech = WWW::Mechanize::Firefox->new(); $mech->get($uri) ; print file $s->scrape($mech->content) ; print file "\n" ; print file $r->scrape($mech->content) ; print file "\n" ; $pm->finish; } print "WITEID\n" ; my $s = scraper { process 'font',sen => 'TEXT'; result 'sen'; }; my $r = scraper { process 'div#content',ren => 'TEXT'; result 'ren'; }; close (file) ; です。 $i の順序でファイルへ書き込みをしていきたいのですが、前の処理が終わっていなかった場合に待つ方法がわからないので初心者レベルで教えてください。

    • ベストアンサー
    • Perl
  • perlの正規表現

    はじめまして現在Perlでスクリプトを作成しています。 やりたいことは ・ユーザがコマンドラインより文字(ユーザID)を入力 ・その文字列が#getent passwdの結果にあるか無いかで処理を分ける です。 #getent passwd | grep hogehogeの結果は下記のとおりです。 hogehoge:x:1210:104:staff:/home/data/staff/hogehoge:/bin/bash これより先頭の[hogehoge]とユーザが入力したhogehogeが完全一致すれば問題ありません。 正規表現を調べましたが文字列での一致はあるのですが引数での文字列が調べることが出来ませんでした。 よろしくお願いします。 print "Enter User ID\n"; $id = <STDIN>; chomp($id); $cmd =`getent passwd | grep $id`; system($cmd); if ($cmd == ~ /^$id/) { print "There is not ID\n"; } else { print "Your ID is there\n"; }

  • YAMLについて

    perlの初心者の者です. 以下のようなサンプルソースを実行すると Can't locate auto/YAML/Syck/DumpYAML.al in @INC (@INC contains: C:/Perl/site/lib C:/Perl/lib .) at C:/Perl/site/lib/YAML/Syck.pm line 113 というエラーが出てしまってyaml.txtに当然実行結果が書き込まれていません.原因はなんでしょうか?cpanコマンド, ppmコマンドを用いてYAML::Syckをうまくインストールできなかったのでcpanサイトにいってtarボールを取ってきて解凍し, 適当な格納モジュールフォルダに格納しています. サンプルスクリプト #!/usr/bin/perl use YAML::Syck; $data = [ {data1=>10, data2=>20, data3=>30} ]; DumpFile("test.txt", $data); 出力結果はtest.txtは  data1: 10 data2: 20 data3: 30 になるはずなのですが.

    • ベストアンサー
    • Perl
  • 正規表現について2

    すみません、前回「正規表現について」でお世話になりました者です。 前回の分は解決したのですが、それに関連してもう少し教えてください。 data.txt---------------------------------------- aaabbbccc aaadddccc aaaeeeccc ------------------------------------------------ test.pl----------------------------------------- #!C:\Perl\bin\perl use CGI; my $q = CGI->new; $q->charset('Shift_JIS'); print $q->header(-type => "text/html"); my $line=0; open(IN,"<data.txt"); open(OUT,">output.txt"); while(<IN>){ if ($line++==0){ $output1="$1" if/aaa(.*?)ccc/;} s/aaa(.*)ccc/$1/ if (?aaa(.*)ccc?); print OUT; } close(OUT); close(IN); print $output1; ------------------------------------------------ とすることで、得られたい結果である、 output.txt-------------------------------------- bbb aaadddccc aaaeeeccc ------------------------------------------------ IEでの表示-------------------------------------- bbb ------------------------------------------------ となりました。そこで今回教えていただきたいのは、 data.txt---------------------------------------- <空行> aaabbbccc aaadddccc aaaeeeccc ------------------------------------------------ というようにdata.txtのはじめが空行の場合にも、 上記と同じような結果を得たいです。output.txtの はじめは空行になっても構いません。得られる文字として、上と同じ結果がほしいです。どうしたらよいでしょうか?よろしくお願いします。

    • ベストアンサー
    • Perl
  • perlの構文でわからない部分があるので教えて下さい。

    こんにちわ。パールの文で解らない部分があり困って居ります。$class->SUPER::new();ここの箇所なのですが、$classはどこから来たものなのかがわからなくて、メソッドの起動なのかとも思ったのですが、本も調べてみたのですがはっきりしません。お解りの方、どうか教えて下さい。よろしくお願いします。 package CGIBook::UserTracker; push @ISA,"HTML::Parser"; use strict; use URI; use HTML::Parser; 1; sub new{my($class,$path)=@_; my$id; if($ENV{PATH_INFO}and $ENV{PATH_INFO}=~ s|^/\.([a-z0-9_.-]*)/|/|i){$id=$1;} my$self=$class->SUPER::new(); $self->{user_id}=$id;$self->{base_path}=defined($path)?$path:""; return$self;}

    • ベストアンサー
    • Perl
  • DBIモジュールと Perl5.8

    Perl5.8のエンコードが理解できずに困っております。 MySQLでは、utf8の文字コードのデータがあります。 以下のスクリプトを実行させると、 Wide character in print at C:/usr/local/site/lib/DBI.pm line 1008. となります。 対処方法はあるのでしょうか? use utf8; use strict; use DBI; my $dbh = DBI->connect("dbi:mysql:dbname=test", "root", "", { AutoCommit=>1, PrintError=>1, RaiseError=>1} ); my $fname = "test.txt"; my $sth = $dbh->prepare("select id, namae from test order by id asc;"); $sth->execute(); # 出力ファイルを開く。 open FILE, ">" , $fname or die "Can't open $fname: $!"; # 整形された結果をファイルにダンプする。 my $rows = $sth->dump_results(80, "\n", ",", \*FILE); # 出力ファイルを閉じる。 close FILE or die "Error closing result file: $!\n"; $dbh->disconnect();

    • ベストアンサー
    • Perl
  • perlのDigest::MD5;でのMD5算出が異なる

    perlのDigest::MD5;でのMD5算出が異なる 下記、スクリプトをレンタルサーバ上と、WindowsOS上で走らせてみたところ、おなじファイルにも関わらず、MD5が異なります。 何故でしょうか? #!/usr/local/bin/perl use strict; use warnings; use Digest::MD5; my $file = 'test.zip'; my $ctx = Digest::MD5->new; open my $fh, "<$file"; $ctx->addfile($fh); my $md5 = $ctx->hexdigest; close($fh); open my $fh2, ">>md5.txt"; print $fh2 "$file $md5\n"; print "$file $md5\n"; close $fh2;

    • ベストアンサー
    • Perl