2012-06-25 109 views
1

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

我尝试使用下面的代码,我在相关的职位找到这样:How do you Programmatically Download a Webpage in Java

是从做一个谷歌搜索查询获得此代码中使用的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 
      } 
     } 
    } 
} 

Google首页。出于某种原因,我不明白,如果我在我的Web浏览器的URL栏中编写要搜索的短语,然后在代码中使用生成的搜索结果页的URL,则会出现403错误。

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

经过深入研究,我发现如果您查看Google搜索查询结果的源代码(通过右键单击搜索结果页面的背景并选择“查看页面源代码”)并将其与源代码进行比较的Google主页,它们都是相同的。

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

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

谢谢!

回答

2

与其解析从标准谷歌搜索产生的HTML页面,也许你最好看看官方的Custom Search api以更有用的格式返回谷歌的结果。 API绝对是要走的路。否则,如果Google要更改google.com前端HTML的某些功能,那么您的代码可能会中断。该API旨在供开发人员使用,并且您的代码将更加脆弱。

要回答你的问题,虽然:我们不能真正帮助你,只是从你提供的信息。你的代码似乎检索到了stackoverflow的html;从链接的问题中精确复制并粘贴代码。你有没有尝试改变代码?您实际尝试使用哪个网址来检索Google搜索结果?

我试图用url = new URL("http://www.google.com/search?q=test");来运行你的代码,我个人得到了HTTP错误403禁止。如果我没有在Web请求中提供User-Agent标头,那么问题的快速搜索就会发生这种情况,但如果您实际上正在返回HTML,那么这不会对有帮助。如果您希望获得特定帮助,您将不得不提供更多信息 - 尽管切换到Custom Search 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只是忽略了“#”后的所有内容,因为sharp-signs只能被客户端/浏览器使用 - 这会给你留下url https://www.google.com/。嘿,至少它是按照预期工作的!

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

EDIT2:根据Tengji张回答的问题,对于“测试”

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

谢谢您的所有信息!我将研究Google API。但是,我想了解为什么Java代码不会返回所需的结果。我使用我使用的代码更新了原始帖子,并添加了有关如何获得不会生成403错误的网址的说明。我希望这使得它更容易理解。 – Erich

+0

@ Kyndod7不知道你是否收到我的编辑通知 - 但我回答了你的问题:)你为什么要以编程方式谷歌搜索我的大学的名字? :) –

+0

非常感谢Alex!当我测试代码时,我只是随机选择UCF,它也是我的大学:) – Erich

-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”。这个文件告诉你哪个url被google服务器所允许。

下面的代码是成功的。

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

您的代码不起作用。我使用google.com而不是google.com.hk进行了测试 - 但它应该没有区别。看到我的答案,为什么它不起作用。 –

+0

我的代码在我的电脑中很有用。 @ Kyndod7的代码不符合谷歌的爬虫规则。所以得到错误403. –

+0

是的,但你的代码仍然返回谷歌主页,而不是实际的搜索结果。 403错误不会发生,因为您*从未实际执行过谷歌搜索*。只返回google主页的HTML,而不是搜索查询的HTML(这是作者想要的)。如果您将您的请求标头与*实际上会返回搜索结果的网址*相结合,那么您的代码是正确的,并且OP的问题将得到解答。但是在目前的状态下,你的回答并没有描述为什么OP的代码不会返回与搜索查询相关的HTML。 –