• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:LWPでHTML取得(その前にSocket取得)できない)

LWPでHTML取得できない理由と解決方法

このQ&Aのポイント
  • LWP::Simpleを使用してWebサイトのHTMLソースを取得できない問題が発生しています。
  • 環境Aでは取得できているが、環境Bでは取得できない状況です。
  • 原因としては、Socketの取得でundefが返却されており、ソケットが返されていない可能性があります。無線LANを使用しているかどうかが大きな差として存在します。

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

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

print $!; これも追加してやってみてください。 ソケットに対するシステムコールのエラーメッセージが入っているはずですが、何と表示されるでしょうか。

worao
質問者

補足

実行してみたところ、 Invalid argument というエラーが出ていました。 IO::Socket::INETのソースを追い、 やはり if ($sock->connect(pack_sockaddr_in($rport, $raddr))) { # ${*$sock}{'io_socket_timeout'} = $timeout; return $sock; } という部分でコケてるのかな、と思いました。 $rport,$raddr,$sock,$argの値を出してみました。結果は↓です。 $sock:IO::Socket::INET=GLOB(0x10260af8) $arg:HASH(0x10209ab4) $rport:80 $raddr:ヒョHa       ←文字化けです。 引き続き、宜しくお願い致します。

その他の回答 (6)

回答No.7

うーん、プログラムも変数の値も正常だと思います。 あと、考えられる原因はファイアウォールくらいしかないと思われますが・・・ お使いのファイアウォールソフトで、Perlからの外部接続がブロックされていたりしませんか? # 真っ先にファイアウォールを疑うべきだったかもしれません。

worao
質問者

お礼

原因はファイアウォールでした。 ログを見るとスクリプト実行端末から 端末外へポート138で接続しようとしているのを ブロックしているように見えました。 とりあえずファイアウォールをアンインストールして 動作確認できましたのでこれでCloseとさせて いただきたいと思います。 twinkleluzさんには本当にご迷惑おかけし、 また大変お世話になりました。 ありがとうございました!

worao
質問者

補足

なるほど。 確かに私の端末には問題児なアプリが入ってます。 ウィ○スセ○○リティが。 このアプリではperlの外部への接続は 制限解除してあるつもりなのですが、 自宅でもう一度確認してみます。 ありがとうございました。

回答No.5

下記のスクリプトですが、当方の環境では正常に動作しました。 my $content = get($url); の後に print $@; を加えて、どのようなメッセージが出るのか確認してみてください。 $@は、大概の場合、何らかのエラーが発生したときにエラー内容が入る変数です。

worao
質問者

お礼

ありがとうございます! そんなアプローチがあるんですね! 自宅に帰ったらやってみます。以上です。

worao
質問者

補足

print $@;をお教えいただいた通りに追加、実行してみました。 すると、 IO::Socket::INET: connect: timeout というメッセージが出ました。 timeoutと出ていますが、1秒もかからずにこれが出ています。 すみませんが、引き続き宜しくお願い致します。

回答No.4

あら、すみません。勘違いをしていたようです。 環境B内のマシンから環境A内のウェブサーバへLANでアクセスするのかと思っていました。 考えられる原因を一つ。 会社のほうではプロキシサーバを立てていらっしゃいますか。 スクリプトの中でプロキシを通してwebにアクセスする設定にしていると、当然自宅環境ではプロキシが存在しないのでアクセスが出来ません。 スクリプトのほうでプロキシの設定があるかどうかチェックしてみてください。 "proxy"で検索してみると分かります。 あと、接続時にどのようなエラーメッセージが出たかを明示してもらえると、もっと的確なアドバイスがしやすくなります。

worao
質問者

お礼

回答ありがとうございます。 会社では…おそらく立てているとは思いますが訊いてみなければいけませんが訊けません; 自分で作った凄く簡素なスクリプトなのです。 proxyという単語もございません。 困った事にエラーメッセージも出てくれずといった状況です。 LWP::Simple::get( )を使って サイトに接続し、ただHTMLソースを取得したいだけですのに。 参考にはならないと思いますが、スクリプト内容を晒していきます…。 <code> #! /usr/bin/perl use LWP::Simple; #文字コード変換 use Jcode; use Encode qw/from_to/; use Encode::Guess qw/euc-jp shiftjis 7bit-jis/; use constant CHAR_CODE => "shiftjis"; $output = "./output.txt"; if(!open (OUT, "+<$output" )){ print "cannot open file."; } @codes = (7212,7213); foreach $code (@codes){ my $url = "http://finance.livedoor.com/quote/format?c=" . $code; my $content = get($url); Jcode::convert( $content, CHAR_CODE); @temp = split(/\n/,$content); my $flg = 0; my $target; foreach my $line (@temp){ if($flg == 1){ $line =~ /<small>(.*)<\/small>/; $target = $1; last; } if ($line =~ /発行済株式数/){ $flg = 1; next; } } print "[$code]$target株\n"; print OUT "$code\t$target\n"; } close(OUT); exit(0);</code> それでは、宜しくお願い致します。

回答No.3

> A環境=会社 > B環境=自宅 > なのです。全く別のネットワークです。 > > すみませんが宜しくお願い致します。 異なるプライベートネットワークに192.168...から始まるプライベートアドレスで接続することはできません。 接続したければ、IPマスカレードを設定し、特定のポートとLAN内のマシンを対応付けてサーバを外部公開する必要があります。 セキュリティ的に大きな問題になることがあるので、IPマスカレードの設定に関しては質問者さんの会社のネットワーク管理担当者によく相談してください。

worao
質問者

お礼

丁寧なご回答、まことに有難う御座います。 接続したい先(取得したいHTML)は LAN内のページではなくyahooなどの 一般的なWebサイトなのですが、 本問題解決の為にはご回答にあるような手順が必要なのでしょうか。 以上、よろしくお願い致します。

回答No.2

> 環境AとBは接続しているルータは、 > 違います。 AとBは同じプライベートネットワークに入っているでしょうか。 プライベートネットワークの範囲が違えば同一アドレスでも違うサーバにアクセスすることになります。 一度、BをAと同じルータに*有線で*つなぎ、ネットワークの疎通とプログラムの挙動を確かめてみてください。 これで正常に動作すれば、BがAとは違うプライベートネットワークに接続している、ということになります。 質問の文面から類推できそうな原因は、これくらいだと思いますが。。。

worao
質問者

お礼

ご回答ありがとうございます。 > AとBは同じプライベートネットワークに入っているでしょうか。 入っておりません。 A環境=会社 B環境=自宅 なのです。全く別のネットワークです。 すみませんが宜しくお願い致します。

回答No.1

とりあえず、pingなりを使って環境Bからネットワークの疎通ができているか確認しましょう。 pingで192.168.xx.yyや192.168.xx.zzにつながらなければ、perl以前にLANの問題です。 環境Aと環境Bで接続しているルータが違う、なんてことはないですよね?

worao
質問者

お礼

ご回答有難う御座います。 ping実験はしてあります。 yyにもzzにも通っております。 (伝え漏れ、すみません) 環境AとBは接続しているルータは、 違います。 宜しくお願い致します。