2012-06-25 142 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。 –