【问题标题】:How can I Retrieve the HTML of a Search Engine Query Result?如何检索搜索引擎查询结果的 HTML?
【发布时间】:2012-06-25 03:24:21
【问题描述】:

我正在尝试使用 Java 检索 Google 搜索查询结果的 html。也就是说,如果我在 Google.com 中搜索特定短语,我想检索结果网页的 html(包含指向可能匹配项的链接及其描述、URL 等的页面)。

我尝试使用在相关帖子中找到的以下代码来执行此操作:

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
            }
        }
    }
} 

发件人:How do you Programmatically Download a Webpage in Java

此代码中使用的 URL 是通过从 Google 主页执行 Google 搜索查询获得的。出于某种原因,我不明白,如果我在网络浏览器的 URL 栏中写下要搜索的短语,然后在代码中使用生成的搜索结果页面的 URL,我会收到 403 错误。

但是,此代码没有返回搜索查询结果页面的 html。相反,它返回了 Google 主页的源代码。

经过进一步研究,我注意到如果你查看谷歌搜索查询结果的源代码(通过右键单击搜索结果页面的背景并选择“查看页面源”)并将其与源代码进行比较Google 主页,它们都是相同的。

如果我不查看搜索结果页面的源代码,而是保存搜索结果页面的 html(通过按 ctrl+s),我可以获得我要查找的 html。

有没有办法使用Java检索搜索结果页面的html?

谢谢!

【问题讨论】:

    标签: java html


    【解决方案1】:

    与其从标准的 google 搜索解析生成的 HTML 页面,不如查看官方的Custom Search api 以更可用的格式从 Google 返回结果。 API 绝对是要走的路;否则,如果 Google 要更改 google.com 前端 html 的某些功能,您的代码可能会简单地中断。该 API 旨在供开发人员使用,您的代码不会那么脆弱。

    不过,要回答您的问题:仅凭您提供的信息,我们无法真正为您提供帮助。您的代码似乎检索了 stackoverflow 的 html;从您链接到的问题中精确复制和粘贴代码。您是否尝试过更改代码?您实际尝试使用哪个 URL 来检索 Google 搜索结果?

    我尝试使用 url = new URL("http://www.google.com/search?q=test"); 运行您的代码,但我个人收到了 HTTP 错误 403 禁止。对问题的快速搜索表明,如果我没有在 Web 请求中提供 User-Agent 标头,则会发生这种情况,尽管如果您实际上返回的是 HTML,这并不能完全帮助 。如果您希望获得具体帮助,则必须提供更多信息 - 尽管切换到自定义搜索 API 可能会解决您的问题。


    编辑:原始问题中提供的新信息;现在可以直接回答问题了!

    在对java发送的web请求进行数据包捕获并应用一些基本调试之后,我发现了你的问题......让我们看看!

    这是 Java 使用您提供的示例 URL 发送的 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 类的文档(这是所有网页的标准),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.

    让我们看看您的示例网址...

    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

    注意到“#”是文件路径中的第一个字符吗? Java 只是忽略了“#”之后的所有内容,因为尖号仅由客户端/Web 浏览器使用 - 这给您留下了 url https://www.google.com/。嘿,至少它按预期工作!

    我不能确切地告诉你谷歌在做什么,但尖锐的符号 url 绝对意味着谷歌正在通过一些客户端(ajax / javascript)脚本返回查询结果。我敢打赌,如果没有正确的标头,您直接发送到服务器的任何查询(即没有“#”符号)都会返回 403 禁止错误 - 看起来他们鼓励您使用 API :)

    edit2:根据 Tengji Zhang 对问题的回答,这里是返回“test”的谷歌查询结果的工作代码

        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
            }
        }
    

    【讨论】:

    • 感谢您提供的所有信息!我将研究 Google API。但是,我想了解为什么 Java 代码没有返回所需的结果。我用我使用的代码更新了原始帖子,并添加了关于我如何获得没有产生 403 错误的 URL 的说明。我希望这能让它更容易理解。
    • @Kyndod7 不确定您是否收到我的编辑通知 - 但我回答了您的问题 :) 为什么您尝试以编程方式在 Google 上搜索我的大学名称? :)
    • 非常感谢亚历克斯!我只是在测试代码时随机选择了UCF,它也是我的大学:)
    【解决方案2】:

    我建议你试试http://seleniumhq.org/

    google有很好的搜索教程

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

    【讨论】:

      【解决方案3】:

      您没有在代码中设置用户代理。

      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
                  }
              }
          }
      }
      

      【讨论】:

      • 您的代码不起作用。我使用 google.com 而不是 google.com.hk 进行了测试 - 但应该没有区别。请参阅我关于为什么它不起作用的答案。
      • 我的代码在我的电脑中很有用。 @Kyndod7 的代码不遵循谷歌的爬虫规则。所以得到错误 403。
      • 是的,但是您的代码仍然返回 google 主页,而不是实际的搜索结果。 403 错误不会发生,因为您从未真正执行过 google 搜索。只返回 google 主页 HTML,而不是搜索查询的 HTML(这是作者想要的)。如果您将请求标头与 实际返回搜索结果 的 URL 结合使用,那么您的代码是正确的,并且 OP 的问题得到了回答。但在目前的状态下,您的回答没有描述为什么 OP 的代码不返回与搜索查询相关的 HTML。
      猜你喜欢
      • 2012-04-10
      • 1970-01-01
      • 2011-04-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多