• 締切済み

socketを使用したスクリプトがうまく動きません

お世話になります。教えて!gooを初めて利用する者です。 Perlは本などを見ながら何とか動かせるレベルです。 この度、socketを使って他サイトを読み込む実験をしてみたところ、以下のコードでGoogleのトップページは読み込めましたがYahoo!のトップは何度やってもちゃんと読み込めません。 失敗している部分は、相対パス指定になっている部分のようです。 リンクや画像など、「http://www.yahoo.co.jp/~」となるはずのところが、「http://127.0.0.1/~」となってしまっています。 また、LWPモジュールというものも試してみましたが、こちらはGoogleのトップの読み込みも失敗しました。症状は上と同じです。 コードは本や有名サイトからそのまま引用してもダメで、多少いじってもやはりダメでした。 一人で解決するのは限界だと思いましたので、分かる方いらっしゃいましたらご助言をお願いいたします。 (試したコードの例↓) use Socket; $addr = (gethostbyname("www.google.co.jp"))[4]; $name = pack("S n a4 x8", 2, 80, $addr); socket(S, PF_INET, SOCK_STREAM, 0) || die "socket"; connect(S, $name) || die "connect"; binmode(S); select(S); $| = 1; select(STDOUT); print S "GET / HTTP/1.0\r\n\r\n"; while (<S>) { print; } close(S);

みんなの回答

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.5

>ブラウザで閲覧するのに、そんなふうにする必要があるのでしょうか? ブラウザで閲覧する場合と、スクリプトでページや画像を取り込んだ時とごっちゃになっていると思います。 基本的に、勘違いなされていると思います。 自分のホームページに自分が作ったページをアップする場合と、 自分のホームページで動かすスクリプトが他のサイトから持ってきたページが同じディレクトリにあるとしましょう。 他のサイトから持ってきたページというのは、自分が作成してアップしたのと基本的に同じ(区別はつかない)ですよね。 そうしたときに、リンクなどの指定はどうなっているべきか? ということをちょっと考えてみるとよいのではないでしょうか? >もう一度別の場所でも聞いてみて宜しいでしょうか? もちろん私に聞いてみるまでもなくかまいません。 お役に立てなくて申し訳ありません。

oshietechan123
質問者

お礼

サイトを丸ごと取り込むようなスクリプトの場合はディレクトリ構造も再現する必要があるのでしょうが、今問題になっているような処理でそれが必要となると、アクセスする度にサーバー側(http://127.0.0.1/以下)にファイルやフォルダがどんどん溜まっていくことになって、やっぱりおかしいのではないかと思いますが……一人で考えてもそれ以上はよく分かりませんでした。 他の場所で聞いてみることにします。 長々とお世話になり、どうもありがとうございました。

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.4

>それをどこに保存すればいいのかという問題が出てくると思うんですが…。 オリジナルのリンクが相対参照で書かれていれば、 それに合わせてやる必要があります。 例えば src="image/img01.jpg" とかなっていれば、 カレントディレクトリのimageフォルダの中に入れてやる必要があります。 >インターネット上のファイル閲覧って、ベースになるURLを与えてやれば、あとはブラウザが自動的にソースを解析してくれて画像やスタイルシート等も読み込まれてくるのではないのでしょうか? それは、その通りです しかし、 相対パス指定になっているリンクや画像を 自サーバーにダウンロードした状態で、元のサーバーパスhttp://www.yahoo.co.jp/ が、補われたりはしません、 相対パスにはそのような情報はないからです。 相対パスで指定してあるので、デフォルトのサーバーパスがhttp://127.0.0.1/ ~ のように補われます。 これはある意味当然だと思いますけど・・ (自サーバーの相対パスで指定した画像が全然別のサーバーパスになってたらおかしいでしょ?)

oshietechan123
質問者

補足

> カレントディレクトリのimageフォルダの中に入れてやる必要があります。 ブラウザで閲覧するのに、そんなふうにする必要があるのでしょうか? 普通にキャッシュフォルダに入るだけかと思っていましたが…。 > 相対パスにはそのような情報はないからです。 LWPモジュールを使った場合ですけど、私の方でも調べてみると、HTTPレスポンスヘッダ内にそのような情報があるようだと分かりました。(Content-Locationとか、Content-Baseとかそのあたり) これがHTMLの<base>タグのように基準のURLとして使われるのかなと思い、Content-Typeと一緒に渡してみたりしたんですけど、実際には何も変わりませんでした。 …というわけで、もうお手上げです。 やっぱり私のところの環境がおかしいのかもしれません。 そろそろ質問してから1週間経ちますので、もう一度別の場所でも聞いてみて宜しいでしょうか? この度はご迷惑をおかけしましてどうもすみませんでした。

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.3

>LWPモジュールを使用する場合も他のファイルを一つずつ読み込まないといけないんでしょうか? 基本的に1つずつGETしなければダメだと思いますが、もしかしたら丸ごとダウンロードできるような指定があるんですかね? 聞いたところによると、w3mir というのがあるらしいです。 http://search.cpan.org/~janl/w3mir-1.0.10/w3mir.PL >リンクのところが「http://127.0.0.1/~」となってしまう原因は何なんでしょうか? ローカルにダウンロードしたHTMLファイルを起動して相対参照になっている画像ファイルをローカルサーバーのリンクアドレスに展開しているというようなかんじなんじゃないかと思います。

oshietechan123
質問者

補足

w3mirっていうのはちょっと違うみたいです。 私はブラウザで普通に表示できないので困っています。 まず目的のHTMLファイルをGETして、それを解析して画像などを1つずつ読み込んだとしても、それをどこに保存すればいいのかという問題が出てくると思うんですが…。 やっぱり「http://127.0.0.1/~」となっている限り、画像等は読み込まれないような気がします。 インターネット上のファイル閲覧って、ベースになるURLを与えてやれば、あとはブラウザが自動的にソースを解析してくれて画像やスタイルシート等も読み込まれてくるのではないのでしょうか?

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.2

>> それぞれの、画像などの部分は、別に読み込まないといけないです >これは具体的にはどうやるのでしょうか? >ブラウザが自動的にやってくれるのとは違うんですか? ソケットを使って要求しているファイルは、 >print S "GET / HTTP/1.0\r\n\r\n"; で、トップページだけです。 他のファイルが要るなら、そのファイルを要求しなくちゃいけません。 読み込んだトップページを解析して、リンクから必要なファイルを分析して更に要求しなくちゃいけません。 ブラウザはそれ(アドレスで指定したトップページの内容となる画像などのダウンロードとか)を(影で)やっています。

oshietechan123
質問者

補足

そうなんですか…。ちょっと難しそうです。 LWPモジュールを使用する場合も他のファイルを一つずつ読み込まないといけないんでしょうか? 手元の本にはLWPモジュールを使えば簡単にHTTPアクセスできるというようなことが書いてあるので、socketは諦めてそっちを使おうかとも思います。 それにしても、リンクのところが「http://127.0.0.1/~」となってしまう原因は何なんでしょうか?

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.1

試してみましたが、むしろ、​"www.google.co.jp" が、別のリンクに転送されるので、失敗し、Yahoo! は、そのままでうまくいく。 と思うのですが。。 LWP は、転送(?)を処理してくれるので逆にうまくいく。 >失敗している部分は、相対パス指定になっている部分のようです。 それぞれの、画像などの部分は、別に読み込まないといけないですけど、(ソケットで要求しているのはトップページだけなので)そういうことじゃないですか?

oshietechan123
質問者

補足

ご回答ありがとうございます。 成功するのと失敗するのが逆になっているとは…環境のせいなんでしょうか…。 > それぞれの、画像などの部分は、別に読み込まないといけないですけど これは具体的にはどうやるのでしょうか? ブラウザが自動的にやってくれるのとは違うんですか?

関連するQ&A