• 締切済み

ファイルの有無で条件分岐

よろしくお願いします。 表題の通り、指定ファイルがあればそのサイトへのリンクをアクティブに、無ければリンクしないという表形式(といっても1~15行ほど)のHTMLファイルを生成するCGIを作成しています。 問題なのはそのファイルは「hogehoge.txt」「hogehoge.pdf」などのファイル実態ではなく、 「http://www.hoge.jp/hoge.aspx?hogeID=1234」といったアドレスです。 (もちろんブラウザのアドレスバーに直接入力して、そのサイトが存在すれば正しく表示されます。) そのためなのか?「-f」「-e」などのファイルテスト演算子が使用できません。 よって、強引に use LWP::Simple; while(<IN>){ #テーブル作成_前処理 $hoge = get(http://www.hoge.jp/hoge.aspx?hogeID=1234); $hoge2 = get(http://www.hoge.jp/hoge.aspx?hogeID=3987); $hoge3 = get(http://www.hoge.jp/hoge.aspx?hogeID=9988); : if($hoge = 該当条件なら){リンクアクティブ処理} if($hoge2 = 該当条件なら){リンクアクティブ処理} if($hoge3 = 該当条件なら){リンクアクティブ処理} : #テーブル作成_後処理 close(IN); } などととして行ごとに指定ページを読み込み、その内容から条件分岐させているのですが、一行あたり7~8サイト分get();させているためなのか、表示にとても時間がかかって困っています。 表示されるまでの時間は5秒くらい。普通のテーブルを利用した表形式のサイトでこのget();をはずせば、ぱっとすばやく表示されます。 表示時間を短縮する方法をご教授いただけないでしょうか? よろしくお願いします。

みんなの回答

回答No.2

GET リクエストをシーケンシャルにやっているのが一番時間がかかってい ると思います。Coro なり POE なり AnyEnvent なり使うんでしょうが、 とりあえず use strict; use warnings; use LWP; use HTTP::Response; use HTTP::Request; my $url1 = 'http://www.google.co.jp/'; my $url2 = 'http://www.google.co.jp/dummy'; my $url3 = 'http://www.yahoo.co.jp/'; my ( $reader1, $pid1 ) = is_success_async($url1); my ( $reader2, $pid2 ) = is_success_async($url2); my ( $reader3, $pid3 ) = is_success_async($url3); # Wait the end of all child process waitpid $_, 0 for ( $pid1, $pid2, $pid3 ); print "$url1 success\n" if divide_status_string($reader1); print "$url2 success\n" if divide_status_string($reader2); print "$url3 success\n" if divide_status_string($reader3); sub divide_status_string { my $reader = shift; my $status = <$reader>; close $reader; chomp $status; return $status; } # Return file descripter and process ID sub is_success_async { my $url = shift; # create pipe pipe my $reader, my $writer; if ( my $pid = fork ) { # parent close $writer; return ( $reader, $pid ); } elsif ( defined $pid ) { # child close $reader; my $status = is_success($url); print $writer "$status\n"; exit 0; } } sub is_success { my $url = shift; my $timeout = shift || '5'; my $ua = LWP::UserAgent->new; $ua->agent('Mozilla'); $ua->timeout($timeout); my $req = HTTP::Request->new( GET => $url ); my $res = $ua->request($req); return $res->is_success; }

taka552101
質問者

お礼

_--_1l1_1_さんありがとうございます。 あまりにも敷居が高すぎて、ちょっと解読できそうもありません。 書いていただいたコードを分解してテストしてみたいと思います。

  • ryu_chan
  • ベストアンサー率37% (69/186)
回答No.1

外部のサーバーと通信をするので時間がかかるのは仕方がないかもしれません。 以前、同じような質問に回答したことがあるのですが、head情報のみを取得す れば多少は時間短縮になるかもしれません。 以下、その質問と回答です。 ファイルの存在確認をしたい - 教えて!goo http://oshiete1.goo.ne.jp/qa5381343.html ファイルの有無以外の情報もあるので、それをハッシュとして持ち、以下の ようにすると分かりやすいかもです。 use LWP; my %status_code = ( 200 => 'OK', 204 => 'No Response', 301 => 'Moved Permanently', 302 => 'Found', 303 => 'See Other', 307 => 'Temporary Redirect', 400 => 'Bad Request', 401 => 'Unauthorized', 403 => 'Forbidden', 404 => 'Not Found', 405 => 'Not Allowed', 408 => 'Request Timed Out', 500 => 'Internal Server Error', 503 => 'Service Unavailable', 504 => 'Gateway Timed Out', ); my $url = 'http://www.google.co.jp'; my $ua = LWP::UserAgent->new; my $head = $ua->head($url); print "Response is `", $status_code{$head->code}, q{'}; 他にもっといい方法があるかもしれないので、回答はオープンにしておいて ください。(以前の方はすぐに締め切られまして焦りました(-。-;)

taka552101
質問者

お礼

ryu_chanさんありがとうございます。 書いていただいたコードをそのままコピペ → 動作せず。 my $head = head($url)で何らかのアクションがということで、 そのままプリントしてみましたが、 HTTP::Response=HASH(0x834017c)など…HASH(さまざま)でファイルにアクセスできるかどうかの偏りは見られませんでした。 なおテストを続け、7つ配置しましたが、表示スピードもgetとそれほどかわらないように思います。 引き続きテスト続けます。

関連するQ&A