1

Java を使用して Google 検索クエリ結果の html を取得しようとしています。つまり、Google.com で特定のフレーズを検索すると、結果の Web ページ (一致する可能性のあるリンクとその説明、URL などを含むページ) の html を取得したいと考えています。

関連する投稿で見つけた次のコードを使用して、これを実行してみました。

import java.io.*;
import java.net.*;
import java.util.*;

public class Main {

    public static void main (String args[]) {

        URL url;
        InputStream is = null;
        DataInputStream dis;
        String line;

        try {
            url = new URL("https://www.google.com/#hl=en&output=search&sclient=psy-ab&q=UCF&oq=UCF&aq=f&aqi=g4&aql=&gs_l=hp.3..0l4.1066.1471.0.1862.3.3.0.0.0.0.382.1028.2-1j2.3.0...0.0.OxbV2LOXcaY&pbx=1&bav=on.2,or.r_gc.r_pw.r_cp.r_qf.,cf.osb&fp=579625c09319dd01&biw=944&bih=951");
            is = url.openStream();  // throws an IOException
            dis = new DataInputStream(new BufferedInputStream(is));

            while ((line = dis.readLine()) != null) {
                System.out.println(line);
            }
        } catch (MalformedURLException mue) {
             mue.printStackTrace();
        } catch (IOException ioe) {
             ioe.printStackTrace();
        } finally {
            try {
                is.close();
            } catch (IOException ioe ) {
                // nothing to see here
            }
        }
    }
} 

From: Java で Web ページをプログラムでダウンロードする方法

このコードで使用されている URL は、Google ホームページから Google 検索クエリを実行して取得したものです。どういうわけか、Web ブラウザーの URL バーに検索したいフレーズを記述し、結果の検索結果ページの URL をコードで使用すると、403 エラーが発生します。

ただし、このコードは検索クエリ結果ページの html を返しませんでした。代わりに、Google ホームページのソース コードが返されました。

さらに調査した結果、Google 検索クエリ結果のソース コードを表示し (検索結果ページの背景を右クリックして [ページのソースを表示] を選択)、Google ホームページのソース コードと比較することに気付きました。 、どちらも同一です。

検索結果ページのソース コードを表示する代わりに、(ctrl+s を押して) 検索結果ページの html を保存すると、探している html を取得できます。

Javaを使用して検索結果ページのhtmlを取得する方法はありますか?

ありがとうございました!

4

3 に答える 3

2

標準のGoogle検索から結果のHTMLページを解析するのではなく、公式のカスタム検索APIを調べて、Googleからの結果をより使いやすい形式で返す方がよいでしょう。APIは間違いなく進むべき道です。そうしないと、Googleがgoogle.comフロントエンドのhtmlの一部の機能を変更した場合に、コードが壊れてしまう可能性があります。APIは開発者が使用するように設計されており、コードの脆弱性ははるかに低くなります。

しかし、あなたの質問に答えるために:私たちはあなたが提供した情報だけからあなたを本当に助けることはできません。あなたのコードはstackoverflowのhtmlを取得しているようです。リンクした質問からのコードの正確なコピーアンドペースト。コードを変更しようとしましたか?Googleの検索結果を取得するために実際に使用しようとしているURLは何ですか?

を使用してコードを実行しようとしましたが、url = new URL("http://www.google.com/search?q=test");個人的にHTTPエラー403が禁止されています。問題をすばやく検索すると、WebリクエストでUser-Agentヘッダーを指定しない場合にこれが発生することがわかりますが、実際にHTMLが返される場合は、正確には役に立ちません。特定のヘルプを利用したい場合は、より多くの情報を提供する必要があります。ただし、カスタム検索APIに切り替えると、問題が解決する可能性があります。


編集:元の質問で提供された新しい情報。今すぐ質問に直接答えることができます!

Javaが送信していたWebリクエストをパケットキャプチャし、いくつかの基本的なデバッグを適用した後、問題を理解しました...見てみましょう!

提供されたサンプルURLを使用してJavaが送信したWebリクエストは次のとおりです。

GET / HTTP/1.1
User-Agent: Java/1.6.0_30
Host: www.google.com
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive

リクエストがほとんどのURLを無視しているように見えたことに注意してください...「GET/」だけを残します。それ、変だよ。私はこれを調べなければなりませんでした。

Java URLクラスのドキュメントによると(これはすべてのWebページの標準です)、A URL may have appended to it a "fragment", also known as a "ref" or a "reference". The fragment is indicated by the sharp sign character "#" followed by more characters ... This fragment is not technically part of the URL.

サンプルURLを見てみましょう...

https://www.google.com/#hl=en&output=search&sclient=psy-ab&q=UCF&oq=UCF&aq=f&aqi=g4&aql=&gs_l=hp.3..0l4.1066.1471.0.1862.3.3.0.0.0.0.382.1028.2-1j2.3.0...0.0.OxbV2LOXcaY&pbx=1&bav=on.2,or.r_gc.r_pw.r_cp.r_qf.,cf.osb&fp=579625c09319dd01&biw=944&bih=951

「#」がファイルパスの最初の文字であることに注意してください。シャープサインはクライアント/Webブラウザでのみ使用されるため、Javaは「#」以降のすべてを単に無視します。これにより、URLが残りhttps://www.google.com/ます。ねえ、少なくともそれは意図したとおりに機能していました!

Googleが何をしているのか正確にはわかりませんが、シャープシンボルのURLは、Googleがクライアント側(ajax / javascript)のスクリプトを介してクエリの結果を返していることを意味します。適切なヘッダーなしでサーバーに直接送信するクエリ(つまり、「#」記号がない)は、403禁止エラーを返すことになります。APIの使用を推奨しているようです:)

edit2:質問に対するTengji Zhangの回答によると、「test」のgoogleクエリの結果を返す作業コードは次のとおりです。

    URL url;
    InputStream is = null;
    DataInputStream dis;
    String line;
    URLConnection c;

    try {
        url = new URL("https://www.google.com/search?q=test");
        c = url.openConnection();
        c.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.168");
        c.connect();
        is = c.getInputStream();
        dis = new DataInputStream(new BufferedInputStream(is));
        while ((line = dis.readLine()) != null) {
            System.out.println(line);
        }
    } catch (MalformedURLException mue) {
         mue.printStackTrace();
    } catch (IOException ioe) {
         ioe.printStackTrace();
    } finally {
        try {
            is.close();
        } catch (IOException ioe ) {
            // nothing to see here
        }
    }
于 2012-06-25T03:45:12.327 に答える
1

http://seleniumhq.org/を試してみることをお勧めします

グーグルで検索するための良いチュートリアルがあります

http://code.google.com/p/selenium/wiki/GettingStarted

于 2012-06-25T03:45:14.217 に答える
-1

コードに User-Agent を設定しません。

URLConnection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.168");

または、その「http://www.google.com/robots.txt」を読むことができます。このファイルは、Google サーバーで許可されている URL を示します。

以下のコードは成功です。

package org.test.stackoverflow;

import java.io.*;
import java.net.*;
import java.util.*;

public class SearcherRetriver {
    public static void main (String args[]) {

        URL url;
        InputStream is = null;
        DataInputStream dis;
        String line;
        URLConnection c;

        try {
            url = new URL("https://www.google.com.hk/#hl=en&output=search&sclient=psy-ab&q=UCF&oq=UCF&aq=f&aqi=g4&aql=&gs_l=hp.3..0l4.1066.1471.0.1862.3.3.0.0.0.0.382.1028.2-1j2.3.0...0.0.OxbV2LOXcaY&pbx=1&bav=on.2,or.r_gc.r_pw.r_cp.r_qf.,cf.osb&fp=579625c09319dd01&biw=944&bih=951");
            c = url.openConnection();
            c.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.168");
            c.connect();
            is = c.getInputStream();
            dis = new DataInputStream(new BufferedInputStream(is));
            while ((line = dis.readLine()) != null) {
                System.out.println(line);
            }
        } catch (MalformedURLException mue) {
             mue.printStackTrace();
        } catch (IOException ioe) {
             ioe.printStackTrace();
        } finally {
            try {
                is.close();
            } catch (IOException ioe ) {
                // nothing to see here
            }
        }
    }
}
于 2012-06-26T08:18:49.927 に答える