アプリ版:「スタンプのみでお礼する」機能のリリースについて

よろしくお願いします。
表題の通り、指定ファイルがあればそのサイトへのリンクをアクティブに、無ければリンクしないという表形式(といっても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();をはずせば、ぱっとすばやく表示されます。

表示時間を短縮する方法をご教授いただけないでしょうか?
よろしくお願いします。

A 回答 (2件)

外部のサーバーと通信をするので時間がかかるのは仕方がないかもしれません。



以前、同じような質問に回答したことがあるのですが、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{'};


他にもっといい方法があるかもしれないので、回答はオープンにしておいて
ください。(以前の方はすぐに締め切られまして焦りました(-。-;)
    • good
    • 0
この回答へのお礼

ryu_chanさんありがとうございます。

書いていただいたコードをそのままコピペ → 動作せず。

my $head = head($url)で何らかのアクションがということで、
そのままプリントしてみましたが、
HTTP::Response=HASH(0x834017c)など…HASH(さまざま)でファイルにアクセスできるかどうかの偏りは見られませんでした。

なおテストを続け、7つ配置しましたが、表示スピードもgetとそれほどかわらないように思います。

引き続きテスト続けます。

お礼日時:2009/11/07 18:40

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;
}
    • good
    • 0
この回答へのお礼

_--_1l1_1_さんありがとうございます。

あまりにも敷居が高すぎて、ちょっと解読できそうもありません。

書いていただいたコードを分解してテストしてみたいと思います。

お礼日時:2009/11/07 18:42

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!