perlでLWP::UserAgentを使ってgoogle検索結果を取得しようとする際の問題

このQ&Aのポイント
  • perlのLWP::UserAgentを使ってgoogle検索結果を取得しようとしたが、#を含むURLでは正しい結果が返ってこない
  • 同じ操作をYahoo!で行った場合には正常に検索結果が返ってくるため、googleの仕様が問題と考えられる
  • ブラウザのURL欄に?q=を使ってgoogleを検索すると、トップページに検索クエリが表示される現象が発生する
回答を見る
  • ベストアンサー

URLに含まれる「#」,「?」、HTTPリクエスト

皆様いつもお世話になっております。 今日はperlでLWP::UserAgentを使って、google検索結果を得ようとしたところで、岩に躓いて肘の骨に皹が入った点で質問させていただきます。 googleで「asd」と検索するとURLは http://www.google.co.jp/#q=asd となりますが、#ってのは、ページ内遷移などを主目的とした、クライアント、ブラウザ側がご自由に使ってくださいのパラメータの記述開始マークではないのですか? まあ、これに従ったとして、 「http://www.google.co.jp/#q=asd」 を、perlのLWP::UserAgentを使って、 ---- my $ua = LWP::UserAgent->new; $ソース = $ua->get("http://www.google.co.jp/#q=asd"); # googleのトップページの検索結果が返る ---- と投げてみましたところ、Google ☆ト ッ プ ペ ー ジ☆ のソースが返ってくるのです。 Yahoo!ではasdと検索すると?がついて「http://search.yahoo.co.jp/search?p=asd」となるし、perlで同じ文字列をリクエストするとちゃんと検索結果が返ってくるので、googleの仕様がおかしいのではないか?というのが、私の推測群の現在の最有力候補であります。 ---- my $ua = LWP::UserAgent->new; $ソース = $ua->get("http://search.yahoo.co.jp/search?p=asd"); # asdの検索結果が返る ---- ちなみにですが、googleを?を使って 「http://www.google.co.jp/?q=asd」 と、ブラウザURL欄に入力しEnterを押すと、Googleトップページがテキストボックスに「asd」と入力された状態で表示されます。 この現象を説明していただける方がいらっしゃいましたら、どうかよろしくお願い致します。m(_ _)m -- 環境情報 ブラウザ IE10 OS Windows7 --

  • HTML
  • 回答数4
  • ありがとう数4

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

  • ベストアンサー
  • hirotn
  • ベストアンサー率59% (147/246)
回答No.4

Googleは、Web検索を外部プログラマが利用できるよう、Google Web APIを公開しています。 このAPIは制限があり、一日1000クエリまで、検索結果もGoogleの検索サイトと少し異なるようです。 この問題を回避するため、Google検索にクエリを投げてHTMLを解析しようとすることがありますが、(Googleの)ライセンス違反の恐れが高いですし(他人のコンテンツをキャッシュしてビジネスしてるのに)、検索結果のHTML自体が頻繁に内容が変わって解析できなくなってしまうことがあります。 本音と建前が出てしまいますが、冒頭が回答になります。

35fa8e3c
質問者

お礼

hirotn様、再びありがとうございます。 なるほど、クエリーを投げるためのAPIがあり、一日1000回までなんですね。 #を?にしてしまうと自由に検索結果を取得できてAPIを利用する意味がない=>Googleのビジネスが成立しない、商品(コンテンツまたはそれをキャッシュしたもの)の提供者としての"世界の管理人たち"に対してGoogleがライセンス違反?したということになりかねないという解釈でよいしょうか。 勉強になりました。ありがとうございましたm(_ _)m 結局プログラムにはYahoo!の検索結果を用いましたが、機会があればGoogleAPIに手を出そうと思います!

その他の回答 (3)

  • hirotn
  • ベストアンサー率59% (147/246)
回答No.3

#q=xxxxxxxx は、jQueryからみかと。 以下URLが該当かと。 http://www.kaasan.info/archives/564 これを参考にソースを見てみると、こんな記述があって、知識不足なのでよくわかりませんが匂います。 location.hash.match("[#&]((q|fp)=|tbs=simg|tbs=sbi)") とすると、URLを生成するだけではだめできちんとイベントが起きていないと、#q=xxxxxx表記による検索は実行されないと考えられます。?を使って記述するのではダメでしょうか?

35fa8e3c
質問者

お礼

hirotn様、ご回答ありがとうございます。 頂いた情報をもとに調べた結果、#以降をアンカーと呼ぶこと、javascriptでlocation.hashによってアンカーを取得できることを初めて知りました。 googleで検索キーワードを入力している最中に結果が随時表示される((1)おそらく頻出キーワードに限って(2)yahooにはこの機能はない)ところを見ると、おそらくhirotnさんの推測されるとおりjQueryか何かでajaxを使ってサーバーとやりとりをしていますね・・・ ?を使った表記では、 ブラウザ:テキストボックスにキーワードが入力されたトップページが表示される Perl:トップページのソースが返る といった結果ですので、googleに関してはプログラム(javascriptを解析できないようなシンプルなもの)で検索結果を取得するのは無理か、骨が折れるものになるか、GoogleがAPIを出しているかも?ということでしょうな。。 とても勉強になりました。ありがとうございます。

  • hirotn
  • ベストアンサー率59% (147/246)
回答No.2

URI::Escapeは利用可能ですか? http://search.cpan.org/dist/URI/URI/Escape.pm http://homepage3.nifty.com/hippo2000/perltips/URI/Escape.html use URI::Escape; $safe = uri_escape("10% is enough\n"); $verysafe = uri_escape("foo", "\0-\377"); $str = uri_unescape($safe);

35fa8e3c
質問者

お礼

回答ありがとうございます。 日本語ならescapeするつもりです。 今回google検索結果のurlとそのurl中パラメータが#で区切られていてしかもそのURLでHTTPリクエストを投げるとトップページのソースが返るので悩んでいます。 エンコ・デコに関しては大丈夫です。

  • ORUKA1951
  • ベストアンサー率45% (5062/11036)
回答No.1

Perlの#は、どういう意味でしたか? $ソース = $ua->get("http://www.google.co.jp/#q=asd"); # googleのトップページの検索結果が返る は、 $ソース = $ua->get("http://www.google.co.jp/ では?? >googleで「asd」と検索するとURLは http://www.google.co.jp/#q=asd となりますが、  なりません。

35fa8e3c
質問者

お礼

回答ありがとうございます。 #はコメントアウトの 場 合 があります。 コメントアウト扱いになってたらまずエラーが出てますよね。 #は例外として""中の#と$後の#はコメントアウト扱いさません。 あと文末の「なりません」の意味がわかりません。 なんかすみません。何かご存知でしたらよろしくお願いいたします。

関連するQ&A

  • Perlで言う、LWP HTTPをPHPで

    PerlでのスクリプトをPHPに移行しようかと考えております。(勉強のため) それで、PerlのモジュールでいうLWPとHTTPに代わるクラスライブラリ(API)は、どれにあたるのでしょうか? 具体的には、LWP::UserAgentとHTTP::Requestです。 ※詳しくは、 my $wa = new LWP::UserAgent; my $req = new HTTP::Request(GET => $url); my $res = $wa->request($req); PHPのドキュメント(http://www.php.net/manual/ja/)を見たのですが、いまいちピンときませんでした。 参考URLで結構ですので、よろしくお願いいたします。

    • ベストアンサー
    • PHP
  • CGIの接続エラー

    PerlのLWP::UserAgentを使った接続で,エラーが生じてしまいます. ローカルからなら期待通りにページ内容を取得できるのですが,サーバに配置してブラウザからアクセスするとInternal Server Errorとなります. プロキシは使っていません.ファイアウォールやセキュリティソフトを切ってもエラーが生じてしまいます. 対象URL(下のコードではhttp://wikipedia.simpleapi.net/api?keyword=YouTube&output=xml)を変えても同じ結果になります. 理由がわかる方がいらっしゃればご教授願います. CGIにPerl5,サーバにApache Tomcat 5.5を利用しています. エラー内容とコードは下のようになっています. エラー内容 「500 Can't connect to wikipedia.simpleapi.net:80 (Bad hostname 'wikipedia.simpleapi.net')」 コード #!/usr/local/bin/perl use LWP::UserAgent; print "Content-type: text/plain\n\n"; my $ua = LWP::UserAgent->new; $ua->agent("Mozilla/5.0"); my $req = HTTP::Request->new(GET => "http://wikipedia.simpleapi.net/api?keyword=YouTube&output=xml"); my $res = $ua->request($req); $res = $ua->request($req); my $content = $res->content; print $content; exit;

  • 別サーバーへの書き込み

    別サーバーのファイルを以下のようにすると、読み込みは可能となりました。 このファイルに書き込むロジックを調べているのですが、 中々見つかりません。 どのようにすれば、書き込む事が出来るのでしょうか。 $url = "http://www.test.jp/test.dat"; require LWP::UserAgent; $ua = new LWP::UserAgent; $request = new HTTP::Request('GET', $url); $response = $ua->request($request); if ($response->is_success) { $content = $response->content; } @DATA = $content;

  • Perl LWPでproxyがうまく刺さらない

    Perl初心者です。 LWPでどうしてもproxyが通りません・・・。 何が悪いのかわかりません。教えてください。 モジュールは全て導入を確認しました。 よろしくお願いします。 稚拙なミスだったらごめんなさい。 use LWP::Simple; use LWP::UserAgent; use HTTP::Request::Common; my $ua = LWP::UserAgent->new( timeout=>"5" ); #cybersyndromeさんからLWP::Simpleでproxyを取得 $_ = get('http://www.cybersyndrome.net/pla5.html'); #proxyをリストに代入 (@proxy_list)=/\"\>(.*?)\<\/a\>\<\/li\>\<li\>/g; #適当なサイトをリクエストのターゲットに $r = new HTTP::Request GET,('http://taruo.net/e/'); #前述のターゲットへリクエストしてひとつづつproxyが通るか確かめたいのに何故かすべてすぐにERRORに for($i = 0;$i <= 10;$i++){ $proxy = 'http://'.$proxy_list[$i]; $ua->proxy ([qw(http https)] , $proxy); $req = $ua->request($r); if ($req->is_success) { print "Success!\n"; }else{ print "Error\n"; } }

    • ベストアンサー
    • Perl
  • モジュールを使ってリクエストヘッダーの表示をさせたい

    宜しくお願いします。 ウェブサーバーにリクエストを送った際、 リクエストヘッダ レスポンスヘッダとあると思うんですけど、 レスポンスヘッダは下記の形で表示できるのですが、 リクエストの際のヘッダ情報(HOST:やReferer:など)を表示させる事ができません。 どなたか、モジュールを使った形でリクエストヘッダを表示させるプログラム記述をご教授願えませんでしょうか。 ※下記は実際にテストを行っているリクエストヘッダとレスポンスヘッダとソースを表示する記述例です。(レスポンスヘッダは正常に表示できているとおもうのですが・・。) #!/usr/bin/perl use HTTP::Request::Common qw(POST GET); use LWP::UserAgent; use HTTP::Cookies; my $ua = LWP::UserAgent->new; my $req = $ua->request(HTTP::Request->new(GET => "http://localhost/")); print "Content-type: text/html\n\n"; print $req3->headers_as_string([$endl]);#これを追加し表示される情報はリファレンスっぽくなってしまうのと、 #リクエストヘッダのHOST:やReferer:UserAgentなどの情報が入ってないので、 #モジュールを利用してリクエストヘッダを表示させてみたいです。 print $req->as_string; リクエストヘッダーのイメージは下記のような情報だと思うのですが、モジュールを使って表示させる事はできないでしょうか どなた様かご教授の程宜しくお願い致します。 HTTP/1.1 Accept: */* Referer: http://okwave.jp/search.php3 Accept-Language: ja User-Agent: Mozilla/4.0 (compatible ; MSIE 6.0; Windows NT 5.0) Host: okwave.jp Connection: Keep-Alive Transfer-Encoding: chunked Content-Type: text/html; charset=Shift_JIS

    • ベストアンサー
    • Perl
  • LWP Cookie取得

    恐れ入ります。 LWPで、特定サイトにアクセスした時に発行されるCookieを任意のディレクトリに保存したいのですが、どのようにしたらよいかわかりません。 use HTTP::Cookies; use LWP::UserAgent; $ua = LWP::UserAgent->new(); $cookie_file = './cookie/xxx.txt'; $cookie_jar = HTTP::Cookies->new(file => $cookie_file, autosave => 1); $url = "http://~~"; $response = $ua->get($url); print $response->content; で、コンテンツは表示されますが、xxx.txtにcookieが保存されません。 #LWP-Cookies-1.0 のみが記載された白紙のxxx.txtが精製されます。 よろしくお願いします。

    • ベストアンサー
    • Perl
  • クッキーを保持したままコード取得

    こんばんは。 Perlで例えば「https://secure.nicovideo.jp/secure/login?site=niconico」にアクセスして、そのログイン情報のまま「http://www.nicovideo.jp/」にアクセスしたソースコードが欲しいです。 下記ためしたコード use LWP::UserAgent; use HTTP::Request::Common qw(POST); $nico_ua = LWP::UserAgent->new; %loginform = ('mail' => 'hoge@hoge.jp', 'password' => '****'); $request = POST('https://secure.nicovideo.jp/secure/login?site=niconico', [%loginform]); $nico_ua->request($request); ##この時点でログインはできてる模様 $response = $nico_ua->get("http://www.nicovideo.jp/"); print $response->content; ##↑のprintが上手くいかない。 $nico_ua をそのまま使えばログイン情報も維持されると思ったが甘かったです。 LWPの接続でクッキーなどの情報を保持したまま次に指定したURLのコードを取得する方法が知りたいです。 お願いします。

    • ベストアンサー
    • Perl
  • Perlでgoogle newsのRSSを取得2

    質問を閉め切った直後に気付いたもので、すいません!! QNo.3797932の、つづきなのですが、、、 教えていただいた以下の方法 ------------------------- #!/usr/local/bin/perl use LWP::Simple; use XML::RSS; use LWP::UserAgent; my $url = 'http://news.google.com/news?hl=ja&ned=us&ie=UTF-8&oe=UTF-8&output=rss&q=aiko'; my $ua = new LWP::UserAgent; my $responce = $ua->get($url, 'User-Agent' => 'Mozilla/4.0'); my $data_from_web = $responce->content; print <<"HTML"; Content-type: text/html <html> HTML print $data_from_web; exit; ------------------------- の場合だと、ページ表示データは取得できるのですが、RSS特有のタグが 抜け落ちる為、その後の解析ができない事に気付きました。 なんとか、RSS特有のタグも含めてのRSS情報を入手する方法はないでしょうか? ちなみに、RSS特有のタグも含めてのRSS情報は、ブラウザーのURLの窓に http://news.google.com/news?hl=ja&ned=us&ie=UTF-8&oe=UTF-8&output=rss&q=aiko このアドレスを直接入力してリターンキーを押すと、確認する事ができます。 度々申し訳ないのですが、よろしくご指導、お願い致します。

    • ベストアンサー
    • Perl
  • Perlのコードを隠蔽する

    Perlのソースコードを隠蔽する&ActivePerlなどがない環境でも動くようにperl2exeを使って変換して配布しようと思っています。 逆コンパイラされる可能性が0ではないことはわかっています。 しかし、下記コードの実行がなかなかうまくいきません。実際の.plでの起動時ではうまくいくのですが、.exeに変換するとうまくいかないようです。回避方法を教えてください。 -------------------- use HTTP::Request::Common qw(POST); use LWP::UserAgent; my $ua = LWP::UserAgent->new; my %loginform = ('mail' => 'hogehoge@hoge.jp', 'password' => 'hogehoge'); my $request = POST('https://****/login', [%loginform]); my $res = $ua->request($request); my $cookie = $res->header('Set-Cookie'); --------------------

  • ページのタイトル

    googleだけページタイトルが取得できません。 何方か、ご教授して頂けないでしょうか。 ---結果--- 403 Forbidden Yahoo!検索 - テスト [テスト] goo ウェブ検索結果 Excite エキサイト 検索結果 : テスト テスト - infoseek 検索 ---cgi--- #!/usr/bin/perl use LWP::UserAgent; use HTTP::Request; require './jcode.pl'; print "Content-type:text/html;charset=Shift_JIS\n\n"; print "<html><head>\n"; print "<title>ddd</title></head>\n"; print "<body>\n"; @data[0] = "http://www.google.co.jp/search?hl=ja&inlang=ja&ie=Shift_JIS&oe=Shift_JIS&c2coff=1&q=%83e%83X%83g&btnG=Google+%8C%9F%8D%F5&lr="; @data[1] = "http://search.yahoo.co.jp/bin/search?p=%A5%C6%A5%B9%A5%C8"; @data[2] = "http://search.goo.ne.jp/web.jsp?TAB=&MT=%A5%C6%A5%B9%A5%C8"; @data[3] = "http://www.excite.co.jp/search.gw?target=combined&look=excite_jp&lang=jp&search=%83e%83X%83g"; @data[4] = "http://www.infoseek.co.jp/OTitles?qt=%A5%C6%A5%B9%A5%C8&col=OW"; foreach $url (@data) { $test = &gettitle($url); &jcode::convert(\$test,'sjis'); print "$test<br>"; } sub gettitle { my $url = shift or return undef; my $ua = LWP::UserAgent->new; my $req = HTTP::Request->new(GET => $url); $req->header("Accept" => "text/html"); my $res = $ua->request($req, sub { my($chunk, $res) = @_; die if ($res->title or ($chunk =~ m{</head}i)); }); return $res->title; } print "</body></html>\n";

    • ベストアンサー
    • Perl

専門家に質問してみよう