2011-03-18 59 views
7

我最近發現以下內容不適用於某些網站,如IMDB.com。WebRequest「HEAD」輕量級替代品

class Program 
    { 
     static void Main(string[] args) 
     { 
      try 
      { 
       System.Net.WebRequest wc = System.Net.WebRequest.Create("http://www.imdb.com"); //args[0]); 

       ((HttpWebRequest)wc).UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/525.19 (KHTML, like Gecko) Chrome/0.2.153.1 Safari/525.19"; 
       wc.Timeout = 1000; 
       wc.Method = "HEAD"; 
       WebResponse res = wc.GetResponse(); 
       var streamReader = new System.IO.StreamReader(res.GetResponseStream()); 

       Console.WriteLine(streamReader.ReadToEnd()); 
      } 
      catch (Exception ex) 
      { 
       Console.WriteLine(ex.Message); 
      } 
     } 
    } 

它返回一個HTTP 405(方法不允許)。我的問題是,我使用與上述類似的代碼來檢查鏈接是否有效,以及絕大多數時候它是否正常工作。我可以將它切換到方法相同的GET,它可以工作(增加超時),但是這會使事情減慢一個數量級。我假設405響應是IMDB服務器端的服務器配置。

有沒有辦法讓我在.NET中以輕量級的方式做同樣的事情?或者,有沒有辦法解決上面的代碼,所以它作爲一個GET請求與imdb一起使用?

+1

我不得不增加超時時間,但上面發佈的代碼適用於我。將其更改爲POST將毫無意義,因爲您沒有任何要發佈的數據。而你的標題談到HEAD,但你沒有做HEAD請求。請澄清問題是什麼,因爲你的「破」的代碼工作正常。 – 2011-03-18 15:17:25

+0

烏,真的很愚蠢的錯字在標題。現在修正了......想到一件事並輸入另一件事的經典例子。當你運行上面的代碼時,你沒有得到405迴應?編輯:好的,意識到即使我的代碼是有缺陷的。以上是我的意思是發佈,並編輯給405錯誤(和有道理.....) – Serapth 2011-03-18 15:29:22

回答

3

你必須澄清你的意思是「輕量級」。你想達到什麼目的?

您是否可以使用GET/POST/HEAD/DELETE/etc將取決於URL以及在該URL上的服務器上運行的應用程序中配置的內容。

如果你所要做的只是看看你是否可以在沒有實際下載內容的情況下建立連接,那麼你可以嘗試使用sockets來啓動與端口80的連接,但是並沒有真正可靠或普遍支持的方式只需改變HTTP方法。

+0

好吧,基本上我現在使用HEAD請求是a)檢查一個網站是否真的存在b)如果網站存在,爲每個鏈接,驗證它們實際存在(因此每個圖像,樣式表等)。因此,在某些圖像繁重的頁面上,它幾乎可以被稱爲數百次。所以,通過輕量級我主要是指網絡流量。 – Serapth 2011-03-18 15:44:32

+1

正確...就帶寬而言,我能想到的唯一更輕量級的方法是使用套接字手動構建HTTP請求,獲取足夠的響應以確定HTTP狀態代碼,然後關閉連接。 – 2011-03-18 15:46:27

+0

手動製作HTTP的路線實際上是否會繞過405錯誤結果?編輯:呃,我應該說的狀態結果,我想技術上HTTP 405實際上不是一個錯誤。這只是少數幾個返回405的網站,實際上我不知道哪個部分導致了這種迴應。現在,我正在承擔其HEAD請求,但我不確定。 – Serapth 2011-03-18 15:49:19

6

使用套接字(而不是HttpRequestWebClient)自己打開連接,並在讀取狀態代碼後立即關閉流。幸運的是,狀態碼接近響應流的頂部:)

4

如果HEAD返回405,這意味着服務器不支持HEAD(至少對於該URL),您將退回到GET 。大多數網站都應該支持HEAD,所以你可能希望默認使用HEAD,但是如果它拋出405,你可能會回退到GET。或者,也許你想先爲每個請求嘗試HEAD;因人而異。

如果服務器需要GET並且想要減少網絡流量,可以嘗試執行條件GET和/或部分GET(請參閱,例如RFC2616)。我從來沒有嘗試過使用WebRequest來做這些,但我認爲它可以讓你添加自定義的傳出HTTP頭文件,所以你應該可以做到。另外,不要忘記,如果你正在寫一個蜘蛛(你明確的是),你應該尊重服務器的robots.txt,並且它也很有禮貌地將你的請求限制爲每兩個請求秒,所以你不要slashdot服務器。

+0

謝謝你的迴應。我實際上並不是在寫蜘蛛,最終產品本質上比網頁瀏覽器更接近於其他任何東西。我按照你先前的建議(HEAD請求,然後在405上完成一個GET),這是我目前的做法,但它是次優的。我會研究部分GET,這可能是完美的。謝謝。 – Serapth 2011-03-18 16:17:12