Perlで他サイトの情報を取得し一覧表示させる処理の高速化
Perl初心者です。よろしくお願いします。
同サーバ内にあるテキストデータをPerlで読みこみ、HTMLで一覧表示させるプログラムを見よう見真似で作成しました。リストのレコード数は10~30ほど。タイトルとボタンA~Eが配置されており、ボタンAはファイルA、ボタンBはファイルB…とリンクしています。
ファイルは同サーバ内にあり、ファイルの有無を調べてリンクするか、しないかを設定していましたが、この度、訳があってこのファイルが他サーバへ移動、さらにシステムから吐き出される仕組みになって、同じPDFファイルでも「xxxx.pdf」が「http://hoge.com/hoge.aspx?code=1234」のようにファイルの場所を特定することができなくなりました。
仕方なくファイルの有無を指定するHTMLを書き出すようにしてもらったのですが、それをget(url)で取得する方法に切り替えたとたん、一覧表示にするのに5~6秒かかるようになってしましました。
さらにこれが原因でアクセス過多でサーバに負荷がかかり、ページを表示できない要因にもなってしましました。
情報の取得方法や、負荷をかけない方法などご教授いただければ幸いです。
以下CGI抜粋
#!/usr/local/bin/perl
use LWP::Simple;
use Time::Local;
use LWP::UserAgent;
$file = @ARGV[0];
$data = $file;
$file .= ".txt";
print "Content-type: text/html\n\n";
print <<HTML;
<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.0 Transitional//EN'>
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html;CHARSET=x-sjis">
<META HTTP-EQUIV="Content-Script-Type" CONTENT="text/javascript" />
…
</HEAD>
<BODY style="margin : 0px; >
<TABLE BORDER="0" CELLSPACING="0" CELLPADDING="0">
HTML
open(IN, $file);
while(<IN>){
@in = split(/\t/);
$pdf = "https://www.hoge.com/filecheck/entFileCheck.aspx …[10]
$gPdf = get($pdf);
#ボタン配置の処理とか・・・
close(IN);
print "</BODY>\n";
print "</HTML>\n";
exit;
A 回答 (4件)
- 最新から表示
- 回答順に表示
No.1
- 回答日時:
を a タグを使ってリンクとして出せば?
説明不足でした。
リンク先ファイル、例えばAファイルならアドレスはhttp://www.hoge.com/link_a.aspx?=@in[10]
※@in[10]はループで各レコードからコード番号を拾っています。
このファイルが存在するときだけ、リンクするように、なければリンクなしで表示させています。
ファイルが同サーバーなら「-e」とかでその有無を調べられますが、できないのでファイルの有無をHTMLで書き出してもらっています。そのアドレスが例えばhttp://www.hoge.com/fcheck.aspx?=@in[10]で、ファイルAがあれば「fileA」、ファイルBがあれば「fileB」…と表示されます。
なので該当アドレスから表示データを取得して、検索。マッチすればボタンA~Eはリンク、無ければリンクなしとなります。
$url;
$gurl = get($url);
if ($gurl =~ /fileA/){#ファイルAにリンクする}
としているのですが、どうもこの処理がリスト表示を遅くさせているのではと考えています。
No.2
- 回答日時:
をループで取得するのが問題でしょうか。
get の前後で時間を計ることをお勧めします。
---
use Time::HiRes qw(gettimeofday);
use POSIX 'strftime';
my ( $sec, $usec ) = gettimeofday;
my $str = strftime( '%Y-%m-%d %H:%M:%S', localtime($sec) );
printf "%s.%03d\n", $str, $usec / 1000;
---
getを複数実行することがボトルネックなら、
複数のページ情報を一度に取得できるように交渉するしかないでしょうね。
例) 1から10,11のベージを取得する
https://www.hoge.com/filecheck/entFileCheck.aspx …
とか
ありがとうございます。
きっとそこに時間が取れれてるんだろうと、勝手な憶測で計測までしませんでしたが…
組み方が悪いのか?サーバで禁止してるのか?use Time::HiRes qw(gettimeofday); を設置するとエラー発生?なので、
$t1 = (times())[0];
#$gurl = get($url);
#$gurl2 = get($url2);
$t2 = (times())[0];
$t3 = $t2 - $t1;
で計測してみると、それぞれのレコードで「0.01~0.2」と出ます。しかし実感は全体の処理から表示まで5~6秒かかっています。同様にプログラムのはじめと終わりにタイマーセット。「0.5~0.6」と出ます。おかしいですよね。
プログラム全体の方をtime()に変えると10~12秒。実感に近いです。
1レコードのデータ取得時間が本当に「0.01~0.1」秒なら他に原因があることになりますが「$gurl = get($url); 」「$gurl2 = get($url2); 」を削除して実行しますと、あっという間に表示(0秒)されますので、やはりここに時間がかかってるのは間違いありません。
おっしゃるようにループで回すより、全レコード分吐き出してもらうのは時間、負荷ともに軽減できそうですね。これは相談してみますが、他に方法はないか。いまだに模索中。
よろしくおねがいします。
No.3
- 回答日時:
> 同様にプログラムのはじめと終わりにタイマーセット。
「0.5~0.6」と出ます。ループの先頭と最後という意味でしょうか。
> プログラム全体の方をtime()に変えると10~12秒。実感に近いです。
これはプログラムの先頭と最後という意味ですよね。
ちなみにループが終ってから次のループが始まるまでの時間という観点ではどうなりますか?
while () {
2)
....
1)
}
ループのおわり 1)から 次のループがはじまる 2)まで
お世話になります。
>ループの先頭と最後という意味でしょうか。
いえ、1レコード毎にget()の前後で計測した値です。その平均値が0.5~0.6。
>これはプログラムの先頭と最後という意味ですよね。
はい。
>ちなみにループが終ってから次のループが始まるまでの時間という観点ではどうなりますか?
これは、どんな理由があって計測するのか私のスキルでは理解できませんが、やってみました。
while(<IN>){
$tt2 = (times())[0];
$tt3 = $tt2 - $tt1;
処理
$tt1 = (times())[0];
}
close(IN);
1レコード目以外は「0」と出ました。
No.4
- 回答日時:
>>ちなみにループが終ってから次のループが始まるまでの時間という観点ではどうなりますか?
>これは、どんな理由があって計測するのか私のスキルでは理解できませんが、やってみました。
ちょっと考えすぎました。$gPdf がwhileループの最後に達したとき、オブジェクトが捨てられて遅くなるのかなと考えました。
get したあとの処理が遅いんですかね?
この回答への補足
ありがとうございます。
get()の前後で計測すると「0.01~0.05」。「0.5~0.6」ではありませんでした。しかし全体では10~12秒かかっています。get()の処理をはずすと「0秒」。get()に時間がとられているのは間違いないようです。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- CGI htmlからパラメータで、cgiに渡したい。 1 2023/02/06 16:15
- PHP PHPでCookieを使った訪問回数について 1 2023/05/28 14:10
- PHP if(preg_match("/[^0-9]/",$gu_d)){意味を教えてください。 1 2022/05/06 05:37
- PHP htmlspecialcharsが機能していないです。 バグですか? 1 2022/04/05 01:22
- PHP PHP MySql 画像を取得 1 2022/06/04 14:05
- CGI perlで書いたcgiでsqliteの使い方を教えてください 2 2023/05/08 21:29
- Excel(エクセル) PHPプログラムをエクセルに張り付けると検索ボックスがでてくる! 3 2022/05/08 07:10
- PHP ここでの ②if($su_d<>"")の比較演算子 を使う理由は 1 2022/03/26 02:33
- JavaScript 入力フォームの javascript で メールアドレスの正規チェックをを行い、ボタンをクリックして 2 2022/04/27 16:06
- HTML・CSS ボタンをクリックした時に、入力フォームのすぐ下部に、「入力欄が空白です」というテキストメッセージが表 1 2022/04/27 16:25
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
while(<ハンドラ>) {} で行数を...
-
AutoCADのスクリプト
-
オープンしたファイルで行の連結
-
cgiの投票回数制限設定について...
-
Perl で syntax error
-
perlで、文字列の中から何番目...
-
perlのflock関数でロックをかけ...
-
文字列をカウントする方法
-
ファイル全てを .xlsm に変更し...
-
一定時間が経過したフォルダの削除
-
csvファイルの横方向への改行に...
-
画像アップロード機能を追加し...
-
batファイルでrenameができませ...
-
while文がうまく動かない
-
VBAでCSVファイルの特定行を書...
-
MATLABのm-fileについて
-
配列のサイズを動的に拡張
-
ディレクトリのファイル作成を...
-
ANSI Cでファイル名、ディレク...
-
VB6.0でDB接続する際に切断時の...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
close()で例外が投げられる理由
-
perlのflock関数でロックをかけ...
-
改行コードが勝手に
-
巨大ファイルの行をを逆順に並...
-
オープンしたファイルで行の連結
-
Perl で syntax error
-
where can I buy snowbord in t...
-
open中のファイルをrename
-
perlを用いた特定文字列間の抽...
-
Perlで他サイトの情報を取得し...
-
die関数のエラー出力先について
-
ハッシュにファイルハンドル
-
サブスクリプトとのファイルハ...
-
テキストファイルの本文中に行...
-
perlで大容量CSVのsort方法につ...
-
フォルダが開かなくなりました。
-
AutoCADのスクリプト
-
ジョブショップスケジューリング
-
バッチファイルの作り方(CSV→...
-
awkスクリプトでダブルクォーテ...
おすすめ情報