2012-07-25 48 views
4

我正在尋找一種方法,可以讓我獲取網頁的標題並將其作爲字符串存儲。如何在不下載所有頁面源的情況下獲取網頁標題

但是到目前爲止我發現的所有解決方案都涉及到下載頁面的源代碼,這對大量的網頁來說並不實用。

我能看到的唯一方法是限制字符串的長度,或者它只下載一個字符集或停止一旦達到標籤,但是這顯然仍然會很大?

感謝

回答

13

由於<title>標籤是在HTML本身,就沒有辦法下載文件中找到「只是」稱號。在閱讀<title>標籤或</head>標籤並停止之前,您應該可以下載文件的一部分,但仍然需要下載(至少一部分)該文件。

這可以使用HttpWebRequest/HttpWebResponse並從響應流中讀取數據,直到我們讀取了<title></title>塊或</head>標記爲止。我添加了</head>標記檢查,因爲在有效的HTML中,標題塊必須出現在頭部塊中 - 因此,通過此檢查,我們決不會在任何情況下解析整個文件(除非沒有頭塊)。

下應該能夠完成這項任務:

string title = ""; 
try { 
    HttpWebRequest request = (HttpWebRequest.Create(url) as HttpWebRequest); 
    HttpWebResponse response = (request.GetResponse() as HttpWebResponse); 

    using (Stream stream = response.GetResponseStream()) { 
     // compiled regex to check for <title></title> block 
     Regex titleCheck = new Regex(@"<title>\s*(.+?)\s*</title>", RegexOptions.Compiled | RegexOptions.IgnoreCase); 
     int bytesToRead = 8092; 
     byte[] buffer = new byte[bytesToRead]; 
     string contents = ""; 
     int length = 0; 
     while ((length = stream.Read(buffer, 0, bytesToRead)) > 0) { 
      // convert the byte-array to a string and add it to the rest of the 
      // contents that have been downloaded so far 
      contents += Encoding.UTF8.GetString(buffer, 0, length); 

      Match m = titleCheck.Match(contents); 
      if (m.Success) { 
       // we found a <title></title> match =] 
       title = m.Groups[1].Value.ToString(); 
       break; 
      } else if (contents.Contains("</head>")) { 
       // reached end of head-block; no title found =[ 
       break; 
      } 
     } 
    } 
} catch (Exception e) { 
    Console.WriteLine(e); 
} 

UPDATE:更新的原始來源,例如使用編譯RegexusingStream聲明,以便提高效率和可維護性。

+1

我給+2爲最後評論中的悲傷面孔,但我不能= [ – Charleh 2012-07-25 15:39:42

+1

這是一個很棒的代碼解決方案,謝謝。僅供參考 - 編譯正則表達式的問題是,它不會真的幫助這裏,因爲你編譯每個請求的正則表達式。最好在運行時編譯一次,然後在此方法中使用它。編譯需要一些時間和更多的內存,但對於大規模(100MB +)文檔或循環(數十萬)非常有用。未編譯的正則表達式被緩存,並且對於這個文本的大小不會真的有很大的影響。 +1 – ppumkin 2015-03-21 10:23:11

1

一個更簡單的處理,這將是下載的方式,然後分裂:

using System; 
    using System.Net.Http; 

    private async void getSite(string url) 
    { 
     HttpClient hc = new HttpClient(); 
     HttpResponseMessage response = await hc.GetAsync(new Uri(url, UriKind.Absolute)); 
     string source = await response.Content.ReadAsStringAsync(); 

     //process the source here 

    } 

處理源,可以使用在文章中這裏所描述的方法上Getting Content From Between HTML Tags

+0

要提高帖子的質量,請包括此代碼如何/爲何解決問題。 – 2012-10-04 09:56:21

相關問題