CGIについて質問です。

下記のようなプログラムでgoogleの検索結果を$htmldataに格納していました。

$domain = 'www.google.co.jp';
$word = 'キーワード';
$file = '/search?q='.$word.'&ie=UTF-8&oe=UTF-8&hl=ja&start=0&num=20';
$handle = 'S';
$addr = (gethostbyname("$domain"))[4];
$name = pack("S n a4 x8", 2, 80, $addr);
socket($handle, 2, 1, 0);
connect($handle, $name);
binmode($handle);
select($handle); $| = 1; select(stdout);
print S "GET $file HTTP/1.0\r\n\r\n";
while (<$handle>) {
$htmldata .= $_;
}
close($handle);

検索結果の画面のソースが取得出来ていたのですが、数日前から下記のようなメッセージに変わってしまいました。

302 Moved
The document has movedhere.HTTP/1.0 302 FoundLocation: http://www.google.co.jp/search?q=・・・・・・・・・・

解決方法が分かりましたら、ご教授頂ければ幸いです。
よろしくお願い致します。

回答の条件
  • 1人1回まで
  • 登録:
  • 終了:2014/12/11 01:03:42
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:gizmo5 No.2

回答回数504ベストアンサー獲得回数141

ポイント120pt

www.google.co.jp に対して、以下のコマンドを発行すると 302 のステータスで返ってきます。

GET /search?q=キーワード&ie=UTF-8&oe=UTF-8&hl=ja&start=0&num=20 HTTP/1.0

ヘッダの先頭付近は以下のようになっています。

HTTP/1.0 302 Found
Location: http://www.google.co.jp/search?q=%3F%3F%3F%3F%3F%3F%3F%3F%3F%3F&ie=UTF-8&oe=UTF-8&hl=ja&start=0&num=20&gws_rd=cr&ei=JNOBVJzzDMrc8AX4wIDIBQ

302 は Rewrite の指定になります。
http://ja.wikipedia.org/wiki/HTTP%E3%82%B9%E3%83%86%E3%83%BC%E3%82%BF%E3%82%B9%E3%82%B3%E3%83%BC%E3%83%89

Location ヘッダーで移動すべき URL が指定されているので、そちらの URL に対してもう一度 HTTP のリクエストを投げてレスポンスを取得してください。

id:uwao

有り難うございました。
リダイレクトのURLでアクセスする事にしました。

2014/12/11 01:02:55

その他の回答1件)

id:JULY No.1

回答回数966ベストアンサー獲得回数247

ポイント80pt

えーと、この Perl プログラムを動かすと、Web コンテンツが取得できない、という話で、CGI であるかどうかは無関係かと。

で、おそらく、Google へ HTTP でアクセスした場合、HTTPS へリダイレクトされるようになった影響でしょう。

なので、単純な socket の代わりに IO::Socket::SSL モジュールを使って... という方法があると思いますが、もっと簡単に WWW::Curl モジュールを使う、という手もあります。

WWW::Curl - search.cpan.org

ざっくりとこんな感じになると思います。

#!/usr/bin/perl
use strict;
use warnings;
use WWW::Curl::Easy;

my $curl = WWW::Curl::Easy->new;
my $word = "hatena";
my $htmldata;

$curl->setopt(CURLOPT_URL, "http://www.google.co.jp/search?q=${word}&ie=UTF-8&oe=UTF-8&hl=ja&start=0&num=20");
$curl->setopt(CURLOPT_FILE, \$htmldata);

my $retcode = $curl->perform;

ただ、WWW::Curl でスカラー変数に取得内容をセットできるのは Ver 4.14 からで、それより古いバージョンだと、ファイルに保存してから読み出す形になると思います。ちなみに、手元の CentOS 6で perl-WWW-Curl を yum で入れると Ver 4.09 なので、上記のままでは失敗します。

上記の例だと「$curl->setopt(CURLOPT_FILE, \$htmldata);」の行を書かなければ、標準出力に取得内容が出力されます。

id:uwao

有り難うございました。
検索結果のソースが取得出来ました。
ただし、モジュールを使うよりリダイレクト先にアクセスした方が良いようでしたので、そちらで対応する事にしました。

2014/12/11 01:02:27
id:gizmo5 No.2

回答回数504ベストアンサー獲得回数141ここでベストアンサー

ポイント120pt

www.google.co.jp に対して、以下のコマンドを発行すると 302 のステータスで返ってきます。

GET /search?q=キーワード&ie=UTF-8&oe=UTF-8&hl=ja&start=0&num=20 HTTP/1.0

ヘッダの先頭付近は以下のようになっています。

HTTP/1.0 302 Found
Location: http://www.google.co.jp/search?q=%3F%3F%3F%3F%3F%3F%3F%3F%3F%3F&ie=UTF-8&oe=UTF-8&hl=ja&start=0&num=20&gws_rd=cr&ei=JNOBVJzzDMrc8AX4wIDIBQ

302 は Rewrite の指定になります。
http://ja.wikipedia.org/wiki/HTTP%E3%82%B9%E3%83%86%E3%83%BC%E3%82%BF%E3%82%B9%E3%82%B3%E3%83%BC%E3%83%89

Location ヘッダーで移動すべき URL が指定されているので、そちらの URL に対してもう一度 HTTP のリクエストを投げてレスポンスを取得してください。

id:uwao

有り難うございました。
リダイレクトのURLでアクセスする事にしました。

2014/12/11 01:02:55

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません