• ベストアンサー

SOCKETで入手したデータを抜き出したい

他サーバのHTMLから部分的に抜き出したいと思っています。 他サーバのHTMLを表示する所までは出来たのですが、抜き出す所が出来ずに困っています。 私が抜き出そうと、表示のwhile文内を下記に変えた所、何も表示されなくなりました。  if( $_ =~ m/抜き出したい頭のキーワード/ ){ $flag = 1;}  if( $_ =~ m/表示したい尾のキーワード/ ){ $flag = 0;}  if( $flag eq 1){ print $_;} このwhile文内には変数に代入するとどうもNGのようです。 教えてGooの過去ログにも同様の質問があったのですが、 解決に至っていませんでした。ご教示願います。 ↓現在のソースコード ---------------------------- #!/usr/local/bin/perl -w use strict; use Socket; # Socket モジュールを使う # 接続先ホスト名 my $host = 'www.xxxx.co.jp'; # HTTP プロトコルを使う my $port = getservbyname('http', 'tcp'); # ホスト名を、IP アドレスの構造体に変換 my $iaddr = inet_aton($host) or die "$host は存在しないホストです。\n"; # ポート番号と IP アドレスを構造体に変換 my $sock_addr = pack_sockaddr_in($port, $iaddr); # ソケット生成 socket(SOCKET, PF_INET, SOCK_STREAM, 0) or die "ソケットを生成できません。\n"; # 指定のホストの指定のポートに接続 connect(SOCKET, $sock_addr) or die "$host のポート $portに接続できません。\n"; # ファイルハンドル SOCKET をバッファリングしない select(SOCKET); $|=1; select(STDOUT); # WWW サーバに HTTP リクエストを送る print SOCKET "GET /index.html HTTP/1.0\r\n"; print SOCKET "\r\n"; # ヘッダ部分を受け取る while (<SOCKET>){ # 改行のみの行ならループを抜ける m/^\r\n$/ and last; } # ボディ部分を受け取り、表示 while (<SOCKET>){ print $_; }

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

  • ベストアンサー
  • guci-ok
  • ベストアンサー率33% (49/146)
回答No.2

そちらの事情も解らず、失礼しました。 > ソケットのwhile文内には変数宣言ですらNGになります。 > たとえば $i = "1"; NGとは、如何なる状況ですか? my $i = "1"; とmyを付けてもだめなのですか? > (ソケットを使わなければ何も問題なく処理できます。) もしかしてこれも、 use Socket; していないと大丈夫だが、この宣言があると動作がおかしい、 ということでしょうか? Socketを使ったプログラムは多少書いていますが、そうなったこと は経験有りません。他人の私が確認できるプログラム出せないで しょうか?

select_nao
質問者

お礼

連絡遅れて大変すいませんでした。 詳細な説明ありがとうございます。納得です、勉強になりました。 myが原因でした。初歩的な話で大変お恥ずかしいです

その他の回答 (3)

  • pipipi523
  • ベストアンサー率40% (148/365)
回答No.4

use strictを入れた場合、変数は使う前にmy や localで宣言する必要があります (use strictは変数の宣言を忘れたらエラーになるように入れる物なので) # ボディ部分を受け取り、表示 while (<SOCKET>){ my $flag=0; if( $_ =~ m/抜き出したい頭のキーワード/ ){ $flag = 1;} if( $_ =~ m/表示したい尾のキーワード/ ){ $flag = 0;} if( $flag eq 1){ print $_;} } と、してみてください

select_nao
質問者

お礼

連絡遅れて大変すいませんでした。 詳細な説明ありがとうございます。納得です、勉強になりました。

  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.3

だめなパターンのソースが見たいのですが、多分、$flagという変数の宣言位置が 悪いのではないかと思います。 #コンパイルエラーになるわけではないのですよね? とりあえずパターン決めうちでやってみましたが、こんなんで抜き出せました。 とりあえず最後の部分だけです。あとは一緒。 # ボディ部分を受け取り、表示 #my $flag = 0; while (<SOCKET>){ =begin #フラグ変数使用パターン if ( $_ =~ m/<table/ ){ $flag = 1;} if ( $_ =~ m{</table>}){ $flag = 0;} if ( $flag == 1){ print $_;} print $_; =cut my $f; print if (($f = /<table/ ... m{</table>}) && $f > 1 && $f !~ /E0$/); } フラグ変数なしでやってますが、使ってもできました。

select_nao
質問者

お礼

連絡遅れて大変すいませんでした。 詳細な説明ありがとうございます。納得です、勉強になりました。

  • guci-ok
  • ベストアンサー率33% (49/146)
回答No.1

キツい言い方ですが、問題を切り分ける力を養うことが肝要です。 ソケットでデータを受信することと、そのデータから希望のデータを抽出する こととは別の問題です。 ソケットで受信したデータに、特別な印が付いている訳では有りません。 ソケットを過剰に意識しすぎています。 ソケットでの処理に問題がないのなら、一旦そのデータをファイルに保存 するなりして、そのファイルを処理するプログラムでデバッグするなり、する と解決も早いでしょう。 さらに質問もシンプルなものになり、質問するほうも、解答するほうも 問題により集中することができます。 > if( $_ =~ m/抜き出したい頭のキーワード/ ){ $flag = 1;} > if( $_ =~ m/表示したい尾のキーワード/ ){ $flag = 0;} > if( $flag eq 1){ print $_;} 数字の比較は==です。 キーワードの所が正しい正規表現なのか、が問題かもしれません。 日本語を使う場合、日本語の正規表現が使えるケースなのか?

select_nao
質問者

補足

回答ありがとうございます。 基本的な話なのは重々承知です。ただ、正規表現や不等号の話ではありません。 ソケットのwhile文内には変数宣言ですらNGになります。 たとえば $i = "1"; 面倒なのは重々承知ですが、実際、スクリプトを動かしてみないとわからないかもしれません。 (ソケットを使わなければ何も問題なく処理できます。)

関連するQ&A