2011-03-18 58 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