重要なお知らせ

「教えて! goo」は2025年9月17日(水)をもちまして、サービスを終了いたします。詳細はこちら>

電子書籍の厳選無料作品が豊富!

初めて投稿させていただきます。
宜しくお願い致します。

LWP::Simpleなどを使ってWebサイトのHTMLソースを
取得したいのですが、できません。
同じplファイルを使って環境Aでは取得できているのですが、
環境Bでは出来ません。
LWPのバージョンは5.805で、両環境とも同じです。

どこでエラー?が起こっているかSimple.pmから
ソースを追って見たところ、
LWP::Simple::_trivial_http_get( )のSocketを取得する所で
undefが返却されているようです。
さらに追っていくと、
IO::Socket::INET::new( )
→IO::Socket::new( )
→IO::Socket::INET::configure( )
最終的にここまで来ました。
configure( )の、
---------------------------------------------
if ($sock->connect(pack_sockaddr_in($rport, $raddr))) {
# ${*$sock}{'io_socket_timeout'} = $timeout;
return $sock;
}
---------------------------------------------
ここまで来て、上記のifブロックに入らず、timeoutかよくわかりませんが、
とにかくソケットを返していないようなのです。
その原因を、お教え頂きたいのです。

環境AとBで違う所は、大きな差としては、
無線LANを使ってない(A)か、使ってるか(B)しか無いです…。

また、環境Bで試した点としては、
・無線LANルータに対して
get('http://192.168.xx.yy');のようにした事と →結果、だめ
・apache tomcatが立ち上がっているローカルホストに
get('http://192.168.xx.zz:8080');のようにした事 →結果、だめ
です。

長々と状況説明してすみませんが、ご回答お待ちしております。
以上です。

A 回答 (7件)

print $!;



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

この回答への補足

実行してみたところ、
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       ←文字化けです。

引き続き、宜しくお願い致します。

補足日時:2006/03/09 23:42
    • good
    • 0

うーん、プログラムも変数の値も正常だと思います。


あと、考えられる原因はファイアウォールくらいしかないと思われますが・・・

お使いのファイアウォールソフトで、Perlからの外部接続がブロックされていたりしませんか?

# 真っ先にファイアウォールを疑うべきだったかもしれません。

この回答への補足

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

補足日時:2006/03/10 11:20
    • good
    • 0
この回答へのお礼

原因はファイアウォールでした。
ログを見るとスクリプト実行端末から
端末外へポート138で接続しようとしているのを
ブロックしているように見えました。

とりあえずファイアウォールをアンインストールして
動作確認できましたのでこれでCloseとさせて
いただきたいと思います。

twinkleluzさんには本当にご迷惑おかけし、
また大変お世話になりました。
ありがとうございました!

お礼日時:2006/03/11 15:18

下記のスクリプトですが、当方の環境では正常に動作しました。



my $content = get($url);
の後に
print $@;
を加えて、どのようなメッセージが出るのか確認してみてください。
$@は、大概の場合、何らかのエラーが発生したときにエラー内容が入る変数です。

この回答への補足

print $@;をお教えいただいた通りに追加、実行してみました。
すると、
IO::Socket::INET: connect: timeout
というメッセージが出ました。

timeoutと出ていますが、1秒もかからずにこれが出ています。

すみませんが、引き続き宜しくお願い致します。

補足日時:2006/03/08 22:29
    • good
    • 0
この回答へのお礼

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

お礼日時:2006/03/08 13:45

あら、すみません。

勘違いをしていたようです。
環境B内のマシンから環境A内のウェブサーバへLANでアクセスするのかと思っていました。

考えられる原因を一つ。
会社のほうではプロキシサーバを立てていらっしゃいますか。
スクリプトの中でプロキシを通してwebにアクセスする設定にしていると、当然自宅環境ではプロキシが存在しないのでアクセスが出来ません。
スクリプトのほうでプロキシの設定があるかどうかチェックしてみてください。
"proxy"で検索してみると分かります。

あと、接続時にどのようなエラーメッセージが出たかを明示してもらえると、もっと的確なアドバイスがしやすくなります。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。

会社では…おそらく立てているとは思いますが訊いてみなければいけませんが訊けません;

自分で作った凄く簡素なスクリプトなのです。
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>

それでは、宜しくお願い致します。

お礼日時:2006/03/07 23:24

> A環境=会社


> B環境=自宅
> なのです。全く別のネットワークです。
>
> すみませんが宜しくお願い致します。

異なるプライベートネットワークに192.168...から始まるプライベートアドレスで接続することはできません。
接続したければ、IPマスカレードを設定し、特定のポートとLAN内のマシンを対応付けてサーバを外部公開する必要があります。

セキュリティ的に大きな問題になることがあるので、IPマスカレードの設定に関しては質問者さんの会社のネットワーク管理担当者によく相談してください。
    • good
    • 0
この回答へのお礼

丁寧なご回答、まことに有難う御座います。

接続したい先(取得したいHTML)は
LAN内のページではなくyahooなどの
一般的なWebサイトなのですが、
本問題解決の為にはご回答にあるような手順が必要なのでしょうか。

以上、よろしくお願い致します。

お礼日時:2006/03/07 13:44

> 環境AとBは接続しているルータは、


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

質問の文面から類推できそうな原因は、これくらいだと思いますが。。。
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。

> AとBは同じプライベートネットワークに入っているでしょうか。

入っておりません。
A環境=会社
B環境=自宅
なのです。全く別のネットワークです。

すみませんが宜しくお願い致します。

お礼日時:2006/03/06 14:50

とりあえず、pingなりを使って環境Bからネットワークの疎通ができているか確認しましょう。


pingで192.168.xx.yyや192.168.xx.zzにつながらなければ、perl以前にLANの問題です。

環境Aと環境Bで接続しているルータが違う、なんてことはないですよね?
    • good
    • 0
この回答へのお礼

ご回答有難う御座います。

ping実験はしてあります。
yyにもzzにも通っております。
(伝え漏れ、すみません)

環境AとBは接続しているルータは、
違います。

宜しくお願い致します。

お礼日時:2006/03/06 10:48

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